aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS6
-rw-r--r--audio/decoders/flac.h1
-rw-r--r--audio/decoders/mp3.h1
-rw-r--r--audio/decoders/vorbis.h1
-rw-r--r--base/plugins.cpp3
-rwxr-xr-xconfigure1
-rw-r--r--dists/engine-data/m4.datbin137897 -> 0 bytes
-rw-r--r--dists/engine-data/mads.datbin12126 -> 0 bytes
-rw-r--r--dists/scummvm.rc3
-rw-r--r--engines/m4/actor.cpp199
-rw-r--r--engines/m4/actor.h114
-rw-r--r--engines/m4/animation.cpp535
-rw-r--r--engines/m4/animation.h127
-rw-r--r--engines/m4/assets.cpp650
-rw-r--r--engines/m4/assets.h212
-rw-r--r--engines/m4/burger_data.h82
-rw-r--r--engines/m4/compression.cpp190
-rw-r--r--engines/m4/compression.h77
-rw-r--r--engines/m4/console.cpp428
-rw-r--r--engines/m4/console.h83
-rw-r--r--engines/m4/converse.cpp1239
-rw-r--r--engines/m4/converse.h214
-rw-r--r--engines/m4/detection.cpp419
-rw-r--r--engines/m4/dialogs.cpp558
-rw-r--r--engines/m4/dialogs.h80
-rw-r--r--engines/m4/events.cpp365
-rw-r--r--engines/m4/events.h132
-rw-r--r--engines/m4/font.cpp291
-rw-r--r--engines/m4/font.h119
-rw-r--r--engines/m4/globals.cpp554
-rw-r--r--engines/m4/globals.h346
-rw-r--r--engines/m4/graphics.cpp1361
-rw-r--r--engines/m4/graphics.h270
-rw-r--r--engines/m4/gui.cpp1215
-rw-r--r--engines/m4/gui.h453
-rw-r--r--engines/m4/hotspot.cpp283
-rw-r--r--engines/m4/hotspot.h126
-rw-r--r--engines/m4/m4.cpp606
-rw-r--r--engines/m4/m4.h252
-rw-r--r--engines/m4/m4_menus.cpp724
-rw-r--r--engines/m4/m4_menus.h103
-rw-r--r--engines/m4/m4_scene.cpp326
-rw-r--r--engines/m4/m4_scene.h84
-rw-r--r--engines/m4/m4_views.cpp342
-rw-r--r--engines/m4/m4_views.h115
-rw-r--r--engines/m4/mads_anim.cpp745
-rw-r--r--engines/m4/mads_anim.h110
-rw-r--r--engines/m4/mads_logic.cpp1038
-rw-r--r--engines/m4/mads_logic.h117
-rw-r--r--engines/m4/mads_menus.cpp1173
-rw-r--r--engines/m4/mads_menus.h179
-rw-r--r--engines/m4/mads_player.cpp789
-rw-r--r--engines/m4/mads_player.h113
-rw-r--r--engines/m4/mads_scene.cpp1272
-rw-r--r--engines/m4/mads_scene.h195
-rw-r--r--engines/m4/mads_views.cpp1632
-rw-r--r--engines/m4/mads_views.h494
-rw-r--r--engines/m4/midi.cpp256
-rw-r--r--engines/m4/midi.h59
-rw-r--r--engines/m4/module.mk49
-rw-r--r--engines/m4/rails.cpp358
-rw-r--r--engines/m4/rails.h97
-rw-r--r--engines/m4/resource.cpp530
-rw-r--r--engines/m4/resource.h147
-rw-r--r--engines/m4/saveload.cpp166
-rw-r--r--engines/m4/saveload.h54
-rw-r--r--engines/m4/scene.cpp208
-rw-r--r--engines/m4/scene.h120
-rw-r--r--engines/m4/script.cpp1389
-rw-r--r--engines/m4/script.h463
-rw-r--r--engines/m4/scripttab.h135
-rw-r--r--engines/m4/sound.cpp276
-rw-r--r--engines/m4/sound.h110
-rw-r--r--engines/m4/sprite.cpp207
-rw-r--r--engines/m4/sprite.h121
-rw-r--r--engines/m4/staticres.cpp61
-rw-r--r--engines/m4/staticres.h56
-rw-r--r--engines/m4/viewmgr.cpp444
-rw-r--r--engines/m4/viewmgr.h204
-rw-r--r--engines/m4/woodscript.cpp398
-rw-r--r--engines/m4/woodscript.h348
-rw-r--r--engines/m4/ws_machine.cpp423
-rw-r--r--engines/m4/ws_sequence.cpp768
-rw-r--r--gui/credits.h6
84 files changed, 0 insertions, 28600 deletions
diff --git a/AUTHORS b/AUTHORS
index c20f43e7b3..e152e3a21b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -122,12 +122,6 @@ ScummVM Team
Lure:
Paul Gilbert
- M4:
- Torbjorn Andersson
- Paul Gilbert
- Benjamin Haisch
- Filippos Karapetis
-
MADE:
Benjamin Haisch
Filippos Karapetis
diff --git a/audio/decoders/flac.h b/audio/decoders/flac.h
index a90675cc20..f5e31684fe 100644
--- a/audio/decoders/flac.h
+++ b/audio/decoders/flac.h
@@ -26,7 +26,6 @@
* - agos
* - draci
* - kyra
- * - m4
* - queen
* - saga
* - sci
diff --git a/audio/decoders/mp3.h b/audio/decoders/mp3.h
index cb0cc8375d..df2ee44805 100644
--- a/audio/decoders/mp3.h
+++ b/audio/decoders/mp3.h
@@ -26,7 +26,6 @@
* - agos
* - draci
* - kyra
- * - m4
* - mohawk
* - queen
* - saga
diff --git a/audio/decoders/vorbis.h b/audio/decoders/vorbis.h
index 9e7600af56..3a3052ed7c 100644
--- a/audio/decoders/vorbis.h
+++ b/audio/decoders/vorbis.h
@@ -26,7 +26,6 @@
* - agos
* - draci
* - kyra
- * - m4
* - queen
* - saga
* - sci
diff --git a/base/plugins.cpp b/base/plugins.cpp
index 3e18e0ec4e..e587b962d6 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -133,9 +133,6 @@ public:
#if PLUGIN_ENABLED_STATIC(LURE)
LINK_PLUGIN(LURE)
#endif
- #if PLUGIN_ENABLED_STATIC(M4)
- LINK_PLUGIN(M4)
- #endif
#if PLUGIN_ENABLED_STATIC(MADE)
LINK_PLUGIN(MADE)
#endif
diff --git a/configure b/configure
index b7b0794a25..96667e643f 100755
--- a/configure
+++ b/configure
@@ -98,7 +98,6 @@ add_engine kyra "Legend of Kyrandia" yes "lol"
add_engine lol "Lands of Lore" yes
add_engine lastexpress "The Last Express" no
add_engine lure "Lure of the Temptress" yes
-add_engine m4 "M4/MADS" no
add_engine made "MADE" yes
add_engine mohawk "Mohawk" yes "cstime myst riven"
add_engine cstime "Where in Time is Carmen Sandiego?" no
diff --git a/dists/engine-data/m4.dat b/dists/engine-data/m4.dat
deleted file mode 100644
index 3181d0182c..0000000000
--- a/dists/engine-data/m4.dat
+++ /dev/null
Binary files differ
diff --git a/dists/engine-data/mads.dat b/dists/engine-data/mads.dat
deleted file mode 100644
index b27f9d4471..0000000000
--- a/dists/engine-data/mads.dat
+++ /dev/null
Binary files differ
diff --git a/dists/scummvm.rc b/dists/scummvm.rc
index ce287cdd42..d7d2b7f4cb 100644
--- a/dists/scummvm.rc
+++ b/dists/scummvm.rc
@@ -31,9 +31,6 @@ kyra.dat FILE "dists/engine-data/kyra.dat"
#if ENABLE_LURE == STATIC_PLUGIN
lure.dat FILE "dists/engine-data/lure.dat"
#endif
-#if ENABLE_M4 == STATIC_PLUGIN
-m4.dat FILE "dists/engine-data/m4.dat"
-#endif
#if ENABLE_QUEEN == STATIC_PLUGIN
queen.tbl FILE "dists/engine-data/queen.tbl"
#endif
diff --git a/engines/m4/actor.cpp b/engines/m4/actor.cpp
deleted file mode 100644
index 80a3624475..0000000000
--- a/engines/m4/actor.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/array.h"
-#include "common/textconsole.h"
-#include "m4/actor.h"
-#include "m4/m4_views.h"
-#include "m4/assets.h"
-
-namespace M4 {
-
-#define WALKER_BURGER "Wilbur0%i" // wilbur, with a number denoting his current direction
-
-Actor::Actor(MadsM4Engine *vm) : _vm(vm) {
- _scaling = 100;
- _direction = 5;
- _walkerSprites.resize(10);
- loadWalkers();
-}
-
-Actor::~Actor() {
- unloadWalkers();
-}
-
-int Actor::getWalkerWidth() { return _walkerSprites[kFacingSouth]->getFrame(0)->width(); }
-int Actor::getWalkerHeight() { return _walkerSprites[kFacingSouth]->getFrame(0)->height(); }
-
-void Actor::placeWalkerSpriteAt(int spriteNum, int x, int y) {
- if (_direction < 1 || _direction > 9) {
- warning("Direction is %i, fixing", _direction);
- _direction = 1; // TODO: this is a temporary fix
- }
- SpriteInfo info;
- info.sprite = _walkerSprites[_direction]->getFrame(spriteNum);
- info.hotX = info.hotY = 0;
- info.width = info.sprite->width();
- info.height = info.sprite->height();
- info.scaleX = info.scaleY = _scaling;
- info.palette = _walkerSprites[_direction]->getPalette();
- info.inverseColorTable = _m4Vm->scene()->getInverseColorTable();
-
- _vm->_scene->drawSprite(x, y, info, Common::Rect(640, 400));
-}
-
-void Actor::loadWalkers() {
- for (uint8 i = 1; i < 10; i++) {
- if (i == 6)
- continue; // walker sprite 6 is unused
- loadWalkerDirection(i);
- }
-}
-
-void Actor::loadWalkerDirection(uint8 direction) {
- char name[20];
- Common::SeekableReadStream *walkerS;
-
- if (_vm->getGameType() == GType_Burger) {
- sprintf(name, WALKER_BURGER, direction);
- } else {
- //warning("Actor::loadWalkerDirection: unspecified walker type, not loading walker");
- // TODO: Master Lu walkers
- return;
- }
-
- walkerS = _vm->res()->get(name);
- _walkerSprites.insert_at(direction, new SpriteAsset(_vm, walkerS, walkerS->size(), name));
- _vm->res()->toss(name);
-}
-
-void Actor::unloadWalkers() {
- for (uint8 i = 9; i > 0; i--) {
- if (i == 6)
- continue; // walker sprite 6 is unused
- SpriteAsset *tempSprite = _walkerSprites[i];
- _walkerSprites.remove_at(i);
- delete tempSprite;
- }
-}
-
-void Actor::setWalkerPalette() {
- _vm->_palette->setPalette(_walkerSprites[kFacingSouthEast]->getPalette(), 0,
- _walkerSprites[kFacingSouthEast]->getColorCount());
-}
-
-Inventory::Inventory(MadsM4Engine *vm) : _vm(vm) {
-}
-
-Inventory::~Inventory() {
- _inventory.clear();
-}
-
-void Inventory::registerObject(char* name, int32 scene, int32 icon) {
- InventoryObject *newObject = new InventoryObject();
- int newObjectIndex = 0;
-
- // Capitalize registered inventory object names
- str_upper(name);
-
- newObject->name = strdup(name);
- newObject->scene = scene;
- newObject->icon = icon;
-
- newObjectIndex = _inventory.size();
-
- _inventory.push_back(newObject);
-
- if (scene == BACKPACK)
- addToBackpack(newObjectIndex);
-}
-
-void Inventory::moveObject(char* name, int32 scene) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name)) {
- if (_inventory[i]->scene == BACKPACK && scene != BACKPACK)
- removeFromBackpack(i);
-
- _inventory[i]->scene = scene;
-
- if (scene == BACKPACK)
- addToBackpack(i);
-
- return;
- }
- }
-}
-
-void Inventory::addToBackpack(uint32 objectIndex) {
- _m4Vm->scene()->getInterface()->inventoryAdd(_inventory[objectIndex]->name, "", _inventory[objectIndex]->icon);
-}
-
-void Inventory::removeFromBackpack(uint32 objectIndex) {
- _m4Vm->scene()->getInterface()->inventoryRemove(_inventory[objectIndex]->name);
-}
-
-bool Inventory::isInCurrentScene(char* name) {
- return (getScene(name) == _vm->_scene->getCurrentScene());
-}
-
-int Inventory::getScene(char* name) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name))
- return _inventory[i]->scene;
- }
- return UNKNOWN_OBJECT;
-}
-
-int Inventory::getIcon(char* name) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name))
- return _inventory[i]->icon;
- }
- return UNKNOWN_OBJECT;
-}
-
-int Inventory::getIndex(char* name) {
- uint i = 0;
-
- for (i = 0; i < _inventory.size(); i++) {
- if (!scumm_stricmp(_inventory[i]->name, name))
- return i;
- }
- return UNKNOWN_OBJECT;
-}
-
-void Inventory::clear() {
- for (uint i = 0; i < _inventory.size(); i++) {
- delete _inventory[i]->name;
- delete _inventory[i];
- _inventory.remove_at(i);
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/actor.h b/engines/m4/actor.h
deleted file mode 100644
index e28c522df8..0000000000
--- a/engines/m4/actor.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_ACTOR_H
-#define M4_ACTOR_H
-
-#include "common/array.h"
-
-#include "m4/m4.h"
-#include "m4/scene.h"
-#include "m4/graphics.h"
-#include "m4/assets.h"
-
-namespace M4 {
-
-struct InventoryObject {
- const char* name;
- int32 scene;
- int32 icon;
-};
-
-enum inventoryObjectFlags {
- UNKNOWN_OBJECT = 997,
- BACKPACK = 998,
- NOWHERE = 999
-};
-
-enum WalkerDirection {
- kFacingNorth = 1, // has shadow
- kFacingNorthEast = 2, // has shadow
- kFacingEast = 3, // has shadow
- kFacingSouthEast = 4, // has shadow
- kFacingSouth = 5, // has shadow
- // 6 is unused
- kFacingSouthAlt = 7, // no shadow
- kFacingSouthWest = 8, // no shadow
- kFacingWest = 9 // no shadow
-};
-
-class Actor {
-public:
- Actor(MadsM4Engine *vm);
- ~Actor();
- void placeWalkerSpriteAt(int spriteNum, int x, int y);
- void setWalkerScaling(int scaling) { _scaling = scaling; }
- int getWalkerScaling() { return _scaling; }
- void setWalkerDirection(uint8 direction) { _direction = direction; }
- uint8 getWalkerDirection() { return _direction; }
- void setWalkerPalette();
- int getWalkerWidth();
- int getWalkerHeight();
-private:
- MadsM4Engine *_vm;
- int _scaling;
- uint8 _direction;
- Common::Array<SpriteAsset*> _walkerSprites;
-
- void loadWalkers();
- void loadWalkerDirection(uint8 direction);
- void unloadWalkers();
-};
-
-// TODO: perhaps the inventory and its view could be merged?
-// TODO: the original game capitalizes all inventory object names
-// internally, which we do as well, but perhaps we could make sure
-// that all object names are parsed with the same case and avoid
-// case-insensitive string comparing through scumm_stricmp, using
-// the normal strcmp method instead
-class Inventory {
-public:
- Inventory(MadsM4Engine *vm);
- ~Inventory();
- void clear();
- void registerObject(char* name, int32 scene, int32 icon);
- void moveObject(char* name, int32 scene);
- void giveToPlayer(char* name) { moveObject(name, BACKPACK); }
- void addToBackpack(uint32 objectIndex);
- void removeFromBackpack(uint32 objectIndex);
- bool isInBackpack(char* name) { return (getScene(name) == BACKPACK); }
- bool isInScene(char* name, int32 scene) { return (getScene(name) == scene); }
- bool isInCurrentScene(char* name);
- int getScene(char* name);
- int getIcon(char* name);
- int getIndex(char* name);
- int getTotalItems() { return _inventory.size(); }
-
-private:
- MadsM4Engine *_vm;
- Common::Array<InventoryObject *> _inventory;
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp
deleted file mode 100644
index 4f315dd396..0000000000
--- a/engines/m4/animation.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/assets.h"
-#include "m4/animation.h"
-#include "m4/compression.h"
-#include "m4/mads_scene.h"
-
-namespace M4 {
-
-// TODO: this code needs cleanup
-
-MadsAnimation::MadsAnimation(MadsM4Engine *vm, MadsView *view): Animation(vm), _view(view) {
- _font = NULL;
- _resetFlag = false;
- _freeFlag = false;
- _skipLoad = false;
- _unkIndex = -1;
- _messageCtr= 0;
- _field12 = 0;
-
- _currentFrame = 0;
- _oldFrameEntry = 0;
- _nextFrameTimer = _madsVm->_currentTimer;
- _nextScrollTimer = 0;
-}
-
-MadsAnimation::~MadsAnimation() {
- for (uint i = 0; i < _messages.size(); ++i) {
- if (_messages[i].kernelMsgIndex >= 0)
- _view->_kernelMessages.remove(_messages[i].kernelMsgIndex);
- }
-
- // Further deletion logic
- if (_field12) {
- _view->_spriteSlots.deleteSprites(_spriteListIndexes[_spriteListIndex]);
- }
-}
-
-#define FILENAME_SIZE 13
-
-/**
- * Initializes and loads the data of an animation
- */
-void MadsAnimation::initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) {
- MadsPack anim(filename.c_str(), _vm);
- bool madsRes = filename[0] == '*';
- char buffer[20];
- int streamIndex = 1;
-
- // Chunk 1: header
- // header
-
- Common::SeekableReadStream *animStream = anim.getItemStream(0);
-
- int spriteListCount = animStream->readUint16LE();
- int miscEntriesCount = animStream->readUint16LE();
- int frameEntryCount = animStream->readUint16LE();
- int messagesCount = animStream->readUint16LE();
- animStream->skip(1);
- _flags = animStream->readByte();
-
- animStream->skip(2);
- _animMode = animStream->readUint16LE();
- _roomNumber = animStream->readUint16LE();
- animStream->skip(2);
- _field12 = animStream->readUint16LE() != 0;
- _spriteListIndex = animStream->readUint16LE();
- _scrollX = animStream->readSint16LE();
- _scrollY = animStream->readSint16LE();
- _scrollTicks = animStream->readUint16LE();
- animStream->skip(8);
-
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _interfaceFile = Common::String(buffer);
-
- for (int i = 0; i < 10; ++i) {
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _spriteSetNames[i] = Common::String(buffer);
- }
-
- animStream->skip(81);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _lbmFilename = Common::String(buffer);
-
- animStream->skip(365);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _spritesFilename = Common::String(buffer);
-
- animStream->skip(48);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _soundName = Common::String(buffer);
-
- animStream->skip(13);
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- _dsrName = Common::String(buffer);
-
- animStream->read(buffer, FILENAME_SIZE);
- buffer[FILENAME_SIZE] = '\0';
- Common::String fontResource(buffer);
-
- if (_animMode == 4)
- flags |= 0x4000;
- if (flags & 0x100)
- loadInterface(surface, depthSurface);
-
- // Initialize the reference list
- for (int i = 0; i < spriteListCount; ++i)
- _spriteListIndexes.push_back(-1);
-
- delete animStream;
-
- if (messagesCount > 0) {
- // Chunk 2
- // Following is a list of any messages for the animation
-
- animStream = anim.getItemStream(streamIndex++);
-
- for (int i = 0; i < messagesCount; ++i) {
- AnimMessage rec;
- rec.soundId = animStream->readSint16LE();
- animStream->read(rec.msg, 64);
- animStream->skip(4);
- rec.pos.x = animStream->readSint16LE();
- rec.pos.y = animStream->readSint16LE();
- rec.flags = animStream->readUint16LE();
- rec.rgb1.r = animStream->readByte() << 2;
- rec.rgb1.g = animStream->readByte() << 2;
- rec.rgb1.b = animStream->readByte() << 2;
- rec.rgb2.r = animStream->readByte() << 2;
- rec.rgb2.g = animStream->readByte() << 2;
- rec.rgb2.b = animStream->readByte() << 2;
- animStream->skip(2); // Space for kernelMsgIndex
- rec.kernelMsgIndex = -1;
- animStream->skip(6);
- rec.startFrame = animStream->readUint16LE();
- rec.endFrame = animStream->readUint16LE();
- animStream->skip(2);
-
- _messages.push_back(rec);
- }
-
- delete animStream;
- }
-
- if (frameEntryCount > 0) {
- // Chunk 3: animation frame info
- animStream = anim.getItemStream(streamIndex++);
-
- for (int i = 0; i < frameEntryCount; i++) {
- AnimFrameEntry rec;
- rec.frameNumber = animStream->readUint16LE();
- rec.seqIndex = animStream->readByte();
- rec.spriteSlot.spriteListIndex = animStream->readByte();
- rec.spriteSlot.frameNumber = animStream->readUint16LE();
- rec.spriteSlot.xp = animStream->readSint16LE();
- rec.spriteSlot.yp = animStream->readSint16LE();
- rec.spriteSlot.depth = animStream->readSByte();
- rec.spriteSlot.scale = (int8)animStream->readByte();
-
- _frameEntries.push_back(rec);
- }
-
- delete animStream;
- }
-
- if (miscEntriesCount > 0) {
- // Chunk 4: Misc Data
- animStream = anim.getItemStream(streamIndex);
-
- for (int i = 0; i < miscEntriesCount; ++i) {
- AnimMiscEntry rec;
- rec.soundNum = animStream->readByte();
- rec.msgIndex = animStream->readSByte();
- rec.numTicks = animStream->readUint16LE();
- rec.posAdjust.x = animStream->readUint16LE();
- rec.posAdjust.y = animStream->readUint16LE();
- animStream->readUint16LE();
-
- _miscEntries.push_back(rec);
- }
-
- delete animStream;
- }
-
- // If the animation specifies a font, then load it for access
- if (_flags & ANIM_CUSTOM_FONT) {
- Common::String fontName;
- if (madsRes)
- fontName += "*";
- fontName += fontResource;
-
- if (fontName != "")
- _font = _vm->_font->getFont(fontName.c_str());
- else
- warning("Attempted to set a font with an empty name");
- }
-
- // If a speech file is specified, then load it
- if (!_dsrName.empty())
- _vm->_sound->loadDSRFile(_dsrName.c_str());
-
- // Load all the sprite sets for the animation
- for (int i = 0; i < spriteListCount; ++i) {
- if (_field12 && (i == _spriteListIndex))
- // Skip over field, since it's manually loaded
- continue;
-
- _spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str());
- }
-
-
- if (_field12) {
- Common::String resName;
- if (madsRes)
- resName += "*";
- resName += _spriteSetNames[_spriteListIndex];
-
- _spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str());
- }
-
- // TODO: Unknown section about handling sprite set list combined with messages size
-
- // TODO: The original has two separate loops for the loop below based on _animMode == 4. Is it
- // perhaps that in that mode the sprite frames has a different format..?
-
- // Remap the sprite list index fields from the initial value to the indexes of the loaded
- // sprite sets for the animation
- for (uint i = 0; i < _frameEntries.size(); ++i) {
- int idx = _frameEntries[i].spriteSlot.spriteListIndex;
- _frameEntries[i].spriteSlot.spriteListIndex = _spriteListIndexes[idx];
- }
-
- if (hasScroll())
- _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks;
-}
-
-/**
- * Loads an animation file for display
- */
-void MadsAnimation::load(const Common::String &filename, int abortTimers) {
- initialize(filename, 0, NULL, NULL);
- _messageCtr = 0;
- _skipLoad = true;
-
-/* TODO: figure out extra stuff in this routine
- if (_field12) {
- _unkIndex = -1;
- int listIndex = _spriteListIndexes[_spriteListIndex];
- SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex);
- ..?..
- }
-*/
-
- // Initialize miscellaneous fields
- _currentFrame = 0;
- _oldFrameEntry = 0;
- _nextFrameTimer = _madsVm->_currentTimer;
- _abortTimers = abortTimers;
- _abortMode = _madsVm->scene()->_abortTimersMode2;
-
- if (_madsVm->_scene)
- _actionNouns = _madsVm->scene()->_action._action;
-
- // Initialize kernel message list
- for (uint i = 0; i < _messages.size(); ++i)
- _messages[i].kernelMsgIndex = -1;
-}
-
-void MadsAnimation::update() {
- if (_field12) {
- int spriteListIndex = _spriteListIndexes[_spriteListIndex];
- int newIndex = -1;
-
- for (uint idx = _oldFrameEntry; idx < _frameEntries.size(); ++idx) {
- if (_frameEntries[idx].frameNumber > _currentFrame)
- break;
- if (_frameEntries[idx].spriteSlot.spriteListIndex == spriteListIndex)
- newIndex = _frameEntries[idx].spriteSlot.frameNumber;
- }
-
- if (newIndex >= 0)
- load1(newIndex);
- }
-
- // Check for scroll change
- bool screenChanged = false;
-
- // Handle any scrolling of the screen surface
- if (hasScroll() && (_madsVm->_currentTimer >= _nextScrollTimer)) {
- _view->_bgSurface->scrollX(_scrollX);
- _view->_bgSurface->scrollY(_scrollY);
-
- _nextScrollTimer = _madsVm->_currentTimer + _scrollTicks;
- screenChanged = true;
- }
-
- // If it's not time for the next frame, then exit
- if (_madsVm->_currentTimer < _nextFrameTimer) {
- if (screenChanged)
- _view->_spriteSlots.fullRefresh();
- return;
- }
-
- // Loop checks for any prior animation sprite slots to be expired
- for (int slotIndex = 0; slotIndex < _view->_spriteSlots.startIndex; ++slotIndex) {
- if (_view->_spriteSlots[slotIndex].seqIndex >= 0x80) {
- // Flag the frame as animation sprite slot
- _view->_spriteSlots[slotIndex].spriteType = EXPIRED_SPRITE;
- }
- }
-
- // Validate the current frame
- if (_currentFrame >= (int)_miscEntries.size()) {
- // Is the animation allowed to be repeated?
- if (_resetFlag) {
- _currentFrame = 0;
- _oldFrameEntry = 0;
- } else {
- _freeFlag = true;
- return;
- }
- }
-
- // Handle starting any sound for this frame
- AnimMiscEntry &misc = _miscEntries[_currentFrame];
- if (misc.soundNum)
- _vm->_sound->playSound(misc.soundNum);
-
- // Handle any offset adjustment for sprites as of this frame
- if (_view->_posAdjust.x != misc.posAdjust.x) {
- _view->_posAdjust.x = misc.posAdjust.x;
- screenChanged = true;
- }
- if (_view->_posAdjust.y != misc.posAdjust.y) {
- _view->_posAdjust.y = misc.posAdjust.y;
- screenChanged = true;
- }
-
-
- if (screenChanged) {
- // Signal the entire screen needs refreshing
- _view->_spriteSlots.fullRefresh();
- }
-
- int spriteSlotsMax = _view->_spriteSlots.startIndex;
-
- // Main frame animation loop - frames get animated by being placed, as necessary, into the
- // main sprite slot array
- while ((uint)_oldFrameEntry < _frameEntries.size()) {
- if (_frameEntries[_oldFrameEntry].frameNumber > _currentFrame)
- break;
- else if (_frameEntries[_oldFrameEntry].frameNumber == _currentFrame) {
- // Found the correct frame
- int spriteSlotIndex = 0;
- int index = 0;
-
- for (;;) {
- if ((spriteSlotIndex == 0) && (index < spriteSlotsMax)) {
- int seqIndex = _frameEntries[_oldFrameEntry].seqIndex - _view->_spriteSlots[index].seqIndex;
- if (seqIndex == 0x80) {
- if (_view->_spriteSlots[index] == _frameEntries[_oldFrameEntry].spriteSlot) {
- _view->_spriteSlots[index].spriteType = SPRITE_ZERO;
- spriteSlotIndex = -1;
- }
- }
- ++index;
- continue;
- }
-
- if (spriteSlotIndex == 0) {
- int slotIndex = _view->_spriteSlots.getIndex();
- MadsSpriteSlot &slot = _view->_spriteSlots[slotIndex];
- slot.copy(_frameEntries[_oldFrameEntry].spriteSlot);
- slot.seqIndex = _frameEntries[_oldFrameEntry].seqIndex + 0x80;
-
- SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(
- _view->_spriteSlots[slotIndex].spriteListIndex);
- slot.spriteType = spriteSet.isBackground() ? BACKGROUND_SPRITE : FOREGROUND_SPRITE;
- }
- break;
- }
- }
-
- ++_oldFrameEntry;
- }
-
- // Handle the display of any messages
- for (uint idx = 0; idx < _messages.size(); ++idx) {
- if (_messages[idx].kernelMsgIndex >= 0) {
- // Handle currently active message
- if ((_currentFrame < _messages[idx].startFrame) || (_currentFrame > _messages[idx].endFrame)) {
- _view->_kernelMessages.remove(_messages[idx].kernelMsgIndex);
- _messages[idx].kernelMsgIndex = -1;
- --_messageCtr;
- }
- } else if ((_currentFrame >= _messages[idx].startFrame) && (_currentFrame <= _messages[idx].endFrame)) {
- // Start displaying the message
- AnimMessage &me = _messages[idx];
-
- // The color index to use is dependant on how many messages are currently on-screen
- uint8 colIndex;
- switch (_messageCtr) {
- case 1:
- colIndex = 252;
- break;
- case 2:
- colIndex = 16;
- break;
- default:
- colIndex = 250;
- break;
- }
-
- _vm->_palette->setEntry(colIndex, me.rgb1.r, me.rgb1.g, me.rgb1.b);
- _vm->_palette->setEntry(colIndex + 1, me.rgb2.r, me.rgb2.g, me.rgb2.b);
-
- // Add a kernel message to display the given text
- me.kernelMsgIndex = _view->_kernelMessages.add(me.pos, colIndex * 0x101 + 0x100, 0, 0, INDEFINITE_TIMEOUT, me.msg);
- assert(me.kernelMsgIndex >= 0);
-
- // Play the associated sound, if it exists
- if (me.soundId > 0)
- _vm->_sound->playDSRSound(me.soundId - 1, 255, false);
- ++_messageCtr;
- }
- }
-
- // Move to the next frame
- _currentFrame++;
- if (_currentFrame >= (int)_miscEntries.size()) {
- // Animation is complete
- if (_abortTimers != 0) {
- _view->_abortTimers = _abortTimers;
- _view->_abortTimersMode = _abortMode;
-
- if (_abortMode != ABORTMODE_1) {
- // Copy the noun list
- if (_madsVm->_scene)
- _madsVm->scene()->_action._action = _actionNouns;
- }
- }
- }
-
- int frameNum = MIN(_currentFrame, (int)_miscEntries.size() - 1);
- _nextFrameTimer = _madsVm->_currentTimer + _miscEntries[frameNum].numTicks;
-}
-
-void MadsAnimation::setCurrentFrame(int frameNumber) {
- _currentFrame = frameNumber;
- _oldFrameEntry = 0;
- _freeFlag = false;
-
- _nextScrollTimer = _nextFrameTimer = _madsVm->_currentTimer;
-}
-
-int MadsAnimation::getCurrentFrame() {
- return _currentFrame;
-}
-
-void MadsAnimation::load1(int frameNumber) {
- if (_skipLoad)
- return;
-
- Common::Point pt;
- int listIndex = _spriteListIndexes[_spriteListIndex];
- SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex);
-
- if (_unkIndex < 0) {
- M4Surface *frame = spriteSet.getFrame(0);
- pt.x = frame->bounds().left;
- pt.y = frame->bounds().top;
- } else {
- pt.x = _unkList[_unkIndex].x;
- pt.y = _unkList[_unkIndex].y;
- _unkIndex = 1 - _unkIndex;
- }
-
- if (proc1(spriteSet, pt, frameNumber))
- error("proc1 failure");
-}
-
-bool MadsAnimation::proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber) {
- return 0;
-}
-
-void MadsAnimation::loadInterface(M4Surface *&interfaceSurface, M4Surface *&depthSurface) {
- if (_animMode <= 2) {
- MadsSceneResources sceneResources;
- sceneResources.load(_roomNumber, _interfaceFile.c_str(), 0, depthSurface, interfaceSurface);
-
- } else if (_animMode == 4) {
- // Load a scene interface
- interfaceSurface->madsLoadInterface(_interfaceFile);
- } else {
- // This mode allocates two large surfaces for the animation
- // TODO: Are these ever properly freed?
-error("Anim mode %d - need to check free logic", _animMode);
- assert(!interfaceSurface);
- assert(!depthSurface);
- depthSurface = new M4Surface(MADS_SURFACE_WIDTH, MADS_SCREEN_HEIGHT);
- interfaceSurface = new M4Surface(MADS_SURFACE_WIDTH, MADS_SCREEN_HEIGHT);
- depthSurface->clear();
- interfaceSurface->clear();
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/animation.h b/engines/m4/animation.h
deleted file mode 100644
index 68a2883241..0000000000
--- a/engines/m4/animation.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_ANIMATION_H
-#define M4_ANIMATION_H
-
-#include "m4/m4.h"
-#include "m4/graphics.h"
-#include "m4/assets.h"
-#include "m4/mads_views.h"
-#include "common/array.h"
-
-namespace M4 {
-
-class MadsView;
-class SpriteSlotSubset;
-
-class AnimMessage {
-public:
- int16 soundId;
- char msg[64];
- Common::Point pos;
- RGB8 rgb1, rgb2;
- uint16 flags;
- int startFrame, endFrame;
- int kernelMsgIndex;
-};
-
-class AnimFrameEntry {
-public:
- int frameNumber;
- int seqIndex;
- SpriteSlotSubset spriteSlot;
-};
-
-class AnimMiscEntry {
-public:
- int soundNum;
- int msgIndex;
- int numTicks;
- Common::Point posAdjust;
-};
-
-#define ANIM_SPRITE_SET_SIZE 50
-
-enum MadsAnimationFlags {ANIM_CUSTOM_FONT = 0x20, ANIM_HAS_SOUND = 0x8000};
-
-class MadsAnimation: public Animation {
-private:
- MadsView *_view;
-
- int _spriteListCount;
- Common::Array<AnimMessage> _messages;
- Common::Array<AnimFrameEntry> _frameEntries;
- Common::Array<AnimMiscEntry> _miscEntries;
- Font *_font;
-
- uint8 _flags;
- int _animMode;
- int _roomNumber;
- bool _field12;
- int _spriteListIndex;
- int _scrollX;
- int _scrollY;
- int _scrollTicks;
- Common::String _interfaceFile;
- Common::String _spriteSetNames[10];
- Common::String _lbmFilename;
- Common::String _spritesFilename;
- Common::String _soundName;
- Common::String _dsrName;
- Common::Array<int> _spriteListIndexes;
-
- int _currentFrame, _oldFrameEntry;
- bool _resetFlag;
- bool _freeFlag;
- bool _skipLoad;
- int _unkIndex;
- Common::Point _unkList[2];
- uint32 _nextFrameTimer;
- uint32 _nextScrollTimer;
- int _messageCtr;
- int _abortTimers;
- AbortTimerMode _abortMode;
- ActionDetails _actionNouns;
-
- void load1(int frameNumber);
- bool proc1(SpriteAsset &spriteSet, const Common::Point &pt, int frameNumber);
- void loadInterface(M4Surface *&interfaceSurface, M4Surface *&depthSurface);
- bool hasScroll() const { return (_scrollX != 0) || (_scrollY != 0); }
-public:
- MadsAnimation(MadsM4Engine *vm, MadsView *view);
- virtual ~MadsAnimation();
-
- virtual void initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface);
- virtual void load(const Common::String &filename, int abortTimers);
- virtual void update();
- virtual void setCurrentFrame(int frameNumber);
- virtual int getCurrentFrame();
-
- bool freeFlag() const { return _freeFlag; }
- bool getAnimMode() const { return _animMode; }
- int roomNumber() const { return _roomNumber; }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/assets.cpp b/engines/m4/assets.cpp
deleted file mode 100644
index e871218ec1..0000000000
--- a/engines/m4/assets.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/assets.h"
-#include "m4/globals.h"
-#include "m4/compression.h"
-#include "m4/graphics.h"
-
-#include "common/memstream.h"
-
-namespace M4 {
-
-BaseAsset::BaseAsset(MadsM4Engine *vm) : _vm(vm) {
-}
-
-BaseAsset::~BaseAsset() {
-}
-
-MachineAsset::MachineAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name) : BaseAsset(vm) {
- uint32 stateCount = stream->readUint32LE();
- for (uint32 curState = 0; curState < stateCount; curState++) {
- uint32 stateOffset = stream->readUint32LE();
- _stateTable.push_back(stateOffset);
- }
- _codeSize = size - 4 - 4 * stateCount;
- _code = new byte[_codeSize];
- stream->read(_code, _codeSize);
-}
-
-MachineAsset::~MachineAsset() {
- delete[] _code;
-}
-
-void MachineAsset::getCode(byte *&code, uint32 &codeSize) {
- code = _code;
- codeSize = _codeSize;
-}
-
-uint32 MachineAsset::getStateOffset(uint32 state) {
- assert(state < _stateTable.size());
- return _stateTable[state];
-}
-
-SequenceAsset::SequenceAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name) : BaseAsset(vm) {
- _localVarCount = stream->readUint32LE();
- _codeSize = size - 4;
- _code = new byte[_codeSize];
- stream->read(_code, _codeSize);
-}
-
-SequenceAsset::~SequenceAsset() {
- delete[] _code;
-}
-
-void SequenceAsset::getCode(byte *&code, uint32 &codeSize) {
- code = _code;
- codeSize = _codeSize;
-}
-
-
-DataAsset::DataAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name) : BaseAsset(vm) {
-
- _recCount = stream->readUint32LE();
- _recSize = stream->readUint32LE();
- _dataSize = _recCount * _recSize;
- _data = new long[_dataSize];
- for (uint32 i = 0; i < _dataSize; i++)
- _data[i] = (long)stream->readUint32LE();
-
-}
-
-DataAsset::~DataAsset() {
- delete _data;
-}
-
-long *DataAsset::getRow(int index) {
- assert(index < _recCount);
- return &_data[_recSize * index];
-}
-
-SpriteAsset::SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
- bool asStream, int flags) :
- BaseAsset(vm) {
- _stream = stream;
- _palInterface = NULL;
- _paletteData = NULL;
-
- if (_vm->isM4()) {
- loadM4SpriteAsset(vm, stream, asStream);
- } else {
- loadMadsSpriteAsset(vm, stream, flags);
- }
-}
-
-SpriteAsset::SpriteAsset(MadsM4Engine *vm, const char *name): BaseAsset(vm) {
- _stream = vm->res()->get(name);
- _palInterface = NULL;
- _paletteData = NULL;
-
- if (_vm->isM4()) {
- loadM4SpriteAsset(vm, _stream, true);
- } else {
- loadMadsSpriteAsset(vm, _stream, 0);
- }
-
- vm->res()->toss(name);
-}
-
-SpriteAsset::~SpriteAsset() {
- if (_palInterface) {
- // Internally stored palette translation data, so release it
- _palInterface->deleteRange(_paletteData);
- delete _paletteData;
- }
-
- // Delete the individual frames
- for (Common::Array<SpriteAssetFrame>::iterator it = _frames.begin(); it != _frames.end(); ++it) {
- delete (*it).frame;
- }
-
- delete _charInfo;
-}
-
-void SpriteAsset::loadM4SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, bool asStream) {
- bool isBigEndian = false;
- uint32 frameOffset;
-
- uint32 header = _stream->readUint32LE();
- if (header == HEAD_M4SS) {
- debugC(kDebugGraphics, "LE-encoded sprite\n");
- } else {
- debugC(kDebugGraphics, "BE-encoded sprite\n");
- isBigEndian = true;
- }
-
- _srcSize = parseSprite(isBigEndian);
-
- _stream->readUint32LE();
- _frameRate = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _pixelSpeed = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _maxWidth = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _maxHeight = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _stream->skip(6 * 4);
- _frameCount = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
-
- debugC(kDebugGraphics, "SpriteAsset::SpriteAsset() srcSize = %d; frameRate = %04X; pixelSpeed = %04X; maxWidth = %d; maxHeight = %d; frameCount = %d\n", _srcSize, _frameRate, _pixelSpeed, _maxWidth, _maxHeight, _frameCount);
-
- for (int curFrame = 0; curFrame < _frameCount; curFrame++) {
- frameOffset = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- _frameOffsets.push_back(frameOffset);
- }
- _frameOffsets.push_back(_srcSize - 48 - _frameCount * 4);
-
- _frameStartOffset = _stream->pos();
-
- // We don't need to load frames when streaming
- if (asStream)
- return;
-
- for (int curFrame = 0; curFrame < _frameCount; curFrame++) {
- frameOffset = _frameStartOffset + _frameOffsets[curFrame];
- _stream->seek(frameOffset);
-
- SpriteAssetFrame frame;
- loadFrameHeader(frame, isBigEndian);
-
- // Load & unpack RLE data if it's not a streaming animation
- if (frame.stream != 1) {
-
- frame.frame = new M4Sprite(stream, frame.x, frame.y, frame.w, frame.h, true, frame.comp);
-#if 0
- char fn[512];
- sprintf(fn, "%04d.raw", curFrame);
- FILE *h = fopen(fn, "wb");
- fwrite((byte*)frame.frame->getBasePtr(), frame.w * frame.h, 1, h);
- fclose(h);
-#endif
- }
-
- _frames.push_back(frame);
-
- }
-
-}
-
-void SpriteAsset::loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int flags) {
- int curFrame = 0;
- uint32 frameOffset = 0;
- MadsPack sprite(stream);
- _frameRate = 0;
- _pixelSpeed = 0;
- _maxWidth = 0;
- _maxHeight = 0;
-
- Common::SeekableReadStream *spriteStream = sprite.getItemStream(0);
- _mode = spriteStream->readByte();
- spriteStream->skip(1);
- int type1 = spriteStream->readUint16LE();
- int type2 = spriteStream->readUint16LE();
- _isBackground = (type1 != 0) && (type2 < 4);
- spriteStream->skip(32);
- _frameCount = spriteStream->readUint16LE();
-
- if (_vm->isM4() || ((flags & SPRITE_SET_CHAR_INFO) == 0))
- _charInfo = NULL;
- else
- _charInfo = new MadsSpriteSetCharInfo(spriteStream);
-
- delete spriteStream;
-
- // Get the palette data
- spriteStream = sprite.getItemStream(2);
- int numColors = 0;
- RGB8 *palData = Palette::decodeMadsPalette(spriteStream, &numColors);
- Common::copy(palData, &palData[numColors], &_palette[0]);
- if (numColors < 256)
- Common::fill((byte *)&_palette[numColors], (byte *)&_palette[256], 0);
- _colorCount = numColors;
- delete[] palData;
- delete spriteStream;
-
- spriteStream = sprite.getItemStream(1);
- Common::SeekableReadStream *spriteDataStream = sprite.getItemStream(3);
- SpriteAssetFrame frame;
- Common::Array<int> frameSizes;
- for (curFrame = 0; curFrame < _frameCount; curFrame++) {
- frame.stream = 0;
- frame.comp = 0;
- frameOffset = spriteStream->readUint32LE();
- _frameOffsets.push_back(frameOffset);
- uint32 frameSize = spriteStream->readUint32LE();
- frameSizes.push_back(frameSize);
-
- frame.x = spriteStream->readUint16LE();
- frame.y = spriteStream->readUint16LE();
- frame.w = spriteStream->readUint16LE();
- frame.h = spriteStream->readUint16LE();
- if (curFrame == 0)
- debugC(1, kDebugGraphics, "%i frames, x = %i, y = %i, w = %i, h = %i\n", _frameCount, frame.x, frame.y, frame.w, frame.h);
-
- if (_mode == 0) {
- // Create a frame and decompress the raw pixel data
- uint32 currPos = (uint32)spriteDataStream->pos();
- frame.frame = new M4Sprite(spriteDataStream, frame.x, frame.y, frame.w, frame.h, false);
- assert((uint32)spriteDataStream->pos() == (currPos + frameSize));
- }
-
- _frames.push_back(frame);
- }
-
- if (_mode != 0) {
- // Handle decompressing Fab encoded data
- for (curFrame = 0; curFrame < _frameCount; curFrame++) {
- FabDecompressor fab;
-
- int srcSize = (curFrame == (_frameCount - 1)) ? spriteDataStream->size() - _frameOffsets[curFrame] :
- _frameOffsets[curFrame + 1] - _frameOffsets[curFrame];
- byte *srcData = (byte *)malloc(srcSize);
- assert(srcData);
- spriteDataStream->read(srcData, srcSize);
-
- byte *destData = (byte *)malloc(frameSizes[curFrame]);
- assert(destData);
-
- fab.decompress(srcData, srcSize, destData, frameSizes[curFrame]);
-
- // Load the frame
- Common::MemoryReadStream *rs = new Common::MemoryReadStream(destData, frameSizes[curFrame]);
- _frames[curFrame].frame = new M4Sprite(rs, _frames[curFrame].x, _frames[curFrame].y,
- _frames[curFrame].w, _frames[curFrame].h, false);
- delete rs;
-
- free(srcData);
- free(destData);
- }
- }
-
-
- delete spriteStream;
- delete spriteDataStream;
-}
-
-int32 SpriteAsset::parseSprite(bool isBigEndian) {
-
- uint32 chunkType, chunkSize = 0;
-
- _colorCount = 0;
-
- /*format = (!isBigEndian) ? _stream->readUint32LE() : */_stream->readUint32BE();
-
- chunkType = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
-
- if (chunkType == CELS__PAL) {
- chunkSize = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- uint32 numColors = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- // TODO
- //if (palette) {
- // TODO: A sprite set palette specifies the indexes, which need not start at
- // index 0. For now, I'm simply preloading the currently active palette
- // before starting to replace existing entries
-
- _vm->_palette->grabPalette((byte *) _palette, 0, 256);
- _colorCount = 0;
-
- for (uint32 i = 0; i < numColors; i++) {
- uint32 paletteEntry = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- uint index = (paletteEntry >> 24) & 0xFF;
-
- _palette[index].r = ((paletteEntry >> 16) & 0xFF) << 2;
- _palette[index].g = ((paletteEntry >> 8) & 0xFF) << 2;
- _palette[index].b = (paletteEntry & 0xFF) << 2;
-
- _colorCount = MAX<int>(_colorCount, index);
- }
-
- /*
- } else {
- stream.seek(colorCount, )
- data += colorCount * 4;
- }
- */
- chunkType = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- }
-
- if (chunkType == CELS___SS) {
- chunkSize = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- } else {
- debugC(kDebugGraphics, "SpriteAsset::parseSprite() Expected chunk type %08X, got %08X", CELS___SS, chunkType);
- }
-
- return chunkSize;
-
-}
-
-void SpriteAsset::loadFrameHeader(SpriteAssetFrame &frameHeader, bool isBigEndian) {
- _stream->readUint32LE();
- frameHeader.stream = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.x = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.y = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.w = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.h = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.comp = (!isBigEndian) ? _stream->readUint32LE() : _stream->readUint32BE();
- frameHeader.frame = NULL;
- _stream->seek(8 * 4, SEEK_CUR);
- //debugC(kDebugGraphics, "SpriteAsset::loadFrameHeader() stream = %d; x = %d; y = %d; w = %d; h = %d; comp = %d\n", frameHeader.stream, frameHeader.x, frameHeader.y, frameHeader.w, frameHeader.h, frameHeader.comp);
-}
-
-M4Sprite *SpriteAsset::getFrame(int frameIndex) {
- if ((uint)frameIndex < _frames.size()) {
- return _frames[frameIndex].frame;
- } else {
- debugC(kDebugGraphics, "SpriteAsset::getFrame: Invalid frame %d, out of %d", frameIndex, _frames.size());
- return _frames[_frames.size() - 1].frame;
- }
-}
-
-void SpriteAsset::loadStreamingFrame(M4Sprite *frame, int frameIndex, int destX, int destY) {
- uint32 frameOffset = _frameStartOffset + _frameOffsets[frameIndex];
- _stream->seek(frameOffset);
-
- SpriteAssetFrame frameHeader;
- loadFrameHeader(frameHeader);
-
- if (frameHeader.w > 0 && frameHeader.h > 0) {
- Common::SeekableReadStream *frameData = _stream->readStream(getFrameSize(frameIndex));
- if (frameHeader.stream) {
- frame->loadDeltaRle(frameData, destX - frameHeader.x, destY - frameHeader.y);
- } else {
- frame->loadRle(frameData);
- }
- delete frameData;
- }
-
-}
-
-RGBList *SpriteAsset::getRgbList() {
- RGBList *result = new RGBList(_colorCount);
- Common::copy((byte *)&_palette[0], (byte *)&_palette[_colorCount], (byte *)result->data());
- return result;
-}
-
-void SpriteAsset::translate(RGBList *list, bool isTransparent) {
- for (int frameIndex = 0; frameIndex < _frameCount; ++frameIndex)
- _frames[frameIndex].frame->translate(list, isTransparent);
-}
-
-void SpriteAsset::translate(Palette *palette) {
- _palInterface = palette;
- _paletteData = this->getRgbList();
- palette->addRange(_paletteData);
- this->translate(_paletteData, true);
-}
-
-
-int32 SpriteAsset::getFrameSize(int index) {
- /*
- if (index + 1 == _frameCount) {
- } else {
-
- }
- */
- return _frameOffsets[index + 1] - _frameOffsets[index];
-}
-
-AssetManager::AssetManager(MadsM4Engine *vm) {
-
- _vm = vm;
-
- /* Initialize asset arrays */
- for (int i = 0; i < 256; i++) {
- _MACH[i] = NULL;
- _SEQU[i] = NULL;
- _DATA[i] = NULL;
- _CELS[i] = NULL;
- }
-
-}
-
-AssetManager::~AssetManager() {
- // unload all remaining assets
- clearAssets(kAssetTypeMACH, 0, 255);
- clearAssets(kAssetTypeSEQU, 0, 255);
- clearAssets(kAssetTypeCELS, 0, 255);
- clearAssets(kAssetTypeDATA, 0, 255);
-}
-
-bool AssetManager::clearAssets(AssetType assetType, int32 minHash, int32 maxHash) {
-
- minHash = MAX<int>(0, minHash);
- maxHash = MIN<int>(maxHash, 255);
-
- switch (assetType) {
- case kAssetTypeMACH:
- for (int i = minHash; i <= maxHash; i++)
- if (_MACH[i]) {
- delete _MACH[i];
- _MACH[i] = NULL;
- }
- break;
- case kAssetTypeSEQU:
- for (int i = minHash; i <= maxHash; i++)
- if (_SEQU[i]) {
- delete _SEQU[i];
- _SEQU[i] = NULL;
- }
- break;
- case kAssetTypeDATA:
- for (int i = minHash; i <= maxHash; i++)
- if (_DATA[i]) {
- delete _DATA[i];
- _DATA[i] = NULL;
- }
- break;
- case kAssetTypeCELS:
- for (int i = minHash; i <= maxHash; i++)
- if (_CELS[i]) {
- delete _CELS[i];
- _CELS[i] = NULL;
- }
- break;
- }
-
- // FIXME: no value is returned, returning true for now
- return true;
-}
-
-bool AssetManager::loadAsset(const char *assetName, RGB8 *palette) {
-
- debugC(kDebugGraphics, "AssetManager::loadAsset() %s\n", assetName);
-
- // TODO, better use MemoryReadStreamEndian?
- //convertAssetToLE(assetData, assetSize);
-
- Common::SeekableReadStream *assetS = _vm->res()->get(assetName);
-
- while (assetS->pos() + 12 < assetS->size()) {
- uint32 chunkType, chunkSize, chunkHash;
-
- chunkType = assetS->readUint32LE();
- chunkSize = assetS->readUint32LE() - 12; // sub 12 for the chunk header
- chunkHash = assetS->readUint32LE();
-
- debugC(kDebugGraphics, "hash = %d\n", chunkHash);
-
- // Until loading code is complete, so that chunks not fully read are skipped correctly
- uint32 nextOfs = assetS->pos() + chunkSize;
-
- switch (chunkType) {
- case CHUNK_MACH:
- debugC(kDebugGraphics, "MACH\n");
- clearAssets(kAssetTypeMACH, chunkHash, chunkHash);
- _MACH[chunkHash] = new MachineAsset(_vm, assetS, chunkSize, assetName);
- break;
- case CHUNK_SEQU:
- debugC(kDebugGraphics, "SEQU\n");
- clearAssets(kAssetTypeSEQU, chunkHash, chunkHash);
- _SEQU[chunkHash] = new SequenceAsset(_vm, assetS, chunkSize, assetName);
- break;
- case CHUNK_DATA:
- debugC(kDebugGraphics, "DATA\n");
- clearAssets(kAssetTypeDATA, chunkHash, chunkHash);
- _DATA[chunkHash] = new DataAsset(_vm, assetS, chunkSize, assetName);
- break;
- case CHUNK_CELS:
- debugC(kDebugGraphics, "CELS\n");
- clearAssets(kAssetTypeCELS, chunkHash, chunkHash);
- _CELS[chunkHash] = new SpriteAsset(_vm, assetS, chunkSize, assetName);
- break;
- default:
- debugC(kDebugGraphics, "AssetManager::loadAsset() Unknown chunk type %08X\n", chunkType);
- }
-
- // Until loading code is complete (see above)
- assetS->seek(nextOfs);
-
- }
-
- _vm->res()->toss(assetName);
-
- // FIXME: no value is returned, returning true for now
- return true;
-}
-
-int32 AssetManager::addSpriteAsset(const char *assetName, int32 hash, RGB8 *palette) {
-
- bool alreadyLoaded = false;
-
- if (hash < 0) {
- for (int i = 0; i <= 255; i++) {
- if (_CELS[i] != NULL) {
- if (_CELS[i]->getName() == assetName) {
- alreadyLoaded = true;
- hash = i;
- break;
- }
- } else {
- hash = i;
- break;
- }
- }
- } else {
- alreadyLoaded = _CELS[hash] != NULL && _CELS[hash]->getName() == assetName;
- }
-
- /* Not loaded and no empty slots */
- if (hash < 0)
- return -1;
-
- if (!alreadyLoaded) {
-
- debugC(kDebugGraphics, "AssetManager::addSpriteAsset() asset %s not loaded, loading into %d\n", assetName, hash);
-
- clearAssets(kAssetTypeCELS, hash, hash);
-
- Common::SeekableReadStream *assetS = _vm->res()->get(assetName);
- _CELS[hash] = new SpriteAsset(_vm, assetS, assetS->size(), assetName);
- _vm->res()->toss(assetName);
-
- } else {
-
- debugC(kDebugGraphics, "AssetManager::addSpriteAsset() asset %s already loaded in %d\n", assetName, hash);
-
- /* TODO/FIXME
- if (_CELS[hash].palOffset >= 0 && palette)
- restorePalette(palette, _CELS[hash].data + _CELS[hash].palOffset);
- */
-
- }
-
- return hash;
-
-}
-
-void AssetManager::restorePalette(RGB8 *palette, byte *data) {
- // TODO
-}
-
-void AssetManager::convertAssetToLE(byte *assetData, uint32 assetSize) {
-
-}
-
-MachineAsset *AssetManager::getMachine(int32 hash) {
- assert(_MACH[hash] != NULL);
- return _MACH[hash];
-}
-
-SequenceAsset *AssetManager::getSequence(int32 hash) {
- assert(_SEQU[hash] != NULL);
- return _SEQU[hash];
-}
-
-DataAsset *AssetManager::getData(int32 hash) {
- assert(_DATA[hash] != NULL);
- return _DATA[hash];
-}
-
-SpriteAsset *AssetManager::getSprite(int32 hash) {
- assert(_CELS[hash] != NULL);
- return _CELS[hash];
-}
-
-M4Sprite *AssetManager::getSpriteFrame(int32 hash, int frameIndex) {
- assert(_CELS[hash] != NULL);
- return _CELS[hash]->getFrame(frameIndex);
-}
-
-int32 AssetManager::getSpriteFrameCount(int32 hash) {
- assert(_CELS[hash] != NULL);
- return _CELS[hash]->getCount();
-}
-
-//--------------------------------------------------------------------------
-
-MadsSpriteSetCharInfo::MadsSpriteSetCharInfo(Common::SeekableReadStream *s) {
- _totalFrames = s->readByte();
- s->skip(1);
- _numEntries = s->readUint16LE();
-
- for (int i = 0; i < 16; ++i)
- _frameList[i] = s->readUint16LE();
- for (int i = 0; i < 16; ++i)
- _frameList2[i] = s->readUint16LE();
- for (int i = 0; i < 16; ++i)
- _ticksList[i] = s->readUint16LE();
-
- _unk1 = s->readUint16LE();
- _ticksAmount = s->readByte();
- _yScale = s->readByte();
-}
-
-} // End of namespace M4
diff --git a/engines/m4/assets.h b/engines/m4/assets.h
deleted file mode 100644
index 25996a421e..0000000000
--- a/engines/m4/assets.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-#ifndef M4_ASSETS_H
-#define M4_ASSETS_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-
-#include "m4/sprite.h"
-
-namespace M4 {
-
-// Sequence chunks
-#define CHUNK_SCEN MKTAG('S','C','E','N')
-#define CHUNK_MACH MKTAG('M','A','C','H')
-#define CHUNK_SEQU MKTAG('S','E','Q','U')
-#define CHUNK_DATA MKTAG('D','A','T','A')
-#define CHUNK_CELS MKTAG('C','E','L','S')
-
-// Sprite chunks
-#define HEAD_M4SS MKTAG('M','4','S','S') //'M4SS'
-#define CELS__PAL MKTAG(' ','P','A','L') //' PAL'
-#define CELS___SS MKTAG(' ',' ','S','S') //' SS'
-
-#define SPRITE_SET_CHAR_INFO 4
-
-class MadsM4Engine;
-class Palette;
-
-class BaseAsset {
-public:
- BaseAsset(MadsM4Engine *vm);
- ~BaseAsset();
- const Common::String getName() const { return _name; }
-protected:
- MadsM4Engine *_vm;
- Common::String _name;
-};
-
-class MachineAsset : public BaseAsset {
-public:
- MachineAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name);
- ~MachineAsset();
- void getCode(byte *&code, uint32 &codeSize);
- uint32 getStateOffset(uint32 state);
-protected:
- Common::Array<uint32> _stateTable;
- byte *_code;
- uint32 _codeSize;
-};
-
-class SequenceAsset : public BaseAsset {
-public:
- SequenceAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name);
- ~SequenceAsset();
- void getCode(byte *&code, uint32 &codeSize);
- int localVarCount() const { return _localVarCount; }
-protected:
- int _localVarCount;
- byte *_code;
- uint32 _codeSize;
-};
-
-class DataAsset : public BaseAsset {
-public:
- DataAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name);
- ~DataAsset();
- int getCount() const { return _recCount; }
- long *getRow(int index);
-protected:
- long *_data;
- uint32 _recSize, _dataSize;
- int _recCount;
-};
-
-struct SpriteAssetFrame {
- uint32 stream;
- int x, y, w, h;
- uint32 comp;
- M4Sprite *frame;
-};
-
-class MadsSpriteSetCharInfo {
-public:
- MadsSpriteSetCharInfo(Common::SeekableReadStream *s);
-
- int _totalFrames;
- int _numEntries;
- int _frameList2[16];
- int _frameList[16];
- int _ticksList[16];
- int _unk1;
- int _ticksAmount;
- int _yScale;
-};
-
-class SpriteAsset : public BaseAsset {
-public:
- SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int size, const char *name,
- bool asStream = false, int flags = 0);
- SpriteAsset(MadsM4Engine *vm, const char *name);
- ~SpriteAsset();
- void loadM4SpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, bool asStream);
- void loadMadsSpriteAsset(MadsM4Engine *vm, Common::SeekableReadStream* stream, int flags);
- int32 getCount() { return _frameCount; }
- int32 getFrameRate() const { return _frameRate; }
- int32 getPixelSpeed() const { return _pixelSpeed; }
- int32 getFrameWidth(int index);
- int32 getFrameHeight(int index);
- int32 getMaxFrameWidth() const { return _maxWidth; }
- int32 getMaxFrameHeight() const { return _maxHeight; }
- bool isBackground() const { return _isBackground; }
- M4Sprite *getFrame(int frameIndex);
- void loadStreamingFrame(M4Sprite *frame, int frameIndex, int destX, int destY);
- RGB8* getPalette() { return _palette; }
- int getColorCount() { return _colorCount; }
- RGBList *getRgbList();
- void translate(RGBList *list, bool isTransparent = false);
- void translate(Palette *palette);
- int32 getFrameSize(int index);
- M4Sprite *operator[](int index) { return getFrame(index); }
-public:
- MadsSpriteSetCharInfo *_charInfo;
-protected:
- Common::SeekableReadStream *_stream;
- RGB8 _palette[256];
- uint32 _colorCount;
- uint32 _srcSize;
- int32 _frameRate, _pixelSpeed;
- int _maxWidth, _maxHeight;
- int _frameCount;
- Common::Array<uint32> _frameOffsets;
- Common::Array<SpriteAssetFrame> _frames;
- uint32 _frameStartOffset;
-
- // MADS sprite set fields
- uint8 _mode;
- bool _isBackground;
-
- int32 parseSprite(bool isBigEndian = false);
- void loadFrameHeader(SpriteAssetFrame &frameHeader, bool isBigEndian = false);
-private:
- RGBList *_paletteData;
- Palette *_palInterface;
-};
-
-enum AssetType {
- kAssetTypeMACH,
- kAssetTypeSEQU,
- kAssetTypeDATA,
- kAssetTypeCELS
-};
-
-enum CallbackHandlers {
- kCallbackTriggerDispatch
-};
-
-class AssetManager {
-public:
-
- AssetManager(MadsM4Engine *vm);
- ~AssetManager();
-
- bool clearAssets(AssetType assetType, int32 minHash, int32 maxHash);
- bool loadAsset(const char *assetName, RGB8 *palette);
- int32 addSpriteAsset(const char *assetName, int32 hash, RGB8 *palette);
-
- // TODO: Move to Palette class
- void restorePalette(RGB8 *palette, byte *data);
-
- MachineAsset *getMachine(int32 hash);
- SequenceAsset *getSequence(int32 hash);
- DataAsset *getData(int32 hash);
- SpriteAsset *getSprite(int32 hash);
- M4Sprite *getSpriteFrame(int32 hash, int frameIndex);
- int32 getSpriteFrameCount(int32 hash);
-
-protected:
- // TODO: Check if we need _vm
- MadsM4Engine *_vm;
-
- MachineAsset *_MACH[256];
- SequenceAsset *_SEQU[256];
- DataAsset *_DATA[256];
- SpriteAsset *_CELS[256];
-
- void convertAssetToLE(byte *assetData, uint32 assetSize);
-
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/burger_data.h b/engines/m4/burger_data.h
deleted file mode 100644
index d30e546023..0000000000
--- a/engines/m4/burger_data.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_BURGER_DATA_H
-#define M4_BURGER_DATA_H
-
-#include "m4/graphics.h"
-#include "m4/actor.h"
-
-namespace M4 {
-
-InventoryObject burger_inventory [] = {
- // name scene icon
- //-------------------- ----- -----
- { "empty jug", 303, 14 },
- { "distilled juice", 999, 15 },
- { "broken puz dispenser", 999, 16 },
- { "puz dispenser", 999, 17 },
- { "broken mouse trap", 999, 18 },
- { "mouse trap", 999, 19 },
- { "kindling", 999, 20 },
- { "burning kindling", 999, 21 },
- { "lights", 508, 22 },
- { "lights on", 508, 23 },
- { "bottle", 999, 24 },
- { "carrot juice", 999, 25 },
- { "soapy water", 999, 26 },
- { "iron filings", 999, 27 },
- { "waxed hair", 999, 28 },
- { "fish", 999, 29 },
- { "hook", 999, 30 },
- { "keys", 999, 31 },
- { "records", 999, 32 },
- { "collar", 999, 33 },
- { "amp", 999, 34 },
- { "rubber gloves", 999, 35 },
- { "sock", 504, 36 },
- { "jaws of life", 999, 37 },
- { "deed", 999, 38 },
- { "burger morsel", 999, 39 },
- { "whistle", 999, 40 },
- { "coin", 999, 41 },
- { "matches", 999, 42 },
- { "phone cord", 999, 43 },
- { "kibble", 602, 44 }, // picked up from tray
- { "pantyhose", 999, 45 },
- { "fan belt", 999, 46 },
- { "spring", 999, 47 },
- { "mirror", 999, 48 },
- { "grate", 999, 49 },
- { "ray gun", 604, 50 }, // given to Wilbur when he enters 604
- { "grasshoppers", 999, 51 },
- { "rolling pin", 999, 52 },
- { "rubber duck", 999, 53 },
- { "ladder", 999, 54 },
- { "money", 999, 55 },
- { "crow bar", 999, 56 },
- { "Wilbur", 999, 57 }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/compression.cpp b/engines/m4/compression.cpp
deleted file mode 100644
index 65a25c14e3..0000000000
--- a/engines/m4/compression.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/compression.h"
-#include "m4/m4.h"
-
-#include "common/memstream.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-const char *madsPackString = "MADSPACK";
-
-bool MadsPack::isCompressed(Common::SeekableReadStream *stream) {
- // Check whether the passed stream is packed
-
- char tempBuffer[8];
- stream->seek(0);
- if (stream->read(tempBuffer, 8) == 8) {
- if (!strncmp(tempBuffer, madsPackString, 8))
- return true;
- }
-
- return false;
-}
-
-MadsPack::MadsPack(Common::SeekableReadStream *stream) {
- initialize(stream);
-}
-
-MadsPack::MadsPack(const char *resourceName, MadsM4Engine* vm) {
- Common::SeekableReadStream *stream = vm->_resourceManager->get(resourceName);
- initialize(stream);
- vm->_resourceManager->toss(resourceName);
-}
-
-void MadsPack::initialize(Common::SeekableReadStream *stream) {
- if (!MadsPack::isCompressed(stream))
- error("Attempted to decompress a resource that was not MadsPacked");
-
- stream->seek(14);
- _count = stream->readUint16LE();
- _items = new MadsPackEntry[_count];
-
- byte *headerData = new byte[0xA0];
- byte *header = headerData;
- stream->read(headerData, 0xA0);
-
- for (int i = 0; i < _count; ++i, header += 10) {
- // Get header data
- _items[i].hash = READ_LE_UINT16(header);
- _items[i].size = READ_LE_UINT32(header + 2);
- _items[i].compressedSize = READ_LE_UINT32(header + 6);
-
- _items[i].data = new byte[_items[i].size];
- if (_items[i].size == _items[i].compressedSize) {
- // Entry isn't compressed
- stream->read(_items[i].data, _items[i].size);
- } else {
- // Decompress the entry
- byte *compressedData = new byte[_items[i].compressedSize];
- stream->read(compressedData, _items[i].compressedSize);
-
- FabDecompressor fab;
- fab.decompress(compressedData, _items[i].compressedSize, _items[i].data, _items[i].size);
- delete[] compressedData;
- }
- }
-
- delete[] headerData;
- _dataOffset = stream->pos();
-}
-
-Common::SeekableReadStream *MadsPack::getItemStream(int index) {
- return new Common::MemoryReadStream(_items[index].data, _items[index].size, DisposeAfterUse::NO);
-}
-
-MadsPack::~MadsPack() {
- for (int i = 0; i < _count; ++i)
- delete[] _items[i].data;
- delete[] _items;
-}
-
-//--------------------------------------------------------------------------
-
-void FabDecompressor::decompress(const byte *srcData, int srcSize, byte *destData, int destSize) {
- byte copyLen, copyOfsShift, copyOfsMask, copyLenMask;
- unsigned long copyOfs;
- byte *destP;
-
- // Validate that the data starts with the FAB header
- if (strncmp((const char *)srcData, "FAB", 3) != 0)
- error("FabDecompressor - Invalid compressed data");
-
- int shiftVal = srcData[3];
- if ((shiftVal < 10) || (shiftVal > 13))
- error("FabDecompressor - Invalid shift start");
-
- copyOfsShift = 16 - shiftVal;
- copyOfsMask = 0xFF << (shiftVal - 8);
- copyLenMask = (1 << copyOfsShift) - 1;
- copyOfs = 0xFFFF0000;
- destP = destData;
-
- // Initialize data fields
- _srcData = srcData;
- _srcP = _srcData + 6;
- _srcSize = srcSize;
- _bitsLeft = 16;
- _bitBuffer = READ_LE_UINT16(srcData + 4);
-
- for (;;) {
- if (getBit() == 0) {
- if (getBit() == 0) {
- copyLen = ((getBit() << 1) | getBit()) + 2;
- copyOfs = *_srcP++ | 0xFFFFFF00;
- } else {
- copyOfs = (((_srcP[1] >> copyOfsShift) | copyOfsMask) << 8) | _srcP[0];
- copyLen = _srcP[1] & copyLenMask;
- _srcP += 2;
- if (copyLen == 0) {
- copyLen = *_srcP++;
- if (copyLen == 0)
- break;
- else if (copyLen == 1)
- continue;
- else
- copyLen++;
- } else {
- copyLen += 2;
- }
- copyOfs |= 0xFFFF0000;
- }
- while (copyLen-- > 0) {
- if (destP - destData == destSize)
- error("FabDecompressor - Decompressed data exceeded specified size");
-
- *destP = destP[(signed int)copyOfs];
- destP++;
- }
- } else {
- if (_srcP - srcData == srcSize)
- error("FabDecompressor - Passed end of input buffer during decompression");
- if (destP - destData == destSize)
- error("FabDecompressor - Decompressed data exceeded specified size");
-
- *destP++ = *_srcP++;
- }
- }
-
- if (destP - destData != destSize)
- error("FabDecompressor - Decompressed data does not match header decompressed size");
-}
-
-int FabDecompressor::getBit() {
- _bitsLeft--;
- if (_bitsLeft == 0) {
- if (_srcP - _srcData == _srcSize)
- error("FabDecompressor - Passed end of input buffer during decompression");
-
- _bitBuffer = (READ_LE_UINT16(_srcP) << 1) | (_bitBuffer & 1);
- _srcP += 2;
- _bitsLeft = 16;
- }
-
- int bit = _bitBuffer & 1;
- _bitBuffer >>= 1;
- return bit;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/compression.h b/engines/m4/compression.h
deleted file mode 100644
index cb0ef74eb7..0000000000
--- a/engines/m4/compression.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_COMPRESSION_H
-#define M4_COMPRESSION_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-#include "common/endian.h"
-
-#include "m4/m4.h"
-
-namespace M4 {
-
-struct MadsPackEntry {
-public:
- uint16 hash;
- uint32 size;
- uint32 compressedSize;
- byte *data;
-};
-
-class MadsPack {
-private:
- MadsPackEntry *_items;
- int _count;
- int _dataOffset;
-
- void initialize(Common::SeekableReadStream *stream);
-public:
- static bool isCompressed(Common::SeekableReadStream *stream);
- MadsPack(Common::SeekableReadStream *stream);
- MadsPack(const char *resourceName, MadsM4Engine *vm);
- ~MadsPack();
-
- int getCount() const { return _count; }
- MadsPackEntry &getItem(int index) const { return _items[index]; }
- MadsPackEntry &operator[](int index) const { return _items[index]; }
- Common::SeekableReadStream *getItemStream(int index);
- int getDataOffset() const { return _dataOffset; }
-};
-
-class FabDecompressor {
-private:
- int _bitsLeft;
- uint32 _bitBuffer;
- const byte *_srcData, *_srcP;
- int _srcSize;
-
- int getBit();
-public:
- void decompress(const byte *srcData, int srcSize, byte *destData, int destSize);
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/console.cpp b/engines/m4/console.cpp
deleted file mode 100644
index fa4ca6d121..0000000000
--- a/engines/m4/console.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/console.h"
-#include "m4/dialogs.h"
-#include "m4/scene.h"
-#include "m4/staticres.h"
-
-namespace M4 {
-
-Console::Console(MadsM4Engine *vm) : GUI::Debugger() {
- _vm = vm;
-
- DCmd_Register("scene", WRAP_METHOD(Console, cmdLoadScene));
- DCmd_Register("start", WRAP_METHOD(Console, cmdStartingScene));
- DCmd_Register("show_hotspots", WRAP_METHOD(Console, cmdShowHotSpots));
- DCmd_Register("list_hotspots", WRAP_METHOD(Console, cmdListHotSpots));
- DCmd_Register("play_sound", WRAP_METHOD(Console, cmdPlaySound));
- DCmd_Register("play_dsr_sound", WRAP_METHOD(Console, cmdPlayDSRSound));
- DCmd_Register("show_resources", WRAP_METHOD(Console, cmdShowResources));
- DCmd_Register("show_codes", WRAP_METHOD(Console, cmdShowCodes));
- DCmd_Register("dump_file", WRAP_METHOD(Console, cmdDumpFile));
- DCmd_Register("sprite", WRAP_METHOD(Console, cmdShowSprite));
- DCmd_Register("start_conv", WRAP_METHOD(Console, cmdStartConversation));
- DCmd_Register("textview", WRAP_METHOD(Console, cmdShowTextview));
- DCmd_Register("animview", WRAP_METHOD(Console, cmdShowAnimview));
-}
-
-Console::~Console() {
-}
-
-static int strToInt(const char *s) {
- if (!*s)
- // No string at all
- return 0;
- else if (toupper(s[strlen(s) - 1]) != 'H')
- // Standard decimal string
- return atoi(s);
-
- // Hexadecimal string
- uint tmp = 0;
- int read = sscanf(s, "%xh", &tmp);
- if (read < 1)
- error("strToInt failed on string \"%s\"", s);
- return (int)tmp;
-}
-
-bool Console::cmdLoadScene(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <scene number>\n", argv[0]);
- return true;
- } else {
- if (_vm->isM4())
- _vm->_kernel->newRoom = atoi(argv[1]);
- else
- _vm->_scene->loadScene(atoi(argv[1]));
- return false;
- }
-}
-
-bool Console::cmdStartingScene(int argc, const char **argv) {
- if (_vm->getGameType() != GType_Riddle) {
- if (_vm->isM4())
- _vm->_kernel->newRoom = FIRST_SCENE;
- else
- _vm->_scene->loadScene(FIRST_SCENE);
- return false;
- } else {
- DebugPrintf("%s: Riddle of Master Lu is not supported", argv[0]);
- return true;
- }
-}
-
-bool Console::cmdShowHotSpots(int argc, const char **argv) {
- _vm->_scene->showHotSpots();
- return false;
-}
-
-bool Console::cmdListHotSpots(int argc, const char **argv) {
- DebugPrintf("Scene hotspots\n");
- _vm->_scene->getSceneResources().hotspots->dump();
- if (_vm->isM4()) {
- DebugPrintf("Scene parallax\n");
- _m4Vm->scene()->getSceneResources().parallax->dump();
- DebugPrintf("Scene dynamic hotspots\n");
- _vm->_scene->getSceneResources().dynamicHotspots->dump();
- }
- return true;
-}
-
-bool Console::cmdPlaySound(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <sound file>\n", argv[0]);
- } else {
- _vm->_sound->playSound(argv[1], 255, false);
- }
- return true;
-}
-
-bool Console::cmdPlayDSRSound(int argc, const char **argv) {
- if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: %s <sound index> <DSR file>\n", argv[0]);
- DebugPrintf("The DSR file parameter is optional, and specifies which DSR to load\n");
- } else {
- if (argc == 3)
- _vm->_sound->loadDSRFile(argv[2]);
- _vm->_sound->playDSRSound(atoi(argv[1]), 255, false);
- }
- return true;
-}
-
-bool Console::cmdShowResources(int argc, const char **argv) {
- _vm->res()->dump();
- return true;
-}
-
-bool Console::cmdShowCodes(int argc, const char **argv) {
- _vm->_scene->showCodes();
- return false;
-}
-
-bool Console::cmdDumpFile(int argc, const char **argv) {
- if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: %s <file> <uncompress>\n", argv[0]);
- DebugPrintf("If uncompress is 1, the file is uncompressed (for MADS games)\n");
- } else {
- if (argc == 2) {
- _vm->dumpFile(argv[1], false);
- } else {
- if (argc == 3 && atoi(argv[2]) == 1)
- _vm->dumpFile(argv[1], true);
- else
- _vm->dumpFile(argv[1], false);
- }
- }
- return true;
-}
-
-bool Console::cmdShowSprite(int argc, const char **argv) {
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view == NULL)
- DebugPrintf("The scene view isn't currently active\n");
- else if (argc < 2)
- DebugPrintf("Usage: %s resource_name\n", argv[0]);
- else {
- char resourceName[20];
- strncpy(resourceName, argv[1], 15);
- resourceName[15] = '\0';
- if (!strchr(resourceName, '.'))
- strcat(resourceName, ".SS");
-
- _vm->_viewManager->moveToFront(view);
- Common::SeekableReadStream *data = _vm->res()->get(resourceName);
- SpriteAsset *asset = new SpriteAsset(_vm, data, data->size(), resourceName);
- _vm->res()->toss(resourceName);
-
- RGBList *palData = new RGBList(asset->getColorCount(), asset->getPalette(), true);
- _vm->_palette->addRange(palData);
-
- // Get the scene background surface
- M4Surface *bg = _vm->_scene->getBackgroundSurface();
-
- // Write the sprite onto the screen
- int x = 0, y = 0, yMax = 0;
- for (int index = 0; index < asset->getCount(); index++) {
- M4Sprite *spr = asset->getFrame(index);
- spr->translate(palData); // sprite pixel translation
-
- if ((x + spr->width() >= bg->width()) && (yMax != 0)) {
- x = 0;
- y += yMax;
- yMax = 0;
- }
-
- if (y >= bg->height())
- break;
-
- spr->copyTo(bg, x, y, (int)spr->getTransparencyIndex());
-
- x += spr->width();
- yMax = MAX(yMax, spr->height());
- }
-
- view->restore(0, 0, view->width(), view->height());
- return false;
- }
-
- return true;
-}
-
-bool Console::cmdStartConversation(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <conversation file name>\n", argv[0]);
- return true;
- } else if (_vm->isM4()) {
- ((M4Engine *)_vm)->_converse->startConversation(argv[1]);
- return false;
- } else {
- error("MADS engine does not support conversations yet");
- return false;
- }
-}
-
-bool Console::cmdShowTextview(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <txr resource>\n", argv[0]);
- return true;
- }
-
- _vm->_viewManager->showTextView(argv[1], false);
- return false;
-}
-
-bool Console::cmdShowAnimview(int argc, const char **argv) {
- if (argc != 2) {
- DebugPrintf("Usage: %s <res resource>\n", argv[0]);
- return true;
- }
-
- char resName[80];
- strcpy(resName, "@");
- strcat(resName, *argv[1] == '@' ? argv[1] + 1 : argv[1]);
-
- _vm->_viewManager->showAnimView(resName, false);
- return false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsConsole::MadsConsole(MadsEngine *vm): Console(vm) {
- _vm = vm;
-
- DCmd_Register("object", WRAP_METHOD(MadsConsole, cmdObject));
- DCmd_Register("message", WRAP_METHOD(MadsConsole, cmdMessage));
- DCmd_Register("scene_info", WRAP_METHOD(MadsConsole, cmdSceneInfo));
- DCmd_Register("anim", WRAP_METHOD(MadsConsole, cmdPlayAnimation));
-}
-
-bool MadsConsole::cmdObject(int argc, const char **argv) {
- if (argc == 1) {
- DebugPrintf("Usage: object ['list' | '#objnum' | 'add #objnum']\n");
- } else if (!strcmp(argv[1], "list")) {
- // List of objects
- for (uint objStart = 0; objStart < _vm->globals()->getObjectsSize(); objStart += 5) {
- DebugPrintf("%2d - ", objStart);
- for (uint objId = objStart; objId < MIN<uint>(_vm->globals()->getObjectsSize(), objStart + 5); ++objId) {
- if (objId != objStart) DebugPrintf(", ");
- uint16 descId = _vm->globals()->getObject(objId)->_descId;
- DebugPrintf("%s", _vm->globals()->getVocab(descId));
- }
-
- DebugPrintf("\n");
- }
-
- DebugPrintf("\n");
- } else if (!strcmp(argv[1], "add") && (argc == 3)) {
- // Add the specified object to the player's inventory
- int objNum = strToInt(argv[2]);
-
- if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize()))
- DebugPrintf("Invalid object specified\n");
- else if (_vm->isM4())
- DebugPrintf("Not implemented for M4 games\n");
- else {
- _vm->_scene->getInterface()->addObjectToInventory(objNum);
- return false;
- }
-
- } else {
- // Print the details of a specific object
- int objNum = strToInt(argv[1]);
-
- if ((objNum < 0) || (objNum >= (int)_vm->globals()->getObjectsSize()))
- DebugPrintf("Invalid object specified\n");
- else {
- const MadsObject *obj = _vm->globals()->getObject(objNum);
-
- DebugPrintf("Object #%d (%s) room=%d article=%d/%s vocabs=%d", objNum, _vm->globals()->getVocab(obj->_descId),
- obj->_roomNumber, (int)obj->_article, englishMADSArticleList[obj->_article], obj->_vocabCount);
-
- if (obj->_vocabCount > 0) {
- DebugPrintf(" - ");
- for (int i = 0; i < obj->_vocabCount; ++i) {
- if (i != 0) DebugPrintf(", ");
- DebugPrintf("%s (%d)/%d,%d", _vm->globals()->getVocab(obj->_vocabList[i].vocabId),
- obj->_vocabList[i].vocabId, obj->_vocabList[i].flags1, obj->_vocabList[i].flags2);
- }
- }
- DebugPrintf("\n");
- }
- }
-
- return true;
-}
-
-bool MadsConsole::cmdMessage(int argc, const char **argv) {
- if (argc == 1) {
- DebugPrintf("message 'objnum'\n");
- } else if (!strcmp(argv[1], "list_quotes")) {
- // Dump the quotes list
-#if 0
- // FIXME: The following code is not portable and hence has been disabled.
- // Try replacing FILE by Common::DumpFile.
- FILE *destFile = fopen("mads_quotes.txt", "wb");
- for (uint i = 0; i < _vm->globals()->getQuotesSize(); ++i)
- fprintf(destFile, "%.3d - %s\n", i, _vm->globals()->getQuote(i));
- fclose(destFile);
-#endif
-
- } else if (!strcmp(argv[1], "list_vocab")) {
- // Dump the vocab list
-#if 0
- // FIXME: The following code is not portable and hence has been disabled.
- // Try replacing FILE by Common::DumpFile.
- FILE *destFile = fopen("mads_vocab.txt", "wb");
- for (uint i = 1; i <= _vm->globals()->getVocabSize(); ++i)
- fprintf(destFile, "%.3d/%.3x - %s\n", i, i, _vm->globals()->getVocab(i));
- fclose(destFile);
-#endif
-
- } else {
- int messageIdx = strToInt(argv[1]);
-
- if ((argc != 3) || (strcmp(argv[2], "idx") != 0))
- messageIdx = _vm->globals()->messageIndexOf(messageIdx);
-
- const char *msg = _vm->globals()->loadMessage(messageIdx);
- if (!msg)
- DebugPrintf("Unknown message\n");
- else {
- Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
-
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
-
- return false;
- }
- }
-
- return true;
-}
-
-bool MadsConsole::cmdSceneInfo(int argc, const char **argv) {
- DebugPrintf("Current scene is: %i\n", _vm->_scene->getCurrentScene());
-
- return true;
-}
-
-bool MadsConsole::cmdPlayAnimation(int argc, const char **argv) {
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view == NULL) {
- DebugPrintf("The scene view isn't currently active\n");
- } else if (argc != 2 && argc != 3) {
- DebugPrintf("Usage: %s <anim resource (*.aa)> <fullscreen>\n", argv[0]);
- DebugPrintf("If fullscreen is 1, the screen palette is replaced with the palette of the animation\n");
- } else {
- char resourceName[20];
- strncpy(resourceName, argv[1], 15);
- resourceName[15] = '\0';
- if (!strchr(resourceName, '.'))
- strcat(resourceName, ".AA");
-
- _vm->_viewManager->moveToFront(view);
- if (argc == 3 && atoi(argv[2]) == 1)
- _madsVm->_palette->deleteAllRanges();
-
- _madsVm->scene()->_sceneAnimation->load(resourceName, 0);
-
- view->restore(0, 0, view->width(), view->height());
- return false;
- }
-
- return true;
-}
-
-/*--------------------------------------------------------------------------*/
-
-M4Console::M4Console(M4Engine *vm): Console(vm) {
- _vm = vm;
-
- DCmd_Register("scene_info", WRAP_METHOD(M4Console, cmdSceneInfo));
-}
-
-bool M4Console::cmdSceneInfo(int argc, const char **argv) {
- DebugPrintf("Current scene is: %i\n", _m4Vm->scene()->getCurrentScene());
-
- DebugPrintf("Scene resources:\n");
- DebugPrintf("artBase: %s\n", _m4Vm->scene()->getSceneResources().artBase);
- DebugPrintf("pictureBase: %s\n", _m4Vm->scene()->getSceneResources().pictureBase);
- DebugPrintf("hotspotCount: %i\n", _m4Vm->scene()->getSceneResources().hotspots->size());
- DebugPrintf("parallaxCount: %i\n", _m4Vm->scene()->getSceneResources().parallaxCount);
- DebugPrintf("dynHotspotCount: %i\n", _m4Vm->scene()->getSceneResources().dynamicHotspots->size());
- DebugPrintf("frontY: %i\n", _m4Vm->scene()->getSceneResources().frontY);
- DebugPrintf("backY: %i\n", _m4Vm->scene()->getSceneResources().backY);
- DebugPrintf("frontScale: %i\n", _m4Vm->scene()->getSceneResources().frontScale);
- DebugPrintf("backScale: %i\n", _m4Vm->scene()->getSceneResources().backScale);
- DebugPrintf("depthTable: ");
- for (uint i = 0; i < 16; i++)
- DebugPrintf("%i ", _m4Vm->scene()->getSceneResources().depthTable[i]);
- DebugPrintf("\n");
- DebugPrintf("railNodeCount: %i\n", _m4Vm->scene()->getSceneResources().railNodeCount);
-
- return true;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/console.h b/engines/m4/console.h
deleted file mode 100644
index fc473b6464..0000000000
--- a/engines/m4/console.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_CONSOLE_H
-#define M4_CONSOLE_H
-
-#include "gui/debugger.h"
-
-namespace M4 {
-
-class MadsM4Engine;
-class MadsEngine;
-
-class Console : public GUI::Debugger {
-private:
- MadsM4Engine *_vm;
-
- bool cmdLoadScene(int argc, const char **argv);
- bool cmdStartingScene(int argc, const char **argv);
- bool cmdShowHotSpots(int argc, const char **argv);
- bool cmdListHotSpots(int argc, const char **argv);
- bool cmdPlaySound(int argc, const char **argv);
- bool cmdPlayDSRSound(int argc, const char **argv);
- bool cmdShowResources(int argc, const char **argv);
- bool cmdShowCodes(int argc, const char **argv);
- bool cmdDumpFile(int argc, const char **argv);
- bool cmdShowSprite(int argc, const char **argv);
- bool cmdStartConversation(int argc, const char **argv);
- bool cmdShowTextview(int argc, const char **argv);
- bool cmdShowAnimview(int argc, const char **argv);
-
-public:
- Console(MadsM4Engine *vm);
- virtual ~Console();
-};
-
-class MadsConsole : public Console {
-private:
- MadsEngine *_vm;
-
- bool cmdObject(int argc, const char **argv);
- bool cmdMessage(int argc, const char **argv);
- bool cmdSceneInfo(int argc, const char **argv);
- bool cmdPlayAnimation(int argc, const char **argv);
-
-public:
- MadsConsole(MadsEngine *vm);
- virtual ~MadsConsole() {}
-};
-
-class M4Console : public Console {
-private:
- M4Engine *_vm;
-
- bool cmdSceneInfo(int argc, const char **argv);
-public:
- M4Console(M4Engine *vm);
- virtual ~M4Console() {}
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/converse.cpp b/engines/m4/converse.cpp
deleted file mode 100644
index 299fafb282..0000000000
--- a/engines/m4/converse.cpp
+++ /dev/null
@@ -1,1239 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/array.h"
-#include "common/hashmap.h"
-#include "common/substream.h"
-#include "common/textconsole.h"
-
-#include "m4/converse.h"
-#include "m4/resource.h"
-#include "m4/globals.h"
-#include "m4/m4_views.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-#define CONV_ENTRIES_X_OFFSET 20
-#define CONV_ENTRIES_Y_OFFSET 4
-#define CONV_ENTRIES_HEIGHT 20
-#define CONV_MAX_SHOWN_ENTRIES 5
-
-#define CONVERSATION_ENTRY_HIGHLIGHTED 22
-#define CONVERSATION_ENTRY_NORMAL 3
-
-// Conversation chunks
-// Header
-#define HEAD_CONV MKTAG('C','O','N','V') // conversation
-#define CHUNK_DECL MKTAG('D','E','C','L') // declaration
-#define CHUNK_NODE MKTAG('N','O','D','E') // node
-#define CHUNK_LNOD MKTAG('L','N','O','D') // linear node
-#define CHUNK_ETRY MKTAG('E','T','R','Y') // entry
-#define CHUNK_TEXT MKTAG('T','E','X','T') // text
-#define CHUNK_MESG MKTAG('M','E','S','G') // message
-// Conversation chunks - entry related (unconditional)
-#define CHUNK_RPLY MKTAG('R','P','L','Y') // reply
-#define CHUNK_HIDE MKTAG('H','I','D','E') // hide entry
-#define CHUNK_UHID MKTAG('U','H','I','D') // unhide entry
-#define CHUNK_DSTR MKTAG('D','S','T','R') // destroy entry
-// Conversation chunks - entry related (conditional)
-#define CHUNK_CRPL MKTAG('C','R','P','L') // reply
-#define CHUNK_CHDE MKTAG('C','H','D','E') // hide entry
-#define CHUNK_CUHD MKTAG('C','U','H','D') // unhide entry
-#define CHUNK_CDST MKTAG('D','D','T','S') // destroy entry
-// Conversation chunks - branching and logic (unconditional)
-#define CHUNK_ASGN MKTAG('A','S','G','N') // assign
-#define CHUNK_GOTO MKTAG('G','O','T','O') // goto chunk
-#define CHUNK_EXIT MKTAG('E','X','I','T') // exit/return from goto
-// Conversation chunks - branching and logic (conditional)
-#define CHUNK_CASN MKTAG('C','A','S','N') // assign
-#define CHUNK_CCGO MKTAG('C','C','G','O') // goto chunk
-#define CHUNK_CEGO MKTAG('C','E','G','O') // exit/return from goto
-// Others
-#define CHUNK_FALL MKTAG('F','A','L','L') // fallthrough
-#define CHUNK_WRPL MKTAG('W','R','P','L') // weighted reply chunk
-#define CHUNK_WPRL MKTAG('W','P','R','L') // weighted preply chunk
-
-
-ConversationView::ConversationView(MadsM4Engine *vm): View(vm, Common::Rect(0,
- vm->_screen->height() - INTERFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())) {
-
- _screenType = VIEWID_CONVERSATION;
- _screenFlags.layer = LAYER_INTERFACE;
- _screenFlags.visible = false;
- _screenFlags.get = SCREVENT_MOUSE;
- _conversationState = kNoConversation;
- _currentHandle = NULL;
-}
-
-ConversationView::~ConversationView() {
- _activeItems.clear();
-}
-
-void ConversationView::setNode(int32 nodeIndex) {
- _highlightedIndex = -1;
- _xEnd = CONV_ENTRIES_X_OFFSET;
- _vm->_font->setFont(FONT_CONVERSATION);
-
- // TODO: Conversation styles and colors
- _vm->_font->current()->setColors(2, 1, 3);
-
- _currentNodeIndex = nodeIndex;
-
- _activeItems.clear();
-
- if (nodeIndex != -1) {
- ConvEntry *node = _m4Vm->_converse->getNode(nodeIndex);
-
- for (uint i = 0; i < node->entries.size(); ++i) {
- if (!node->entries[i]->visible)
- continue;
-
- if ((int)_activeItems.size() > CONV_MAX_SHOWN_ENTRIES) {
- warning("TODO: scrolling. Max shown entries are %i, skipping entry %i",
- CONV_MAX_SHOWN_ENTRIES, i);
- }
-
- // Add node to active items list
- _activeItems.push_back(node->entries[i]);
-
- if (node->entries[i]->autoSelect || node->entries[i]->text[0] == '\0') {
- //warning(kDebugConversations, "Auto selecting entry %i of node %i\n", i, nodeIndex);
- selectEntry(i);
- return;
- }
-
- // Figure out the longest string to determine where option highlighting ends
- int tempX = _vm->_font->current()->getWidth(node->entries[i]->text, 0) +
- CONV_ENTRIES_X_OFFSET + 10;
- _xEnd = MAX(_xEnd, tempX);
- }
-
- // Make sure that there aren't too many entries
- //assert((int)_activeItems.size() < (height() - CONV_ENTRIES_Y_OFFSET) / CONV_ENTRIES_HEIGHT);
-
- // Fallthrough
- if (node->fallthroughMinEntries >= 0 && node->fallthroughOffset >= 0) {
- //warning(kDebugConversations, "Current node falls through node at offset %i when entries are less or equal than %i\n",
- // node->fallthroughOffset, node->fallthroughMinEntries);
- if (_activeItems.size() <= (uint32)node->fallthroughMinEntries) {
- const EntryInfo *entryInfo = _m4Vm->_converse->getEntryInfo(node->fallthroughOffset);
- //warning(kDebugConversations, "Entries are less than or equal to %i, falling through to node at offset %i, index %i\n",
- // node->fallthroughMinEntries, node->fallthroughOffset, entryInfo->nodeIndex);
- setNode(entryInfo->nodeIndex);
- return;
- }
- }
-
- _entriesShown = true;
- _conversationState = kConversationOptionsShown;
- }
-}
-
-void ConversationView::onRefresh(RectList *rects, M4Surface *destSurface) {
- //if (!this->isVisible())
- // return;
- clear();
-
- if (_entriesShown) {
- // Write out the conversation options
- _vm->_font->setFont(FONT_CONVERSATION);
- for (int i = 0; i < (int)_activeItems.size(); ++i) {
- // TODO: scrolling
- if (i > CONV_MAX_SHOWN_ENTRIES - 1)
- break;
-
- _vm->_font->current()->setColor((_highlightedIndex == i) ? CONVERSATION_ENTRY_HIGHLIGHTED :
- CONVERSATION_ENTRY_NORMAL);
-
- _vm->_font->current()->writeString(this, _activeItems[i]->text, CONV_ENTRIES_X_OFFSET,
- CONV_ENTRIES_Y_OFFSET + CONV_ENTRIES_HEIGHT * i, 0, 0);
- }
- }
- View::onRefresh(rects, destSurface);
-}
-
-bool ConversationView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- //if (!this->isVisible())
- // return false;
- if (!_entriesShown)
- return false;
- if (eventType == KEVENT_KEY)
- return false;
-
- int localY = y - _coords.top;
- int selectedIndex = _highlightedIndex;
-
- switch (eventType) {
- case MEVENT_MOVE:
- if ((x < CONV_ENTRIES_X_OFFSET) || (x >= _xEnd) || (localY < CONV_ENTRIES_Y_OFFSET))
- _highlightedIndex = -1;
- else {
- int index = (localY - CONV_ENTRIES_Y_OFFSET) / CONV_ENTRIES_HEIGHT;
- _highlightedIndex = (index >= (int)_activeItems.size()) ? -1 : index;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- if (_highlightedIndex != -1) {
- selectEntry(selectedIndex);
- }
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-void ConversationView::selectEntry(int entryIndex) {
- char buffer[20];
- sprintf(buffer, "%s.raw", _activeItems[entryIndex]->voiceFile);
-
- _entriesShown = false;
- _conversationState = kEntryIsActive;
- _vm->_player->setCommandsAllowed(false);
- // Necessary, as entries can be selected programmatically
- _highlightedIndex = entryIndex;
-
- // Play the selected entry's voice
- if (_activeItems[entryIndex]->voiceFile[0] != '\0') {
- _currentHandle = _vm->_sound->getHandle();
- _vm->_sound->playVoice(buffer, 255);
- } else {
- _currentHandle = NULL;
- }
-
- // Hide selected entry, unless it has a persistent flag set
- if (!(_activeItems[entryIndex]->flags & kEntryPersists)) {
- //debugCN(kDebugConversations, "Hiding selected entry\n");
- _m4Vm->_converse->getNode(_currentNodeIndex)->entries[entryIndex]->visible = false;
- } else {
- //debugCN(kDebugConversations, "Selected entry is persistent, not hiding it\n");
- }
-}
-
-void ConversationView::updateState() {
- switch (_conversationState) {
- case kConversationOptionsShown:
- return;
- case kEntryIsActive:
- case kReplyIsActive:
- // FIXME: for now, we determine whether a conversation entry is
- // finished by waiting for its associated speech file to finish playing
- if (_currentHandle != NULL && _vm->_sound->isHandleActive(_currentHandle)) {
- return;
- } else {
- playNextReply();
- } // end else
- break;
- case kNoConversation:
- return;
- default:
- error("Unknown converstation state");
- break;
- }
-}
-
-void ConversationView::playNextReply() {
- char buffer[20];
-
- assert(_highlightedIndex >= 0);
-
- // Start playing the first reply
- for (uint32 i = 0; i < _activeItems[_highlightedIndex]->entries.size(); i++) {
- ConvEntry *currentEntry = _activeItems[_highlightedIndex]->entries[i];
-
- if (currentEntry->isConditional) {
- if (!_m4Vm->_converse->evaluateCondition(
- _m4Vm->_converse->getValue(currentEntry->condition.offset),
- currentEntry->condition.op, currentEntry->condition.val))
- continue; // don't play this reply
- }
-
- if (currentEntry->entryType != kWeightedReply) {
- sprintf(buffer, "%s.raw", currentEntry->voiceFile);
- if (currentEntry->voiceFile[0] != '\0') {
- _currentHandle = _vm->_sound->getHandle();
- _vm->_sound->playVoice(buffer, 255);
- // Remove reply from the list of replies
- _activeItems[_highlightedIndex]->entries.remove_at(i);
- _conversationState = kReplyIsActive;
- return;
- } else {
- _currentHandle = NULL;
- }
- } else {
- int selectedWeight = _vm->_random->getRandomNumber(currentEntry->totalWeight - 1) + 1;
- //debugCN(kDebugConversations, "Selected weight: %i\n", selectedWeight);
- int previousWeight = 1;
- int currentWeight = 0;
-
- for (uint32 j = 0; j < currentEntry->entries.size(); j++) {
- currentWeight += currentEntry->entries[j]->weight;
- if (selectedWeight >= previousWeight && selectedWeight <= currentWeight) {
- sprintf(buffer, "%s.raw", currentEntry->entries[j]->voiceFile);
- if (currentEntry->entries[j]->voiceFile[0] != '\0') {
- _currentHandle = _vm->_sound->getHandle();
- _vm->_sound->playVoice(buffer, 255);
- // Remove reply from the list of replies
- _activeItems[_highlightedIndex]->entries.remove_at(i);
- _conversationState = kReplyIsActive;
- return;
- } else {
- _currentHandle = NULL;
- }
- break;
- }
- previousWeight += currentWeight;
- } // end for j
- } // end if
- } // end for i
-
- // If we reached here, there are no more replies, so perform the active entry's actions
-
- //debugCN(kDebugConversations, "Current selection does %i actions\n", _activeItems[entryIndex]->actions.size());
- for (uint32 i = 0; i < _activeItems[_highlightedIndex]->actions.size(); i++) {
- if (!_m4Vm->_converse->performAction(_activeItems[_highlightedIndex]->actions[i]))
- break;
- } // end for
-
- // Refresh the conversation node, in case it hasn't changed
- setNode(_currentNodeIndex);
-
- _entriesShown = true;
- _vm->_player->setCommandsAllowed(true);
-
- // Check if the conversation has been ended
- if (_currentNodeIndex == -1) {
- _conversationState = kNoConversation;
- }
-}
-
-//--------------------------------------------------------------------------
-
-void Converse::startConversation(const char *convName, bool showConverseBox, ConverseStyle style) {
- if (_vm->isM4())
- loadConversation(convName);
- else
- loadConversationMads(convName);
-
- if (!_vm->isM4()) showConverseBox = false; // TODO: remove
-
- _playerCommandsAllowed = _vm->_player->commandsAllowed;
- if (_vm->isM4()) // TODO: remove (interface not implemented yet in MADS games)
- _interfaceWasVisible = _m4Vm->scene()->getInterface()->isVisible();
- _vm->_player->setCommandsAllowed(false);
- _style = style;
-
- if (showConverseBox) {
- _vm->_conversationView->show();
- _vm->_mouse->lockCursor(CURSOR_ARROW);
-
- if (_interfaceWasVisible)
- _m4Vm->scene()->getInterface()->hide();
-
- _vm->_conversationView->setNode(0);
- _vm->_conversationView->show();
- }
-}
-
-void Converse::endConversation() {
- _vm->_conversationView->setNode(-1);
- _vm->_conversationView->hide();
- // TODO: do a more proper cleanup here
- _convNodes.clear();
- _variables.clear();
- _offsetMap.clear();
- _vm->_player->setCommandsAllowed(_playerCommandsAllowed);
- if (_interfaceWasVisible)
- _m4Vm->scene()->getInterface()->show();
-}
-
-void Converse::loadConversation(const char *convName) {
- char name[40];
- char buffer[256];
- sprintf(name, "%s.chk", convName);
- Common::SeekableReadStream *convS = _vm->res()->get(name);
- uint32 header = convS->readUint32LE();
- uint32 size;
- uint32 chunk;
- uint32 data = 0;
- uint32 i = 0;
- ConvEntry* curEntry = NULL;
- ConvEntry* replyEntry = NULL;
- int32 currentWeightedEntry = -1;
- EntryAction* curAction = NULL;
- uint32 curNode = 0;
- uint32 chunkPos = 0;
- uint32 val;
- int32 autoSelectIndex = -1;
- int returnAddress = -1;
-
- bool debugFlag = false; // set to true for debug messages
-
- // Conversation *.chk files contain a 'CONV' header in LE format
- if (header != HEAD_CONV) {
- warning("Unexpected conversation file external header");
- return;
- }
- size = convS->readUint32LE(); // is this used at all?
- if (debugFlag) debugCN(kDebugConversations, "Conv chunk size (external header): %i\n", size);
-
- // Conversation name, which is the conversation file's name
- // without the extension
- convS->read(buffer, 8);
- if (debugFlag) debugCN(kDebugConversations, "Conversation name: %s\n", buffer);
-
- while (true) {
- chunkPos = convS->pos();
- chunk = convS->readUint32LE(); // read chunk
- if (convS->eos()) break;
-
- if (debugFlag) debugC(kDebugConversations, "***** Pos: %i -> ", chunkPos);
- switch (chunk) {
- case CHUNK_DECL: // Declare
- if (debugFlag) debugCN(kDebugConversations, "DECL chunk\n");
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Tag: %i\n", data);
- if (data > 0)
- warning("Tag > 0 in DECL chunk, value is: %i", data); // TODO
- val = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Value: %i\n", val);
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Flags: %i\n", data);
- if (data > 0)
- warning("Flags != 0 in DECL chunk, value is %i", data); // TODO
- setValue(chunkPos, val);
- break;
- // ----------------------------------------------------------------------------
- case CHUNK_NODE: // Node
- case CHUNK_LNOD: // Linear node
- // Create new node
- curEntry = new ConvEntry();
- curEntry->offset = chunkPos;
- curEntry->entryType = (chunk == CHUNK_NODE) ? kNode : kLinearNode;
- curEntry->fallthroughMinEntries = -1;
- curEntry->fallthroughOffset = -1;
- if (chunk == CHUNK_NODE) {
- if (debugFlag) debugCN(kDebugConversations, "NODE chunk\n");
- } else {
- if (debugFlag) debugCN(kDebugConversations, "LNOD chunk\n");
- }
- curNode = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Node number: %i\n", curNode);
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Tag: %i\n", data);
- if (chunk == CHUNK_LNOD) {
- autoSelectIndex = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Autoselect entry number: %i\n", autoSelectIndex);
- }
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Number of entries: %i\n", size);
- for (i = 0; i < size; i++) {
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Entry %i: %i\n", i + 1, data);
- }
- _convNodes.push_back(curEntry);
- setEntryInfo(curEntry->offset, curEntry->entryType, curNode, -1);
- break;
- case CHUNK_ETRY: // Entry
- // Create new entry
- curEntry = new ConvEntry();
- curEntry->offset = chunkPos;
- curEntry->entryType = kEntry;
- strcpy(curEntry->voiceFile, "");
- strcpy(curEntry->text, "");
- if (debugFlag) debugCN(kDebugConversations, "ETRY chunk\n");
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Unknown (attributes perhaps?): %i\n", data);
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Entry flags: ");
- if (debugFlag) if (data & kEntryInitial) debugCN(kDebugConversations, "Initial ");
- if (debugFlag) if (data & kEntryPersists) debugCN(kDebugConversations, "Persists ");
- if (debugFlag) debugCN(kDebugConversations, "\n");
- curEntry->flags = data;
- curEntry->visible = (curEntry->flags & kEntryInitial) ? true : false;
- if (autoSelectIndex >= 0) {
- if (_convNodes[curNode]->entries.size() == (uint32)autoSelectIndex) {
- curEntry->autoSelect = true;
- autoSelectIndex = -1;
- } else {
- curEntry->autoSelect = false;
- }
- } else {
- curEntry->autoSelect = false;
- }
- _convNodes[curNode]->entries.push_back(curEntry);
- setEntryInfo(curEntry->offset, curEntry->entryType,
- curNode, _convNodes[curNode]->entries.size() - 1);
- replyEntry = NULL;
- break;
- case CHUNK_WPRL: // Weighted preply
- // WPRL chunks are random entries that the character would say, not an NPC
- // They don't seem to be used in Orion Burger
- warning("WPRL chunk - treating as WRPL chunk");
- case CHUNK_WRPL: // Weighted reply
- case CHUNK_CRPL: // Conditional reply
- case CHUNK_RPLY: // Reply
- {
- ConvEntry* weightedEntry = NULL;
- // Create new reply
- replyEntry = new ConvEntry();
- replyEntry->offset = chunkPos;
- strcpy(replyEntry->voiceFile, "");
-
- // Conditional part
- if (chunk == CHUNK_CRPL) {
- replyEntry->isConditional = true;
- replyEntry->condition.offset = convS->readUint32LE();
- replyEntry->condition.op = convS->readUint32LE();
- replyEntry->condition.val = convS->readUint32LE();
- } else {
- replyEntry->isConditional = false;
- }
-
- if (chunk == CHUNK_WPRL || chunk == CHUNK_WRPL) {
- replyEntry->entryType = kWeightedReply;
- replyEntry->totalWeight = 0;
- if (debugFlag) debugCN(kDebugConversations, "WRPL chunk\n");
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Weighted reply %i - %i entries:\n", i, size);
- for (i = 0; i < size; i++) {
- weightedEntry = new ConvEntry();
- weightedEntry->offset = chunkPos;
- strcpy(weightedEntry->voiceFile, "");
- weightedEntry->entryType = kWeightedReply;
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "- Weight: %i ", data);
- weightedEntry->weight = data;
- replyEntry->totalWeight += weightedEntry->weight;
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "offset: %i\n", data);
- replyEntry->entries.push_back(weightedEntry);
- }
- currentWeightedEntry = 0;
- } else {
- replyEntry->entryType = kReply;
- if (debugFlag) debugCN(kDebugConversations, "RPLY chunk\n");
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Reply data offset: %i\n", data);
- }
-
- if (!curEntry)
- error("Converse::loadConversation(): curEntry is NULL while adding a reply");
-
- curEntry->entries.push_back(replyEntry);
- setEntryInfo(replyEntry->offset, replyEntry->entryType,
- curNode, _convNodes[curNode]->entries.size() - 1);
- // Seek to chunk data (i.e. TEXT/MESG tag, which is usually right
- // after this chunk but it can be further on in conditional reply chunks
- assert((int)data >= convS->pos());
- // If the entry's data is not right after the entry, remember the position
- // to return to after the data is read
- if (chunk == CHUNK_CRPL && (int)data != convS->pos())
- returnAddress = convS->pos();
- convS->seek(data, SEEK_SET);
- }
- break;
- // ----------------------------------------------------------------------------
- case CHUNK_TEXT: // Text (contains text and voice)
- case CHUNK_MESG: // Message (contains voice only)
- {
- ConvEntry* parentEntry = NULL;
- if (chunk == CHUNK_TEXT) {
- if (debugFlag) debugCN(kDebugConversations, "TEXT chunk\n");
- } else {
- if (debugFlag) debugCN(kDebugConversations, "MESG chunk\n");
- }
-
- if (replyEntry == NULL) {
- parentEntry = curEntry;
- } else if (replyEntry != NULL && replyEntry->entryType != kWeightedReply) {
- parentEntry = replyEntry;
- } else if (replyEntry != NULL && replyEntry->entryType == kWeightedReply) {
- parentEntry = replyEntry->entries[currentWeightedEntry];
- currentWeightedEntry++;
- } else {
- error("Converse::loadConversation(): Unexpected reply entry while processing TEXT/MESG chunk");
- }
-
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Entry data size: %i\n", size);
- convS->read(buffer, 8);
- size -= 8; // subtract maximum length of voice file name
- // If the file name is 8 characters, it will not be 0-terminated, so use strncpy
- strncpy(parentEntry->voiceFile, buffer, 8);
- parentEntry->voiceFile[8] = '\0';
- if (debugFlag) debugCN(kDebugConversations, "Voice file: %s\n", parentEntry->voiceFile);
-
- if (chunk == CHUNK_TEXT) {
- convS->read(buffer, size);
- if (debugFlag) debugCN(kDebugConversations, "Text: %s\n", buffer);
- sprintf(parentEntry->text, "%s", buffer);
- } else {
- while (size > 0) {
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Unknown: %i\n", data); // TODO
- size -= 4;
- }
- }
- // Now that the data chunk has been read, if we skipped a reply node,
- // jump back to it
- if (returnAddress != -1) {
- convS->seek(returnAddress, SEEK_SET);
- returnAddress = -1;
- }
- }
- break;
- // ----------------------------------------------------------------------------
- // Entry action chunks
- case CHUNK_CASN: // Conditional assign
- case CHUNK_ASGN: { // Assign
- curAction = new EntryAction();
- if (debugFlag) debugCN(kDebugConversations, "ASGN chunk\n");
- curAction->actionType = kAssignValue;
-
- // Conditional part
- if (chunk == CHUNK_CASN) {
- curAction->isConditional = true;
- curAction->condition.offset = convS->readUint32LE();
- curAction->condition.op = convS->readUint32LE();
- curAction->condition.val = convS->readUint32LE();
- } else {
- curAction->isConditional = false;
- }
-
- curAction->targetOffset = convS->readUint32LE();
- int op = convS->readUint32LE();
- assert(op == kOpAssign);
- curAction->value = convS->readUint32LE();
- break;
- }
- case CHUNK_CCGO: // Conditional go to entry
- case CHUNK_CHDE: // Conditional hide entry
- case CHUNK_CUHD: // Conditional unhide entry
- case CHUNK_CDST: // Conditional destroy entry
- case CHUNK_CEGO: // Conditional exit conversation / go to
-
- case CHUNK_GOTO: // Go to entry
- case CHUNK_HIDE: // Hide entry
- case CHUNK_UHID: // Unhide entry
- case CHUNK_DSTR: // Destroy entry
- case CHUNK_EXIT: // Exit conversation
- curAction = new EntryAction();
-
- // Conditional part
- if (chunk == CHUNK_CCGO || chunk == CHUNK_CHDE || chunk == CHUNK_CUHD ||
- chunk == CHUNK_CDST || chunk == CHUNK_CEGO) {
- curAction->isConditional = true;
- curAction->condition.offset = convS->readUint32LE();
- curAction->condition.op = convS->readUint32LE();
- curAction->condition.val = convS->readUint32LE();
- } else {
- curAction->isConditional = false;
- }
-
- if (chunk == CHUNK_GOTO || chunk == CHUNK_CCGO) {
- curAction->actionType = kGotoEntry;
- if (debugFlag) debugCN(kDebugConversations, "GOTO chunk\n");
- } else if (chunk == CHUNK_HIDE || chunk == CHUNK_CHDE) {
- curAction->actionType = kHideEntry;
- if (debugFlag) debugCN(kDebugConversations, "HIDE chunk\n");
- } else if (chunk == CHUNK_UHID || chunk == CHUNK_CUHD) {
- curAction->actionType = kUnhideEntry;
- if (debugFlag) debugCN(kDebugConversations, "UHID chunk\n");
- } else if (chunk == CHUNK_DSTR || chunk == CHUNK_CDST) {
- curAction->actionType = kDestroyEntry;
- if (debugFlag) debugCN(kDebugConversations, "DSTR chunk\n");
- } else if (chunk == CHUNK_EXIT || chunk == CHUNK_CEGO) {
- curAction->actionType = kExitConv;
- if (debugFlag) debugCN(kDebugConversations, "EXIT chunk\n");
- }
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Offset: %i\n", data);
- curAction->targetOffset = data;
- curEntry->actions.push_back(curAction);
- break;
- case CHUNK_FALL: // Fallthrough
- if (debugFlag) debugCN(kDebugConversations, "FALL chunk\n");
- size = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Minimum nodes: %i\n", size);
- _convNodes[curNode]->fallthroughMinEntries = size;
- data = convS->readUint32LE();
- if (debugFlag) debugCN(kDebugConversations, "Offset: %i\n", data);
- _convNodes[curNode]->fallthroughOffset = data;
- break;
- // ----------------------------------------------------------------------------
- default:
- // Should never happen
- error("Unknown conversation chunk");
- break;
- }
- }
-
- _vm->res()->toss(name);
-}
-
-void Converse::loadConversationMads(const char *convName) {
- char name[40];
- char buffer[256];
- char *buf;
- Common::SeekableReadStream *convS;
- int curPos = 0;
- int unk = 0;
- uint32 stringIndex = 0;
- uint32 stringCount = 0;
- int flags = 0;
- int count = 0;
- uint32 i, j;
- ConvEntry* curEntry = NULL;
- MessageEntry *curMessage;
- Common::Array<char *> messageList;
- // TODO
-
- // CND file
- sprintf(name, "%s.cnd", convName);
- MadsPack convDataD(name, _vm);
-
- // ------------------------------------------------------------
- // Chunk 0
- convS = convDataD.getItemStream(0);
- debugCN(kDebugConversations, "Chunk 0\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- // ------------------------------------------------------------
- // Chunk 1
- convS = convDataD.getItemStream(1);
- debugCN(kDebugConversations, "Chunk 1\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- // ------------------------------------------------------------
- // Chunk 2
- convS = convDataD.getItemStream(2);
- debugCN(kDebugConversations, "Chunk 2\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- // ------------------------------------------------------------
- // CNV file
- sprintf(name, "%s.cnv", convName);
- MadsPack convData(name, _vm);
- // *.cnv files have 7 chunks
- // Here is the chunk output of conv001.cnv (from the dump_file command)
- /*
- Dumping conv001.cnv, size: 3431
- Dumping compressed chunk 1 of 7, size is 150
- Dumping compressed chunk 2 of 7, size is 130
- Dumping compressed chunk 3 of 7, size is 224
- Dumping compressed chunk 4 of 7, size is 92
- Dumping compressed chunk 5 of 7, size is 168
- Dumping compressed chunk 6 of 7, size is 4064
- Dumping compressed chunk 7 of 7, size is 2334
- */
-
- // ------------------------------------------------------------
- // TODO: finish this
- // Chunk 0
- convS = convData.getItemStream(0);
- debugCN(kDebugConversations, "Chunk 0\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- debugCN(kDebugConversations, "\n");
- count = convS->readUint16LE(); // conversation face count (usually 2)
- debugCN(kDebugConversations, "Conversation faces: %i\n", count);
- for (i = 0; i < 5; i++) {
- convS->read(buffer, 16);
- debugCN(kDebugConversations, "Face %i: %s ", i + 1, buffer);
- }
- debugCN(kDebugConversations, "\n");
-
- // 5 face slots
- // 1 = face slot has a face (with the filename specified above)
- // 0 = face slot doesn't contain face data
- for (i = 0; i < 5; i++) {
- debugCN(kDebugConversations, "%i ", convS->readUint16LE());
- }
- debugCN(kDebugConversations, "\n");
-
- convS->read(buffer, 14); // speech file
- debugCN(kDebugConversations, "Speech file: %s\n", buffer);
-
- while (!convS->eos()) { // FIXME: eos changed
- debugCN(kDebugConversations, "%i ", convS->readByte());
- }
- debugCN(kDebugConversations, "\n");
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 1: Conversation nodes
- convS = convData.getItemStream(1);
- debugCN(kDebugConversations, "Chunk 1: conversation nodes\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (true) {
- uint16 id = convS->readUint16LE();
- if (convS->eos()) break;
-
- curEntry = new ConvEntry();
- curEntry->id = id;
- curEntry->entryCount = convS->readUint16LE();
- curEntry->flags = convS->readUint16LE();
- if (curEntry->entryCount == 1 && curEntry->flags != 65535) {
- warning("Entry count is 1 and flags is not 65535 (it's %i)", flags);
- } else if (curEntry->entryCount != 1 && flags != 0) {
- warning("Entry count > 1 and flags is not 0 (it's %i)", flags);
- }
- unk = convS->readUint16LE();
- assert (unk == 65535);
- unk = convS->readUint16LE();
- assert (unk == 65535);
- _convNodes.push_back(curEntry);
- debugCN(kDebugConversations, "Node %i, ID %i, entries %i\n", _convNodes.size(), curEntry->id, curEntry->entryCount);
- // flags = 0: node has more than 1 entry
- // flags = 65535: node has 1 entry
- }
- debugCN(kDebugConversations, "Conversation has %i nodes\n", _convNodes.size());
- debugCN(kDebugConversations, "\n");
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 4 contains the conversation string offsets of chunk 5
- // (unused, as it's unneeded - we find the offsets ourselves)
-
- // ------------------------------------------------------------
- // Chunk 5 contains the conversation strings
- convS = convData.getItemStream(5);
- //debugCN(kDebugConversations, "Chunk 5: conversation strings\n");
- //debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- *buffer = 0;
-
- while (true) {
- //if (curPos == 0)
- // debugCN(kDebugConversations, "%i: Offset %i: ", _convStrings.size(), convS->pos());
- uint8 b = convS->readByte();
- if (convS->eos()) break;
-
- buffer[curPos++] = b;
- if (buffer[curPos - 1] == '~') { // filter out special characters
- curPos--;
- continue;
- }
- if (buffer[curPos - 1] == '\0') {
- // end of string
- //debugCN(kDebugConversations, "%s\n", buffer);
- buf = new char[strlen(buffer) + 1];
- strcpy(buf, buffer);
- _convStrings.push_back(buf);
- curPos = 0;
- *buffer = 0;
- }
- }
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 2: entry data
- convS = convData.getItemStream(2);
- //debugCN(kDebugConversations, "Chunk 2 - entry data\n");
- //debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- for (i = 0; i < _convNodes.size(); i++) {
- for (j = 0; j < _convNodes[i]->entryCount; j++) {
- curEntry = new ConvEntry();
- stringIndex = convS->readUint16LE();
- if (stringIndex != 65535)
- sprintf(curEntry->text, "%s", _convStrings[stringIndex]);
- else
- *curEntry->text = 0;
- curEntry->id = convS->readUint16LE();
- curEntry->offset = convS->readUint16LE();
- curEntry->size = convS->readUint16LE();
-
- _convNodes[i]->entries.push_back(curEntry);
- //debugCN(kDebugConversations, "Node %i, entry %i, id %i, offset %i, size %i, text: %s\n",
- // i, j, curEntry->id, curEntry->offset, curEntry->size, curEntry->text);
- }
- }
-
- delete convS;
-
- // ------------------------------------------------------------
- // Chunk 3: message (MESG) chunks, created from the strings of chunk 5
- convS = convData.getItemStream(3);
- //debugCN(kDebugConversations, "Chunk 3 - MESG chunk data\n");
- //debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
-
- while (true) {
- uint16 index = convS->readUint16LE();
- if (convS->eos()) break;
-
- curMessage = new MessageEntry();
- stringIndex = index;
- stringCount = convS->readUint16LE();
- *buffer = 0;
- //debugCN(kDebugConversations, "Message: %i\n", _madsMessageList.size());
- for (i = stringIndex; i < stringIndex + stringCount; i++) {
- //debugCN(kDebugConversations, "%i: %s\n", i, _convStrings[i]);
- curMessage->messageStrings.push_back(_convStrings[i]);
- }
- _madsMessageList.push_back(curMessage);
- //debugCN(kDebugConversations, "----------\n");
- }
- //debugCN(kDebugConversations, "\n");
-
- delete convS;
-
- // ------------------------------------------------------------
- // TODO: finish this
- // Chunk 6: conversation script
- convS = convData.getItemStream(6);
- debugCN(kDebugConversations, "Chunk 6\n");
- debugCN(kDebugConversations, "Conv stream size: %i\n", convS->size());
- /*while (!convS->eos()) { // FIXME (eos changed)
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "%i ", convS->readByte());
- debugCN(kDebugConversations, "\n");
- }
- return;*/
-
- for (i = 0; i < _convNodes.size(); i++) {
- for (j = 0; j < _convNodes[i]->entryCount; j++) {
- debugCN(kDebugConversations, "*** Node %i entry %i data size %i\n", i, j, _convNodes[i]->entries[j]->size);
- debugCN(kDebugConversations, "Entry ID %i, text %s\n", _convNodes[i]->entries[j]->id, _convNodes[i]->entries[j]->text);
- Common::ReadStream *entryStream = new Common::SubReadStream(convS, _convNodes[i]->entries[j]->size);
- readConvEntryActions(entryStream, _convNodes[i]->entries[j]);
- delete entryStream;
- debugCN(kDebugConversations, "--------------------\n");
- }
- }
-
- delete convS;
-}
-
-void Converse::readConvEntryActions(Common::ReadStream *convS, ConvEntry *curEntry) {
- uint8 chunk;
- uint8 type; // 255: normal, 11: conditional
- uint8 hasText1, hasText2;
- int target;
- int count = 0;
- int var, val;
- int messageIndex = 0;
- int unk = 0;
-
- while (true) {
- chunk = convS->readByte();
- if (convS->eos()) break;
-
- type = convS->readByte();
-
- switch (chunk) {
- case 1:
- debugCN(kDebugConversations, "TODO: chunk type %i\n", chunk);
- break;
- case 2:
- debugCN(kDebugConversations, "HIDE\n");
- convS->readByte();
- count = convS->readByte();
- debugCN(kDebugConversations, "%i entries: ", count);
- for (int i = 0; i < count; i++)
- debugCN(kDebugConversations, "%i %d", i, convS->readUint16LE());
- debugCN(kDebugConversations, "\n");
- break;
- case 3:
- debugCN(kDebugConversations, "UNHIDE\n");
- convS->readByte();
- count = convS->readByte();
- debugCN(kDebugConversations, "%i entries: ", count);
- for (int i = 0; i < count; i++)
- debugCN(kDebugConversations, "%i %d", i, convS->readUint16LE());
- debugCN(kDebugConversations, "\n");
- break;
- case 4: // MESSAGE
- debugCN(kDebugConversations, "MESSAGE\n");
-
- if (type == 255) {
- //debugCN(kDebugConversations, "unconditional\n");
- } else if (type == 11) {
- //debugCN(kDebugConversations, "conditional\n");
- } else {
- debugCN(kDebugConversations, "unknown type: %i\n", type);
- }
-
- // Conditional part
- if (type == 11) {
- unk = convS->readUint16LE(); // 1
- if (unk != 1)
- debugCN(kDebugConversations, "Message: unk != 1 (it's %i)\n", unk);
-
- var = convS->readUint16LE();
- val = convS->readUint16LE();
- debugCN(kDebugConversations, "Var %i == %i\n", var, val);
- }
- unk = convS->readUint16LE(); // 256
- if (unk != 256)
- debugCN(kDebugConversations, "Message: unk != 256 (it's %i)\n", unk);
-
- // it seems that the first text entry is set when the message
- // chunk is supposed to be shown unconditionally, whereas the second text
- // entry is set when the message is supposed to be shown conditionally
- hasText1 = convS->readByte();
- hasText2 = convS->readByte();
-
- if (hasText1 == 1) {
- messageIndex = convS->readUint16LE();
- debugCN(kDebugConversations, "Message 1 index: %i, text:\n", messageIndex);
- for (uint32 i = 0; i < _madsMessageList[messageIndex]->messageStrings.size(); i++) {
- debugCN(kDebugConversations, "%s\n", _madsMessageList[messageIndex]->messageStrings[i]);
- }
- }
-
- if (hasText2 == 1) {
- messageIndex = convS->readUint16LE();
- if (hasText1 == 0) {
- debugCN(kDebugConversations, "Message 2 index: %i, text:\n", messageIndex);
- for (uint32 i = 0; i < _madsMessageList[messageIndex]->messageStrings.size(); i++) {
- debugCN(kDebugConversations, "%s\n", _madsMessageList[messageIndex]->messageStrings[i]);
- }
- }
- }
-
- break;
- case 5: // AUTO
- debugCN(kDebugConversations, "AUTO\n");
- for (int k = 0; k < 4; k++)
- convS->readByte();
- messageIndex = convS->readUint16LE();
- debugCN(kDebugConversations, "Message index: %i, text:\n", messageIndex);
- for (uint32 i = 0; i < _madsMessageList[messageIndex]->messageStrings.size(); i++) {
- debugCN(kDebugConversations, "%s\n", _madsMessageList[messageIndex]->messageStrings[i]);
- }
-
- convS->readUint16LE();
- break;
- case 6:
- debugCN(kDebugConversations, "TODO: chunk type %i\n", chunk);
- break;
- case 7: // GOTO
- unk = convS->readUint32LE(); // 0
- if (unk != 0 && unk != 1)
- debugCN(kDebugConversations, "Goto: unk != 0 or 1 (it's %i)\n", unk);
-
- target = convS->readUint16LE();
- convS->readUint16LE(); // 255
-
- if (unk != 0)
- debugCN(kDebugConversations, "Goto: unk != 0 (it's %i)\n", unk);
-
- if (target != 65535)
- debugCN(kDebugConversations, "GOTO node %i\n", target);
- else
- debugCN(kDebugConversations, "GOTO exit\n");
- break;
- case 8:
- debugCN(kDebugConversations, "TODO: chunk type %i\n", chunk);
- break;
- case 9: // ASSIGN
- //debugCN(kDebugConversations, "ASSIGN\n");
- unk = convS->readUint32LE(); // 0
-
- if (unk != 0)
- debugCN(kDebugConversations, "Assign: unk != 0 (it's %i)\n", unk);
-
- val = convS->readUint16LE();
- var = convS->readUint16LE();
- //debugCN(kDebugConversations, "Var %i = %i\n", var, val);
- break;
- default:
- debugCN(kDebugConversations, "Unknown chunk type! (%i)\n", chunk);
- break;
- }
- }
- debugCN(kDebugConversations, "\n");
-}
-
-void Converse::setEntryInfo(int32 offset, EntryType type, int32 nodeIndex, int32 entryIndex) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- EntryInfo info;
- info.targetType = type;
- info.nodeIndex = nodeIndex;
- info.entryIndex = entryIndex;
- _offsetMap[hashOffset] = info;
- //debugCN(kDebugConversations, "Set entry info: offset %i, type %i, node %i, entry %i\n", offset, type, nodeIndex, entryIndex);
-}
-
-const EntryInfo* Converse::getEntryInfo(int32 offset) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- OffsetHashMap::const_iterator entry = _offsetMap.find(hashOffset);
- if (entry != _offsetMap.end())
- return &(entry->_value);
- else
- error("Undeclared entry offset: %i", offset);
-}
-
-void Converse::setValue(int32 offset, int32 value) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- _variables[hashOffset] = value;
-}
-
-int32 Converse::getValue(int32 offset) {
- char hashOffset[10];
- sprintf(hashOffset, "%i", offset);
- ConvVarHashMap::const_iterator entry = _variables.find(hashOffset);
- if (entry != _variables.end())
- return entry->_value;
- else
- error("Undeclared variable offset: %i", offset);
-}
-
-bool Converse::evaluateCondition(int32 leftVal, int32 op, int32 rightVal) {
- switch (op) {
- case kOpPercent:
- return (leftVal % rightVal == 0);
- case kOpGreaterOrEqual:
- return leftVal >= rightVal;
- case kOpLessOrEqual:
- return leftVal <= rightVal;
- case kOpGreaterThan:
- return leftVal > rightVal;
- case kOpLessThan:
- return leftVal < rightVal;
- case kOpNotEqual:
- case kOpCondNotEqual:
- return leftVal != rightVal;
- case kOpAssign:
- return leftVal == rightVal;
- case kOpAnd:
- return leftVal && rightVal;
- case kOpOr:
- return leftVal || rightVal;
- default:
- error("Unknown conditional operator: %i", op);
- }
-}
-
-bool Converse::performAction(EntryAction *action) {
- if (action->isConditional) {
- if (!evaluateCondition(getValue(action->condition.offset),
- action->condition.op, action->condition.val))
- return true; // don't perform this action
- }
-
- if (action->actionType == kAssignValue) {
- //debugCN(kDebugConversations, "Assigning variable at offset %i to value %i\n",
- // action->targetOffset, action->value);
- setValue(action->targetOffset, action->value);
- return true; // nothing else to do in an assignment action
- }
-
- const EntryInfo *entryInfo = getEntryInfo(action->targetOffset);
- ConvEntry *targetEntry;
-
- if (entryInfo->nodeIndex >= 0 && entryInfo->entryIndex >= 0)
- targetEntry = getNode(entryInfo->nodeIndex)->entries[entryInfo->entryIndex];
- else if (entryInfo->nodeIndex >= 0)
- targetEntry = getNode(entryInfo->nodeIndex);
- else
- error("Target node id is negative");
-
- switch (action->actionType) {
- case kGotoEntry:
- //debugCN(kDebugConversations, "Goto entry at offset %i. Associated node is %i, entry %i\n",
- // action->targetOffset, entryInfo->nodeIndex, entryInfo->entryIndex);
- _vm->_conversationView->setNode(entryInfo->nodeIndex);
- if (entryInfo->entryIndex >= 0)
- _vm->_conversationView->selectEntry(entryInfo->entryIndex);
- return false;
- case kHideEntry:
- //debugCN(kDebugConversations, "Hide entry at offset %i. Associated node is %i, entry %i\n",
- // targetEntry->offset, entryInfo->nodeIndex, entryInfo->entryIndex);
- targetEntry->visible = false;
- return true;
- case kUnhideEntry:
- //debugCN(kDebugConversations, "Show entry at offset %i. Associated node is %i, entry %i\n",
- // targetEntry->offset, entryInfo->nodeIndex, entryInfo->entryIndex);
- targetEntry->visible = true;
- return true;
- case kDestroyEntry:
- //debugCN(kDebugConversations, "Destroy entry at offset %i. Associated node is %i, entry %i\n",
- // targetEntry->offset, entryInfo->nodeIndex, entryInfo->entryIndex);
- if (entryInfo->entryIndex >= 0)
- getNode(entryInfo->nodeIndex)->entries.remove_at(entryInfo->entryIndex);
- else
- warning("Target entry is a node, not destroying it");
- targetEntry->visible = true;
- return true;
- case kExitConv:
- //debugCN(kDebugConversations, "Exit conversation\n");
- endConversation();
- return false;
- default:
- warning("Unknown entry action");
- return false;
- } // end switch
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsConversation::MadsConversation() {
- for (int i = 0; i < MADS_TALK_SIZE; ++i) {
- _talkList[i].desc = NULL;
- _talkList[i].id = 0;
- }
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/converse.h b/engines/m4/converse.h
deleted file mode 100644
index b47e8d2a6b..0000000000
--- a/engines/m4/converse.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_CONVERSE_H
-#define M4_CONVERSE_H
-
-#include "common/array.h"
-#include "common/hashmap.h"
-
-#include "m4/globals.h"
-#include "m4/viewmgr.h"
-#include "m4/sound.h"
-
-namespace M4 {
-
-enum ConversationState {
- kConversationOptionsShown = 0,
- kEntryIsActive = 1,
- kReplyIsActive = 2,
- kNoConversation = 3
-};
-
-enum EntryType {
- kVariable = 0,
- kNode = 1,
- kLinearNode = 2,
- kEntry = 3,
- kReply = 4,
- kWeightedReply = 5
-};
-
-// Flags are:
-// bit 0: if it's 1, the entry is "initial", i.e. not hidden when the dialog starts
-// bit 1: if it's 1, the entry persists if selected
-enum EntryFlags {
- kEntryInitial = 1, // byte 0
- kEntryPersists = 2 // byte 1
-};
-
-enum EntryActionType {
- kUnknownAction = 0,
- kGotoEntry = 1,
- kHideEntry = 2,
- kUnhideEntry = 3,
- kDestroyEntry = 4,
- kAssignValue = 5,
- kExitConv = 6
-};
-
-enum LogicOp {
- kOpPercent = 405,
- kOpGreaterOrEqual = 421,
- kOpLessOrEqual = 420,
- kOpGreaterThan = 413,
- kOpLessThan = 412,
- kOpNotEqual = 422,
- kOpCondNotEqual = 448,
- kOpAssign = 407,
- kOpAnd = 444,
- kOpOr = 445
-};
-
-struct Condition {
- int32 offset;
- int32 op;
- int32 val;
-};
-
-struct EntryAction {
- int32 targetOffset; // absolute offset (inside the *.chk file) of the action's target
- int32 value; // the value set by assignment chunks
- EntryActionType actionType;
- EntryType targetType;
- int32 nodeId;
- int32 entryId;
- bool isConditional;
- Condition condition;
-};
-
-struct ConvEntry {
- EntryType entryType;
- int32 id;
- int32 offset; // absolute offset inside the *.chk file, referenced by other chunks
- int32 size; // entry action data size (for MADS games)
- int32 flags;
- int32 fallthroughMinEntries;
- int32 fallthroughOffset;
- int32 weight; // weight for weighted replies
- int32 totalWeight;
- uint16 entryCount; // entries inside this node (for MADS games)
- char voiceFile[10];
- char text[512];
- bool autoSelect;
- bool visible;
- bool isConditional;
- Condition condition;
- Common::Array<EntryAction*>actions;
- Common::Array<ConvEntry*>entries;
-};
-
-struct EntryInfo {
- EntryType targetType;
- int32 nodeIndex;
- int32 entryIndex;
-};
-
-struct MessageEntry {
- Common::Array<char*>messageStrings;
-};
-
-enum ConverseStyle {CONVSTYLE_EARTH, CONVSTYLE_SPACE};
-
-typedef Common::HashMap<Common::String,EntryInfo,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> OffsetHashMap;
-typedef Common::HashMap<Common::String,int32,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> ConvVarHashMap;
-
-class ConversationView : public View {
-public:
- ConversationView(MadsM4Engine *vm);
- ~ConversationView();
- void setNode(int32 nodeIndex);
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- int32 getCurrentNodeIndex() { return _currentNodeIndex; }
- void selectEntry(int entryIndex);
-
-private:
- void updateState();
- void playNextReply();
-
- int32 _currentNodeIndex;
- Common::Array<ConvEntry *> _activeItems;
- int _highlightedIndex;
- int _xEnd;
- bool _entriesShown;
- ConversationState _conversationState;
- SndHandle *_currentHandle;
-};
-
-class Converse {
-
-public:
- Converse(MadsM4Engine *vm) : _vm(vm) {}
- ~Converse() {}
-
- void startConversation(const char *convName, bool showConversebox = true, ConverseStyle style = CONVSTYLE_EARTH );
- void endConversation();
- const EntryInfo* getEntryInfo(int32 offset);
- ConvEntry *getNode(int32 index) { return _convNodes[index]; }
-
- void setValue(int32 offset, int32 value);
- int32 getValue(int32 offset);
- bool evaluateCondition(int32 leftVal, int32 op, int32 rightVal);
- bool performAction(EntryAction *action);
- /*
- void resume() { play(); }
- void play();
- */
-private:
- MadsM4Engine *_vm;
- Common::Array<ConvEntry*>_convNodes;
- Common::Array<MessageEntry*>_madsMessageList;
- Common::Array<char *>_convStrings;
- bool _playerCommandsAllowed;
- bool _interfaceWasVisible;
- ConverseStyle _style;
- OffsetHashMap _offsetMap;
- ConvVarHashMap _variables;
-
- void loadConversation(const char *convName);
- void loadConversationMads(const char *convName);
- void readConvEntryActions(Common::ReadStream *convS, ConvEntry *curEntry);
- void setEntryInfo(int32 offset, EntryType type, int32 nodeIndex, int32 entryIndex);
-};
-
-
-struct MadsTalkEntry {
- uint16 id;
- const char *desc;
-};
-
-#define MADS_TALK_SIZE 5
-
-class MadsConversation {
-private:
- MadsTalkEntry _talkList[MADS_TALK_SIZE];
-public:
- MadsConversation();
-
- MadsTalkEntry &operator[](int index) { return _talkList[index]; }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/detection.cpp b/engines/m4/detection.cpp
deleted file mode 100644
index 6b8af6b5f2..0000000000
--- a/engines/m4/detection.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "base/plugins.h"
-
-#include "engines/advancedDetector.h"
-
-#include "m4/m4.h"
-#include "m4/resource.h"
-
-namespace M4 {
-
-struct M4GameDescription {
- ADGameDescription desc;
-
- int gameType;
- uint32 features;
-};
-
-int MadsM4Engine::getGameType() const { return _gameDescription->gameType; }
-uint32 MadsM4Engine::getFeatures() const { return _gameDescription->features; }
-Common::Language MadsM4Engine::getLanguage() const { return _gameDescription->desc.language; }
-Common::Platform MadsM4Engine::getPlatform() const { return _gameDescription->desc.platform; }
-
-} // End of namespace M4
-
-static const PlainGameDescriptor m4Games[] = {
- {"m4", "MADS/M4 engine game"},
- {"riddle", "Ripley's Believe It or Not!: The Riddle of Master Lu"},
- {"burger", "Orion Burger"},
- {"rex", "Rex Nebular and the Cosmic Gender Bender"},
- {"dragon", "DragonSphere"},
- {"dragoncd", "DragonSphere CD"},
- {"phantom", "Return of the Phantom"},
- {"phantomcd", "Return of the Phantom CD"},
- {0, 0}
-};
-
-namespace M4 {
-
-const char *MadsM4Engine::getGameFile(int fileType) {
- for (int i = 0; _gameDescription->desc.filesDescriptions[i].fileName; i++) {
- if (_gameDescription->desc.filesDescriptions[i].fileType == fileType)
- return _gameDescription->desc.filesDescriptions[i].fileName;
- }
- return NULL;
-}
-
-static const M4GameDescription gameDescriptions[] = {
- {
- {
- "burger",
- "",
- {
- { "burger.has", kFileTypeHash, "10c8064e9c771072122f50737ac97245", 730771},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Burger,
- kFeaturesCD
- },
- {
- {
- "burger",
- "",
- {
- { "burger.has", kFileTypeHash, "55be8693a4c36e7efcdca0f0c77758ae", 724191},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Burger,
- kFeaturesCD
- },
- {
- {
- "burger",
- "",
- {
- { "burger.has", kFileTypeHash, "795c98a74e351ec437a396bb29897daf", 730771},
- { NULL, 0, NULL, 0}
- },
- Common::RU_RUS,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Burger,
- kFeaturesCD
- },
- {
- {
- "burger",
- "Demo",
- {
- { "burger.has", kFileTypeHash, "fc3f363b6153240a448bd3b7be9318da", 62159},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Burger,
- kFeaturesDemo
- },
- {
- {
- "burger",
- "Demo",
- {
- { "overview.has", kFileTypeHash, "57aa43a3ef88a934a43e9b1890ef5e17", 10519},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Burger,
- kFeaturesDemo
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "056d517360c89eb4c297a319f21a7071", 700469},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "d073582c9011d44dd0d7e2ede317a86d", 700469},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "d9e9f8befec432a047b1047fb2bc7aea", 710997},
- { NULL, 0, NULL, 0}
- },
- Common::DE_DEU,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "3d48c5700785d11e6a5bc832b95be918", 701973},
- { NULL, 0, NULL, 0}
- },
- Common::FR_FRA,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Riddle,
- kFeaturesCD
- },
- {
- {
- "riddle",
- "",
- {
- { "ripley.has", kFileTypeHash, "5ee011cff7178dae3ddf6f9b7d4102ac", 701691},
- { NULL, 0, NULL, 0}
- },
- Common::ES_ESP,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Riddle,
- kFeaturesCD
- },
- { // Demo
- {
- "riddle",
- "Demo",
- {
- { "ripley.has", kFileTypeHash, "3a90dd7052860b6e246ec7e0aaf202f6", 104527},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO1(GUIO_NOASPECT)
- },
- GType_Riddle,
- kFeaturesDemo
- },
- {
- {
- "rex",
- "",
- {
- { "global.hag", kFileTypeHAG, "0530cbeee109fc79cc24421128dea1ce", 2083078},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOSPEECH)
- },
- GType_RexNebular,
- kFeaturesNone
- },
- { // Demo
- {
- "rex",
- "Demo",
- {
- { "global.hag", kFileTypeHAG, "d5a481d14bc1bda66e46965a39badcc7", 220429},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO0()
- },
- GType_RexNebular,
- kFeaturesDemo
- },
- {
- {
- "dragon",
- "",
- {
- { "global.hag", kFileTypeHAG, "c3a6877665e7f21bf3d2b1e667155562", 2320567},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOSPEECH)
- },
- GType_DragonSphere,
- kFeaturesNone
- },
- { // CD version
- {
- "dragoncd",
- "",
- {
- { "global.hag", kFileTypeHAG, "c3a6877665e7f21bf3d2b1e667155562", 2320567},
- { "speech.hag", kFileTypeHAG, NULL, -1},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO0()
- },
- GType_DragonSphere,
- kFeaturesCD
- },
- { // Demo
- {
- "dragon",
- "Demo",
- {
- { "global.hag", kFileTypeHAG, "541e12d8e9aad0c65d65f150de47582e", 212718},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO0()
- },
- GType_DragonSphere,
- kFeaturesDemo
- },
- {
- {
- "phantom",
- "",
- {
- { "global.hag", kFileTypeHAG, "bdce9ca93a015f0883d1bc0fabd0cdfa", 812150},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO1(GUIO_NOSPEECH)
- },
- GType_Phantom,
- kFeaturesNone
- },
- { // CD version
- {
- "phantomcd",
- "",
- {
- { "global.hag", kFileTypeHAG, "8a51c984eb4c64e8b30a7e6670f6bddb", 101154000},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_UNSTABLE,
- GUIO0()
- },
- GType_Phantom,
- kFeaturesCD
- },
- { // CD version
- {
- "phantom",
- "Demo",
- {
- { "global.hag", kFileTypeHAG, "e810adbc6fac77ac2fec841a9ec5e20e", 115266},
- { NULL, 0, NULL, 0}
- },
- Common::EN_ANY,
- Common::kPlatformPC,
- ADGF_DEMO | ADGF_UNSTABLE,
- GUIO0()
- },
- GType_Phantom,
- kFeaturesDemo
- },
- { AD_TABLE_END_MARKER, 0, 0 }
-};
-
-} // End of namespace M4
-
-static const char *directoryGlobs[] = {
- "option1",
- 0
-};
-
-class M4MetaEngine : public AdvancedMetaEngine {
-public:
- M4MetaEngine() : AdvancedMetaEngine(M4::gameDescriptions, sizeof(M4::M4GameDescription), m4Games) {
- _singleid = "m4";
- _guioptions = GUIO1(GUIO_NOMIDI);
- _maxScanDepth = 2;
- _directoryGlobs = directoryGlobs;
- }
-
- virtual const char *getName() const {
- return "MADS/M4";
- }
-
- virtual const char *getOriginalCopyright() const {
- return "Riddle of Master Lu & Orion Burger (C) Sanctuary Woods";
- }
-
- virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-};
-
-bool M4MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
- const M4::M4GameDescription *gd = (const M4::M4GameDescription *)desc;
- if (gd) {
- if ((gd->gameType == M4::GType_Burger) || (gd->gameType == M4::GType_Riddle))
- *engine = new M4::M4Engine(syst, gd);
- else
- *engine = new M4::MadsEngine(syst, gd);
- }
- return gd != 0;
-}
-
-#if PLUGIN_ENABLED_DYNAMIC(M4)
- REGISTER_PLUGIN_DYNAMIC(M4, PLUGIN_TYPE_ENGINE, M4MetaEngine);
-#else
- REGISTER_PLUGIN_STATIC(M4, PLUGIN_TYPE_ENGINE, M4MetaEngine);
-#endif
diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp
deleted file mode 100644
index 2a36fa037c..0000000000
--- a/engines/m4/dialogs.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/dialogs.h"
-#include "common/file.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-static void strToUpper(char *s) {
- while (*s) {
- *s = toupper(*s);
- ++s;
- }
-}
-
-static void strToLower(char *s) {
- while (*s) {
- *s = tolower(*s);
- ++s;
- }
-}
-
-const RGB8 DIALOG_PALETTE[8] = {
- {0x80, 0x80, 0x80}, {0x90, 0x90, 0x90}, {0x70, 0x70, 0x70}, {0x9c, 0x9c, 0x9c},
- {0x80, 0x80, 0x80}, {0x90, 0x90, 0x90}, {0xDC, 0xDC, 0xDC}, {0x00, 0x00, 0x00}
-};
-
-#define ROR16(v,amt) (((uint16)(v) >> amt) | ((uint16)(v) << (16 - amt)))
-
-const int DIALOG_SPACING = 1;
-
-/**
- * Handles any dialog initialisation
- */
-void Dialog::initDialog() {
- incLine();
-}
-
-/**
- * Adds a new line to the dialog output
- */
-void Dialog::incLine() {
- _lineX = 0;
- _widthX = 0;
-
- _lines.push_back(*new DialogLine());
- assert(_lines.size() <= 20);
-}
-
-/**
- * Writes some text to the dialog output, taking care of word wrapping if the text size
- * exceeds the dialog's width
- */
-void Dialog::writeChars(const char *srcLine) {
- char wordStr[80];
- char line[80];
- int lineLen, lineWidth;
- const char *srcP = srcLine;
-
- while (*srcP) {
- bool wordEndedP = false, newlineP = false;
- char *destP = &wordStr[0];
- Common::fill(&wordStr[0], &wordStr[80], 0);
-
- // Try and get the next word
- for (;;) {
- char v = *srcP;
- *destP++ = v;
-
- if (v == '\0') break;
- if (v == '\n') {
- newlineP = true;
- ++srcP;
- --destP;
- break;
- }
-
- if (v == ' ') {
- // Word separator
- ++srcP;
- --destP;
- wordEndedP = true;
- } else {
- // Standard character
- if (!wordEndedP)
- // Still in the initial word
- ++srcP;
- else {
- // First character of next word, so time to break
- --destP;
- break;
- }
- }
- }
-
- if (destP < &wordStr[0])
- destP = &wordStr[0];
- *destP = '\0';
-
- strcpy(line, "");
- if (_lineX > 0)
- strcat(line, " ");
- strcat(line, wordStr);
-
- lineLen = strlen(line);
- lineWidth = _vm->_font->current()->getWidth(line, DIALOG_SPACING);
-
- if (((_lineX + lineLen) > _widthChars) || ((_widthX + lineWidth) > _dialogWidth)) {
- incLine();
- appendText(wordStr);
- } else {
- appendText(line);
- }
-
- if (newlineP)
- incLine();
- }
-}
-
-/**
- * Appends some text to the current dialog line
- */
-void Dialog::appendText(const char *line) {
- _lineX += strlen(line);
- _widthX += _vm->_font->current()->getWidth(line, DIALOG_SPACING);
-
- strcat(_lines[_lines.size() - 1].data, line);
-}
-
-/**
- * Adds a line of text to the dialog lines list
- */
-void Dialog::addLine(const char *line, bool underlineP) {
- if ((_widthX > 0) || (_lineX > 0))
- incLine();
-
- int lineWidth = _vm->_font->current()->getWidth(line, DIALOG_SPACING);
- int lineLen = strlen(line);
-
- if ((lineWidth > _dialogWidth) || (lineLen >= _widthChars))
- writeChars(line);
- else {
- _lines[_lines.size() - 1].xp = (_dialogWidth - 10 - lineWidth) / 2;
- strcpy(_lines[_lines.size() - 1].data, line);
- }
-
- if (underlineP)
- _lines[_lines.size() - 1].underline = true;
-
- incLine();
-}
-
-/**
- * Adds a bar separation line to the dialog lines list
- */
-void Dialog::addBarLine() {
- if ((_widthX > 0) || (_lineX > 0))
- incLine();
-
- // Flag the line as being a bar separator
- _lines[_lines.size() - 1].barLine = true;
- incLine();
-}
-
-/**
- * Retrieves a specified vocab entry
- */
-void Dialog::getVocab(int vocabId, char **line) {
- assert(vocabId > 0);
- const char *vocabStr = _madsVm->globals()->getVocab(vocabId);
- strcpy(*line, vocabStr);
-
- if (_commandCase)
- strToUpper(*line);
- else
- strToLower(*line);
-
- // Move the string pointer to after the added string
- while (!**line)
- ++*line;
-}
-
-bool Dialog::handleNounSuffix(char *destP, int nounNum, const char *srcP) {
- char srcLine[40];
-
- // The next source character must be a colon in front of the first verb
- if (*srcP != ':')
- return false;
-
- // Copy the remainder of the line into a temporary buffer to get the seperate verbs
- strcpy(srcLine, ++srcP);
- char *altP = strchr(srcLine, ':');
- if (altP)
- *altP = '\0';
-
- if (*srcP != '\0') {
- while (*srcP != ':') {
- ++srcP;
- if (!*srcP) break;
- }
- }
-
- if (*srcP != '\0')
- ++srcP;
-
- //
- char var_FC[40];
- char tempLine[40];
- strcpy(var_FC, srcP);
- char *tmpP = &tempLine[0];
- char *tmp2P = tmpP;
-
- uint16 _vocabIds[2] = {1, 1}; // FIXME/TODO: Proper vocab ids
- getVocab(_vocabIds[nounNum], &tmpP);
-
- if ((*(tmpP - 1) != 'S') && (*(tmpP - 1) != 's')) {
- // Singular object
- tmpP = &var_FC[0];
- } else if (!strcmp(tempLine, "a ")) {
- // Pontially plural
- char ch = tolower(*tmp2P);
-
- if (!((ch > 'U') || ((ch != 'A') && (ch != 'E') && (ch != 'I') && (ch != 'O'))))
- strcpy(tempLine, "an ");
- }
-
- strcpy(destP, tmpP);
- return true;
-}
-
-/**
- * Sets up an area within the dialog for textual input
- */
-void Dialog::setupInputArea() {
- _askPosition.x = _lineX + 1;
- _askPosition.y = _lines.size();
-
- incLine();
-}
-
-/**
- * Checks whether the start of an extracted command matches a specified given command constant
- */
-bool Dialog::matchCommand(const char *s1, const char *s2) {
- bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
- _commandCase = isupper(static_cast<unsigned char>(*s1));
- return result;
-}
-
-Dialog::Dialog(MadsM4Engine *vm, const char *msgData, const char *title): View(vm, Common::Rect(0, 0, 0, 0)) {
- assert(msgData);
- _vm->_font->setFont(FONT_INTERFACE_MADS);
-
- const char *srcP = msgData;
- bool skipLine = false;
- bool initFlag = false;
- bool cmdFlag = false;
- bool crFlag = false;
- bool underline = false;
-
- _screenType = LAYER_DIALOG;
- _widthChars = 0;
- _dialogIndex = 0;
- _askPosition.x = 0;
- _askPosition.y = 0;
- _lineX = 0;
- _widthX = 0;
- _dialogWidth = 0;
- _commandCase = false;
-
- char dialogLine[256];
- char cmdText[80];
- char *lineP = &dialogLine[0];
- char *cmdP = NULL;
-
- while (srcP && *(srcP - 1) != '\0') {
- if ((*srcP == '\n') || (*srcP == '\0')) {
- // Line completed
- *lineP = '\0';
- ++srcP;
-
- if (!initFlag) {
- initDialog();
- initFlag = true;
- }
-
- if (!skipLine)
- writeChars(dialogLine);
- else {
- addLine(dialogLine, underline);
-
- if (crFlag)
- incLine();
- }
-
- // Clear the current line contents
- dialogLine[0] = '\0';
- lineP = &dialogLine[0];
- skipLine = crFlag = underline = false;
- continue;
-
- } else if (*srcP == '[') {
- // Start of a command sequence
- cmdFlag = true;
- cmdP = &cmdText[0];
- ++srcP;
- continue;
- } else if (*srcP == ']') {
- // End of a command sequence
- *cmdP = '\0';
- cmdFlag = false;
- strToUpper(cmdText);
-
- if (matchCommand(cmdText, "ASK")) {
- setupInputArea();
-
- } else if (matchCommand(cmdText, "BAR")) {
- // Adds a full-width line instead of normal text
- addBarLine();
-
- } else if (matchCommand(cmdText, "CENTER")) {
- // Center command
- skipLine = true;
-
- } else if (matchCommand(cmdText, "CR")) {
- // CR command
- if (skipLine)
- crFlag = true;
- else if (!initFlag) {
- initDialog();
- initFlag = true;
- }
-
- } else if (matchCommand(cmdText, "NOUN1")) {
- // Noun command 1
- handleNounSuffix(lineP, 1, cmdText + 5);
-
- } else if (matchCommand(cmdText, "NOUN2")) {
- // Noun command 2
- handleNounSuffix(lineP, 2, cmdText + 5);
-
- } else if (matchCommand(cmdText, "SENTENCE")) {
- // Sentence command - loads the title into the line buffer
- strcpy(dialogLine, title);
- strToUpper(dialogLine);
- lineP += strlen(dialogLine) + 1;
-
- } else if (matchCommand(cmdText, "TAB")) {
- // Specifies the X offset for the current line
- _lines[_lines.size() - 1].xp = atoi(cmdText + 3);
-
- } else if (matchCommand(cmdText, "TITLE")) {
- // Title command - specifies the dialog width in number of characters
- skipLine = true;
- crFlag = true;
- underline = true;
-
- int id = atoi(cmdText + 5);
- if (id > 0) {
- // Suffix provided - specifies the dialog width in number of chars
- _widthChars = id * 2;
- _dialogWidth = id * (_vm->_font->current()->getMaxWidth() + DIALOG_SPACING) + 10;
- }
-
- } else if (matchCommand(cmdText, "UNDER")) {
- // Underline command
- underline = true;
-
- } else if (matchCommand(cmdText, "VERB")) {
- // Verb/vocab retrieval
- int verbId = 1; // TODO: Get correct vocab
- getVocab(verbId, &lineP);
-
-
- } else if (matchCommand(cmdText, "INDEX")) {
- // Index command
- _dialogIndex = atoi(cmdText + 5);
- } else {
- error("Unknown dialog command '%s' encountered", cmdText);
- }
- }
-
- *lineP++ = *srcP;
- if (cmdFlag)
- *cmdP++ = *srcP;
- ++srcP;
- }
-
- draw();
-}
-
-Dialog::Dialog(MadsM4Engine *vm, int widthChars): View(vm, Common::Rect(0, 0, 0, 0)) {
- _vm->_font->setFont(FONT_INTERFACE_MADS);
- _widthChars = widthChars * 2;
- _dialogWidth = widthChars * (_vm->_font->current()->getMaxWidth() + DIALOG_SPACING) + 10;
- _screenType = LAYER_DIALOG;
- _lineX = 0;
- _widthX = 0;
- _askPosition.x = 0;
- _askPosition.y = 0;
-}
-
-Dialog::~Dialog() {
- _vm->_palette->deleteRange(_palette);
- delete _palette;
-}
-
-void Dialog::draw() {
- assert(_widthChars != 0);
-
- // Set up the palette for this view
- _palette = new RGBList(8, NULL);
- _palette->setRange(0, 8, DIALOG_PALETTE);
- _vm->_palette->addRange(_palette);
-
- // Calculate bounds
- int dlgWidth = _dialogWidth;
- int dlgHeight = _lines.size() * (_vm->_font->current()->getHeight() + 1) + 10;
- int dialogX = (_vm->_screen->width() - dlgWidth) / 2;
- int dialogY = (_vm->_screen->height() - dlgHeight) / 2;
-
- // Create the surface for the dialog
- create(dlgWidth, dlgHeight, Graphics::PixelFormat::createFormatCLUT8());
- _coords.left = dialogX;
- _coords.top = dialogY;
- _coords.right = dialogX + dlgWidth + 1;
- _coords.bottom = dialogY + dlgHeight + 1;
-
- // Set up the dialog
- fillRect(Common::Rect(0, 0, width(), height()), 3);
- setColor(2);
- hLine(1, width() - 1, height() - 2); // Bottom edge
- hLine(0, width(), height() - 1);
- vLine(width() - 2, 2, height()); // Right edge
- vLine(width() - 1, 1, height());
-
- // Render dialog interior
- uint16 seed = 0xb78e;
- for (int yp = 2; yp < (height() - 2); ++yp) {
- byte *destP = this->getBasePtr(2, yp);
-
- for (int xp = 2; xp < (width() - 2); ++xp) {
- // Adjust the random seed
- uint16 v = seed;
- seed += 0x181D;
- v = ROR16(v, 9);
- seed = (seed ^ v) + ROR16(v, 3);
-
- *destP++ = ((seed & 0x10) != 0) ? 1 : 0;
- }
- }
-
- // If an ask position is set, create the input area frame
- if (_askPosition.y > 0) {
-
- }
-
- // Handle drawing the text contents
- _vm->_font->current()->setColors(7, 7, 7);
- setColor(7);
-
- for (uint lineCtr = 0, yp = 5; lineCtr < _lines.size(); ++lineCtr, yp += _vm->_font->current()->getHeight() + 1) {
-
- if (_lines[lineCtr].barLine) {
- // Bar separation line
- hLine(5, width() - 6, ((_vm->_font->current()->getHeight() + 1) >> 1) + yp);
- } else {
- // Standard line
- Common::Point pt(_lines[lineCtr].xp + 5, yp);
- if (_lines[lineCtr].xp & 0x40)
- ++pt.y;
-
- _vm->_font->current()->writeString(this, _lines[lineCtr].data, pt.x, pt.y, 0, DIALOG_SPACING);
-
- if (_lines[lineCtr].underline)
- // Underline needed
- hLine(pt.x, pt.x + _vm->_font->current()->getWidth(_lines[lineCtr].data, DIALOG_SPACING),
- pt.y + _vm->_font->current()->getHeight());
- }
- }
-
- // Do final translation of the dialog to game palette
- this->translate(_palette);
-}
-
-bool Dialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- if (_vm->_mouse->getCursorNum() != CURSOR_ARROW)
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- captureEvents = true;
-
- if (eventType == MEVENT_LEFT_CLICK) {
- captureEvents = false;
- _vm->_viewManager->deleteView(this);
- }
-
- return true;
-}
-
-void Dialog::display(MadsM4Engine *vm, int widthChars, const char **descEntries) {
- Dialog *dlg = new Dialog(vm, widthChars);
-
- while (*descEntries != NULL) {
- dlg->incLine();
- dlg->writeChars(*descEntries);
-
- int lineWidth = vm->_font->current()->getWidth(*descEntries, DIALOG_SPACING);
- dlg->_lines[dlg->_lines.size() - 1].xp = (dlg->_dialogWidth - 10 - lineWidth) / 2;
- ++descEntries;
- }
-
- dlg->_lines[0].underline = true;
-
- dlg->draw();
- vm->_viewManager->addView(dlg);
- vm->_viewManager->moveToFront(dlg);
-}
-
-void Dialog::getValue(MadsM4Engine *vm, const char *title, const char *text, int numChars, int currentValue) {
- int titleLen = strlen(title);
- Dialog *dlg = new Dialog(vm, titleLen + 4);
-
- dlg->addLine(title, true);
- dlg->writeChars("\n");
-
- dlg->writeChars(text);
- dlg->setupInputArea();
- dlg->writeChars("\n");
-
- dlg->draw();
- vm->_viewManager->addView(dlg);
- vm->_viewManager->moveToFront(dlg);
-
- // TODO: How to wait until the dialog is closed
-
-}
-
-} // End of namespace M4
diff --git a/engines/m4/dialogs.h b/engines/m4/dialogs.h
deleted file mode 100644
index ea3519c9e3..0000000000
--- a/engines/m4/dialogs.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_DIALOGS_H
-#define M4_DIALOGS_H
-
-#include "m4/m4.h"
-#include "m4/viewmgr.h"
-#include "common/list.h"
-
-namespace M4 {
-
-class DialogLine {
-public:
- char data[100];
- uint8 xp;
- bool underline;
- bool barLine;
-
- DialogLine() { data[0] = '\0'; xp = 0; underline = barLine = false; }
-};
-
-typedef void (*GetValueFn)(MadsM4Engine *vm, int result);
-
-class Dialog : public View {
-private:
- Common::Array<DialogLine> _lines;
- int _widthChars;
- int _dialogWidth;
- int _dialogIndex;
- Common::Point _askPosition;
- RGBList *_palette;
- int _lineX;
- int _widthX;
- bool _commandCase;
-
- void initDialog();
- void incLine();
- bool matchCommand(const char *s1, const char *s2);
- void writeChars(const char *line);
- void addLine(const char *line, bool underlineP = false);
- void appendText(const char *line);
- void addBarLine();
- void getVocab(int vocabId, char **line);
- bool handleNounSuffix(char *destP, int nounNum, const char *srcP);
- void setupInputArea();
- void draw();
-public:
- Dialog(MadsM4Engine *vm, const char *msgData, const char *title = NULL);
- Dialog(MadsM4Engine *vm, int widthChars);
- virtual ~Dialog();
-
- static void display(MadsM4Engine *vm, int widthChars, const char **descEntries);
- static void getValue(MadsM4Engine *vm, const char *title, const char *text, int numChars, int currentValue);
-
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/events.cpp b/engines/m4/events.cpp
deleted file mode 100644
index b476d08c9c..0000000000
--- a/engines/m4/events.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// TODO: There is a 'please_hyperwalk' variable that gets accessed that is meant to be global, but
-// at the moment it's implemented as a local variable
-
-#include "graphics/cursorman.h"
-
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/scene.h"
-#include "m4/viewmgr.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-bool please_hyperwalk = false;
-
-/*--------------------------------------------------------------------------*
- * Events *
- * *
- * Implements an interface to the event system *
- *--------------------------------------------------------------------------*/
-
-Events::Events(MadsM4Engine *vm) : _vm(vm) {
- _mouseState = MSTATE_NO_EVENT;
- quitFlag = false;
- _keyCode = 0;
- _mouseButtons = 0;
- _ctrlFlag = false;
-
- if (_vm->isM4())
- _console = new M4Console(_m4Vm);
- else
- _console = new MadsConsole(_madsVm);
-}
-
-Events::~Events() {
- delete _console;
-}
-
-M4EventType Events::handleEvents() {
- static int oldX = -1, oldY = -1;
- static uint32 dclickTime = 0;
-
- // Handle event types
- while (g_system->getEventManager()->pollEvent(_event)) {
- switch (_event.type) {
- case Common::EVENT_QUIT:
- quitFlag = true;
- break;
- case Common::EVENT_KEYDOWN:
- // Note: The Ctrl-D ScummVM shortcut has been specialised so it will only activate the debugger
- // if it's the first key pressed after the Ctrl key is held down
- if ((_event.kbd.keycode == Common::KEYCODE_LCTRL) || (_event.kbd.keycode == Common::KEYCODE_RCTRL))
- _ctrlFlag = true;
-
- else if (_event.kbd.hasFlags(Common::KBD_CTRL)) {
- if ((_event.kbd.keycode == Common::KEYCODE_d) && _ctrlFlag) {
- _console->attach();
- _console->onFrame();
- }
- _ctrlFlag = false;
- }
- _keyCode = (int32)_event.kbd.keycode | ((_event.kbd.flags & (Common::KBD_CTRL | Common::KBD_ALT | Common::KBD_SHIFT)) << 24);
-
-
- break;
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_MBUTTONDOWN:
- case Common::EVENT_MBUTTONUP:
- case Common::EVENT_MOUSEMOVE:
- case Common::EVENT_WHEELUP:
- case Common::EVENT_WHEELDOWN:
- _vm->_mouse->handleEvent(_event);
- break;
- default:
- break;
- }
- }
-
- _mouseButtons = g_system->getEventManager()->getButtonState();
-
- // State machine for moving between states
- switch (_mouseState) {
- case MSTATE_NO_EVENT:
- if (_mouseButtons & LEFT_BUTTON_DOWN) {
- if ((dclickTime != 0) && (g_system->getMillis() < dclickTime)) {
- _mouseState = MSTATE_DOUBLECLICK_DOWN;
- dclickTime = 0;
- return MEVENT_DOUBLECLICK;
- }
- dclickTime = 0;
- _mouseState = MSTATE_LEFT_CLICK_DOWN;
- return MEVENT_LEFT_CLICK;
- }
- if (_mouseButtons & RIGHT_BUTTON_DOWN) {
- _mouseState = MSTATE_RIGHT_CLICK_DOWN;
- return MEVENT_RIGHT_CLICK;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_MOVE;
- }
- return MEVENT_NO_EVENT;
-
- case MSTATE_LEFT_CLICK_DOWN:
- if (!(_mouseButtons & LEFT_BUTTON_DOWN)) {
- dclickTime = g_system->getMillis() + 1000 * 15 / 60;
- _mouseState = MSTATE_NO_EVENT;
- return MEVENT_LEFT_RELEASE;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_LEFT_DRAG;
- }
- return MEVENT_LEFT_HOLD;
-
- case MSTATE_RIGHT_CLICK_DOWN:
- if (!(_mouseButtons & RIGHT_BUTTON_DOWN)) {
- _mouseState = MSTATE_NO_EVENT;
- please_hyperwalk = true;
- return MEVENT_RIGHT_RELEASE;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_RIGHT_DRAG;
- }
- return MEVENT_RIGHT_HOLD;
-
- case MSTATE_DOUBLECLICK_DOWN:
- if (!(_mouseButtons & LEFT_BUTTON_DOWN)) {
- _mouseState = MSTATE_NO_EVENT;
- return MEVENT_DOUBLECLICK_RELEASE;
- }
- if ((_event.mouse.x != oldX) || (_event.mouse.y != oldY)) {
- oldX = _event.mouse.x; oldY = _event.mouse.y;
- return MEVENT_DOUBLECLICK_DRAG;
- }
- return MEVENT_DOUBLECLICK_HOLD;
-
- default:
- return MEVENT_NO_EVENT;
- }
-}
-
-bool Events::kbdCheck(uint32 &keyCode) {
- if (_keyCode == 0)
- return false;
-
- keyCode = _keyCode;
- _keyCode = 0;
- return true;
-}
-
-
-/*--------------------------------------------------------------------------*
- * Mouse *
- * *
- * Implements an interface to the mouse *
- *--------------------------------------------------------------------------*/
-
-Mouse::Mouse(MadsM4Engine *vm) : _vm(vm) {
- _locked = false;
- _cursorOn = false;
- _cursor = NULL;
- _cursorSprites = NULL;
- resetMouse();
-}
-
-Mouse::~Mouse() {
- delete _cursorSprites;
-}
-
-bool Mouse::init(const char *seriesName, RGB8 *palette) {
- Common::SeekableReadStream *stream = _vm->res()->get(seriesName);
- int colorCount = 0;
- RGB8* cursorPalette;
-
- _cursorSprites = new SpriteAsset(_vm, stream, stream->size(), seriesName);
-
- // Remove cursor special pixels and set the mouse cursor hotspot in MADS games
- if (!_vm->isM4()) {
- byte *data = NULL;
- for (int i = 0; i < _cursorSprites->getCount(); i++) {
- bool hotSpotSet = false;
-
- for (int x = 0; x < _cursorSprites->getFrame(i)->width(); x++) {
- for (int y = 0; y < _cursorSprites->getFrame(i)->height(); y++) {
- data = _cursorSprites->getFrame(i)->getBasePtr(x, y);
- if (*data == 1) {
- // It seems that some cursors have more than one hotspot
- // In such a case, the first hotspot seems to set the x and
- // the second one the y hotspot offset
- if (!hotSpotSet) {
- _cursorSprites->getFrame(i)->xOffset = x;
- _cursorSprites->getFrame(i)->yOffset = y;
- hotSpotSet = true;
- } else {
- _cursorSprites->getFrame(i)->yOffset = y;
- }
- *data = 0;
- }
- } // for y
- } // for x
- } // for i
- }
-
- colorCount = _cursorSprites->getColorCount();
- cursorPalette = _cursorSprites->getPalette();
- _vm->_palette->setPalette(cursorPalette, 0, colorCount);
-
- //debugCN(kDebugCore, "Cursor count: %d\n", _cursorSprites->getCount());
-
- _vm->res()->toss(seriesName);
-
- _currentCursor = -1;
- return true;
-}
-
-bool Mouse::setCursorNum(int cursorIndex) {
- if ((cursorIndex < 0) || (cursorIndex >= (int)_cursorSprites->getCount()))
- return false;
-
- _lockedCursor = cursorIndex;
- if (_locked)
- // Cursor is locked, so don't go ahead with changing cursor
- return true;
-
- _currentCursor = _lockedCursor;
- _cursor = _cursorSprites->getFrame(cursorIndex);
-
- // Set the cursor to the sprite
- CursorMan.replaceCursor((const byte *)_cursor->getBasePtr(), _cursor->width(), _cursor->height(),
- _cursor->xOffset, _cursor->yOffset, TRANSPARENT_COLOR_INDEX);
-
- return true;
-}
-
-int Mouse::cursorCount() {
- return _cursorSprites->getCount();
-}
-
-void Mouse::cursorOn() {
- _cursorOn = true;
- CursorMan.showMouse(!inHideArea());
-}
-
-void Mouse::cursorOff() {
- _cursorOn = false;
- CursorMan.showMouse(false);
-}
-
-void Mouse::lockCursor(int cursorIndex) {
- _locked = false;
- setCursorNum(cursorIndex);
- _locked = true;
-}
-
-void Mouse::unlockCursor() {
- _locked = false;
- setCursorNum(_lockedCursor);
-}
-
-const char *Mouse::getVerb() {
- switch (_vm->_mouse->getCursorNum()) {
- case CURSOR_LOOK:
- return "LOOK AT";
- case CURSOR_TAKE:
- return "TAKE";
- case CURSOR_USE:
- return "GEAR";
- default:
- return NULL;
- }
-}
-
-void Mouse::resetMouse() {
- _hideRect.left = -1;
- _hideRect.top = -1;
- _hideRect.right = -1;
- _hideRect.bottom = -1;
- _showRect.left = -1;
- _showRect.top = -1;
- _showRect.right = -1;
- _showRect.bottom = -1;
-}
-
-void Mouse::setHideRect(Common::Rect &r) {
- _hideRect = r;
-}
-
-void Mouse::setShowRect(Common::Rect &r) {
- _showRect = r;
-}
-
-const Common::Rect *Mouse::getHideRect() {
- return &_hideRect;
-}
-
-const Common::Rect *Mouse::getShowRect() {
- if ((_showRect.top == -1) || (_showRect.left == -1)) {
- // Show rectangle uninitialised - set it to current screen dimensions
- _showRect.top = 0;
- _showRect.left = 0;
- _showRect.right = _vm->_screen->width() - 1;
- _showRect.bottom = _vm->_screen->height() -1;
- }
-
- return &_showRect;
-}
-
-void Mouse::handleEvent(Common::Event &event) {
- _currentPos.x = event.mouse.x;
- _currentPos.y = event.mouse.y;
-
- // If mouse is turned on, check to see if the position is in the hide rect, or outside the show rect.
- // If so, handle toggling the visibility of the mouse
- bool showFlag = !inHideArea();
- if (_cursorOn && (CursorMan.isVisible() != showFlag)) {
- CursorMan.showMouse(showFlag);
- }
-}
-
-bool Mouse::inHideArea() {
- // Returns true if the mouse is inside a specified hide rect, or if a show rect is specified and
- // the mouse is currently outside it
- if ((_currentPos.x >= _hideRect.left) && (_currentPos.x <= _hideRect.right) &&
- (_currentPos.y >= _hideRect.top) && (_currentPos.y <= _hideRect.bottom))
- // Inside a hide area
- return true;
-
-
- if ((_showRect.top == -1) && (_showRect.left == -1))
- // No show rect defined
- return false;
-
- // Return true if the mouse is outside the show area
- return (_currentPos.x < _showRect.left) || (_currentPos.x > _showRect.right) ||
- (_currentPos.y < _showRect.top) || (_currentPos.y > _showRect.bottom);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/events.h b/engines/m4/events.h
deleted file mode 100644
index 6e7cf68555..0000000000
--- a/engines/m4/events.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_EVENTS_H
-#define M4_EVENTS_H
-
-#include "common/events.h"
-#include "common/rect.h"
-
-#include "m4/globals.h"
-#include "m4/assets.h"
-#include "m4/sprite.h"
-#include "m4/graphics.h"
-#include "m4/console.h"
-
-namespace M4 {
-
-#define LEFT_BUTTON_DOWN 1 << 0
-#define RIGHT_BUTTON_DOWN 1 << 1
-
-enum M4EventType {
- MEVENT_NO_EVENT, MEVENT_MOVE,
- MEVENT_LEFT_CLICK, MEVENT_LEFT_HOLD, MEVENT_LEFT_DRAG, MEVENT_LEFT_RELEASE,
- MEVENT_RIGHT_CLICK, MEVENT_RIGHT_HOLD, MEVENT_RIGHT_DRAG, MEVENT_RIGHT_RELEASE,
- MEVENT_BOTH_CLICK, MEVENT_BOTH_HOLD, MEVENT_BOTH_DRAG, MEVENT_BOTH_RELEASE,
- MEVENT_DOUBLECLICK, MEVENT_DOUBLECLICK_HOLD, MEVENT_DOUBLECLICK_DRAG, MEVENT_DOUBLECLICK_RELEASE,
- KEVENT_KEY
-};
-
-enum M4MouseState {
- MSTATE_NO_EVENT, MSTATE_LEFT_CLICK_DOWN, MSTATE_RIGHT_CLICK_DOWN, MSTATE_BOTH_CLICK_DOWN,
- MSTATE_DOUBLECLICK_DOWN
-};
-
-enum M4CommonCursors {
- CURSOR_ARROW = 0,
- CURSOR_WAIT = 1,
- CURSOR_HOURGLASS = 5,
- CURSOR_LOOK = 6,
- CURSOR_TAKE = 8,
- CURSOR_USE = 9
-};
-
-class M4Sprite;
-class SpriteAsset;
-
-class Events {
-private:
- MadsM4Engine *_vm;
- Common::Event _event;
- M4MouseState _mouseState;
- int32 _keyCode;
- int _mouseButtons;
- Console *_console;
- bool _ctrlFlag;
-public:
- bool quitFlag;
- Events(MadsM4Engine *vm);
- virtual ~Events();
-
- Common::Event &event() { return _event; }
- Common::EventType type() { return _event.type; }
-
- // M4-centric methods
- M4EventType handleEvents();
- bool kbdCheck(uint32 &keyCode);
- int getMouseButtonsState() { return _mouseButtons; }
- Console* getConsole() { return _console; }
-};
-
-
-class Mouse {
-private:
- MadsM4Engine *_vm;
- int _currentCursor, _lockedCursor;
- bool _locked;
- bool _cursorOn;
- M4Sprite *_cursor;
- SpriteAsset *_cursorSprites;
- Common::Rect _hideRect, _showRect;
- Common::Point _currentPos;
-
- void handleEvent(Common::Event &event);
- bool inHideArea();
- friend class Events;
-public:
- Mouse(MadsM4Engine *vm);
- ~Mouse();
-
- bool init(const char *seriesName, RGB8 *palette);
- bool setCursorNum(int cursorIndex);
- int getCursorNum() { return _currentCursor; }
- int cursorCount();
- Common::Point currentPos() const { return _currentPos; }
- M4Sprite *cursor() { return _cursor; }
- void cursorOn();
- void cursorOff();
- bool getCursorOn() { return _cursorOn; }
- void lockCursor(int cursorIndex);
- void unlockCursor();
-
- const char *getVerb();
-
- void resetMouse();
- void setHideRect(Common::Rect &r);
- void setShowRect(Common::Rect &r);
- const Common::Rect *getHideRect();
- const Common::Rect *getShowRect();
-};
-
-}
-
-#endif
diff --git a/engines/m4/font.cpp b/engines/m4/font.cpp
deleted file mode 100644
index d4ba714d73..0000000000
--- a/engines/m4/font.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/font.h"
-#include "m4/m4.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-FontManager::~FontManager() {
- for (uint i = 0; i < _entries.size(); ++i)
- delete _entries[i];
- _entries.clear();
-}
-
-Font *FontManager::getFont(const char *filename) {
- // Append an extension if the filename doesn't already have one
- char buffer[20];
- strncpy(buffer, filename, 19);
- if (!strchr(buffer, '.'))
- strcat(buffer, ".ff");
-
- // Check if the font is already loaded
- for (uint i = 0; i < _entries.size(); ++i) {
- if (!strcmp(_entries[i]->_filename, buffer))
- return _entries[i];
- }
-
- Font *f = new Font(_vm, buffer);
- _entries.push_back(f);
- return f;
-}
-
-void FontManager::setFont(const char *filename) {
- _currentFont = getFont(filename);
-}
-
-//--------------------------------------------------------------------------
-
-Font::Font(MadsM4Engine *vm, const char *filename) : _vm(vm) {
- _sysFont = true;
- strncpy(_filename, filename, 19);
- _filename[19] = '\0';
-
- //TODO: System font
- _fontColors[0] = _vm->_palette->BLACK;
- _fontColors[1] = _vm->_palette->WHITE;
- _fontColors[2] = _vm->_palette->BLACK;
- _fontColors[3] = _vm->_palette->DARK_GRAY;
-
- _sysFont = false;
-
- if (_vm->isM4())
- setFontM4(filename);
- else
- setFontMads(filename);
-}
-
-void Font::setFontM4(const char *filename) {
- Common::SeekableReadStream *fontFile = _vm->res()->openFile(filename);
-
- if (fontFile->readUint32LE() != MKTAG('F','O','N','T')) {
- debugCN(kDebugGraphics, "Font::Font: FONT tag expected\n");
- return;
- }
-
- _maxHeight = fontFile->readByte();
- _maxWidth = fontFile->readByte();
- uint32 fontSize = fontFile->readUint32LE();
-
- //debugCN(kDebugGraphics, "Font::Font: _maxWidth = %d, _maxHeight = %d, fontSize = %d\n", _maxWidth, _maxHeight, fontSize);
-
- if (fontFile->readUint32LE() != MKTAG('W','I','D','T')) {
- debugCN(kDebugGraphics, "Font::Font: WIDT tag expected\n");
- return;
- }
-
- _charWidths = new uint8[256];
- fontFile->read(_charWidths, 256);
-
- if (fontFile->readUint32LE() != MKTAG('O','F','F','S')) {
- debugCN(kDebugGraphics, "Font::Font: OFFS tag expected\n");
- return;
- }
-
- _charOffs = new uint16[256];
-
- for (int i = 0; i < 256; i++)
- _charOffs[i] = fontFile->readUint16LE();
-
- if (fontFile->readUint32LE() != MKTAG('P','I','X','S')) {
- debugCN(kDebugGraphics, "Font::Font: PIXS tag expected\n");
- return;
- }
-
- _charData = new uint8[fontSize];
- fontFile->read(_charData, fontSize);
-
- _vm->res()->toss(filename);
-}
-
-void Font::setFontMads(const char *filename) {
- MadsPack fontData(filename, _vm);
- Common::SeekableReadStream *fontFile = fontData.getItemStream(0);
-
- _maxHeight = fontFile->readByte();
- _maxWidth = fontFile->readByte();
-
- _charWidths = new uint8[128];
- // Char data is shifted by 1
- _charWidths[0] = 0;
- fontFile->read(_charWidths + 1, 127);
- fontFile->readByte(); // remainder
-
- _charOffs = new uint16[128];
-
- uint32 startOffs = 2 + 128 + 256;
- uint32 fontSize = fontFile->size() - startOffs;
-
- // Char data is shifted by 1
- _charOffs[0] = 0;
- for (int i = 1; i < 128; i++)
- _charOffs[i] = fontFile->readUint16LE() - startOffs;
- fontFile->readUint16LE(); // remainder
-
- _charData = new uint8[fontSize];
- fontFile->read(_charData, fontSize);
-
- delete fontFile;
-}
-
-Font::~Font() {
- if (!_sysFont) {
- delete[] _charWidths;
- delete[] _charOffs;
- delete[] _charData;
- }
-}
-
-void Font::setColor(uint8 color) {
- if (_sysFont)
- _fontColors[1] = color;
- else
- _fontColors[3] = color;
-}
-
-void Font::setColors(uint8 col1, uint8 col2, uint8 col3) {
- if (_sysFont)
- _fontColors[1] = col3;
- else {
- _fontColors[0] = 0xFF;
- _fontColors[1] = col1;
- _fontColors[2] = col2;
- _fontColors[3] = col3;
- }
-}
-
-int32 Font::write(M4Surface *surface, const char *text, int x, int y, int width, int spaceWidth, uint8 colors[]) {
-
- /*TODO
- if (custom_ascii_converter) { // if there is a function to convert the extended ASCII characters
- custom_ascii_converter(out_string); // call it with the string
- }
- */
-
- int right;
- if (width > 0)
- right = MIN(surface->width(), x + width + 1);
- else
- right = surface->width();
-
- x++;
- y++;
-
- int skipY = 0;
- if (y < 0) {
- skipY = -y;
- y = 0;
- }
-
- int height = MAX(0, _maxHeight - skipY);
- if (height == 0)
- return x;
-
- int bottom = y + height - 1;
- if (bottom > surface->height() - 1) {
- height -= MIN(height, bottom - (surface->height() - 1));
- }
-
- if (height <= 0)
- return x;
-
- uint8 *destPtr = (uint8*)surface->getBasePtr(x, y);
- uint8 *oldDestPtr = destPtr;
-
- int xPos = x;
-
- while (*text) {
-
- unsigned char theChar = (*text++) & 0x7F;
- int charWidth = _charWidths[theChar];
-
- if (charWidth > 0) {
-
- if (xPos + charWidth > right)
- return xPos;
-
- uint8 *charData = &_charData[_charOffs[theChar]];
- int bpp = charWidth / 4 + 1;
-
- if (!_vm->isM4()) {
- if (charWidth > 12)
- bpp = 4;
- else if (charWidth > 8)
- bpp = 3;
- else if (charWidth > 4)
- bpp = 2;
- else
- bpp = 1;
- }
-
- if (skipY != 0)
- charData += bpp * skipY;
-
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < bpp; j++) {
- if (*charData & 0xc0)
- *destPtr = colors[(*charData & 0xc0) >> 6];
- destPtr++;
- if (*charData & 0x30)
- *destPtr = colors[(*charData & 0x30) >> 4];
- destPtr++;
- if (*charData & 0x0C)
- *destPtr = colors[(*charData & 0x0C) >> 2];
- destPtr++;
- if (*charData & 0x03)
- *destPtr = colors[*charData & 0x03];
- destPtr++;
- charData++;
- }
-
- destPtr += surface->width() - bpp * 4;
-
- }
-
- destPtr = oldDestPtr + charWidth + spaceWidth;
- oldDestPtr = destPtr;
-
- }
-
- xPos += charWidth + spaceWidth;
-
- }
-
- surface->freeData();
- return xPos;
-
-}
-
-int32 Font::getWidth(const char *text, int spaceWidth) {
- /*
- if (custom_ascii_converter) { // if there is a function to convert the extended ASCII characters
- custom_ascii_converter(out_string); // call it with the string
- }
- */
- int width = -spaceWidth; // Accomodate final character not needing spacing
- while (*text)
- width += _charWidths[*text++ & 0x7F] + spaceWidth;
- return width;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/font.h b/engines/m4/font.h
deleted file mode 100644
index 5a9c73e5d5..0000000000
--- a/engines/m4/font.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_FONT_H
-#define M4_FONT_H
-
-#include "common/util.h"
-#include "common/endian.h"
-
-#include "m4/graphics.h"
-
-/*
- TODO:
- - make a FontSystem class that creates/manages the fonts
- (similar to FileSystem)
-*/
-
-namespace M4 {
-
-#define FONT_MENU "fontmenu.fnt"
-#define FONT_INTERFACE "fontintr.fnt"
-#define FONT_TINY "small.fnt"
-#define FONT_SMALL "small.fnt"
-#define FONT_MEDIUM "medium.fnt"
-#define FONT_LINE "fontline.fnt"
-#define FONT_CONVERSATION "fontconv.fnt"
-#define FONT_4X6 "4x6pp.fnt"
-#define FONT_5X6 "5x6pp.fnt"
-
-#define FONT_CONVERSATION_MADS "fontconv.ff"
-#define FONT_INTERFACE_MADS "fontintr.ff"
-#define FONT_MAIN_MADS "fontmain.ff"
-#define FONT_MENU_MADS "fontmenu.ff" // Not in Rex (uses bitmap files for menu strings)
-#define FONT_MISC_MADS "fontmisc.ff"
-#define FONT_TELE_MADS "fonttele.ff" // Not in Phantom
-#define FONT_PHAN_MADS "fontphan.ff" // Phantom only
-
-class Font {
-public:
- Font(MadsM4Engine *vm, const char *filename);
- ~Font();
-
- void setColor(uint8 color);
- void setColors(uint8 col1, uint8 col2, uint8 col3);
-
- int32 getWidth(const char *text, int spaceWidth = -1);
- int32 getHeight() const { return _maxHeight; }
- int32 getMaxWidth() const { return _maxWidth; }
- int32 write(M4Surface *surface, const char *text, int x, int y, int width, int spaceWidth, uint8 colors[]);
- int32 writeString(M4Surface *surface, const char *text, int x, int y, int width = 0, int spaceWidth = -1) {
- return write(surface, text, x, y, width, spaceWidth, _fontColors);
- }
-public:
- char _filename[20];
-private:
- void setFontM4(const char *filename);
- void setFontMads(const char *filename);
-
- MadsM4Engine *_vm;
- uint8 _maxWidth, _maxHeight;
- uint8 *_charWidths;
- uint16 *_charOffs;
- uint8 *_charData;
- bool _sysFont;
- uint8 _fontColors[4];
-};
-
-class FontEntry {
-public:
- Font *_font;
-
- FontEntry() {
- _font = NULL;
- }
- ~FontEntry() {
- delete _font;
- }
-};
-
-class FontManager {
-private:
- MadsM4Engine *_vm;
- Common::Array<Font *> _entries;
- Font *_currentFont;
-public:
- FontManager(MadsM4Engine *vm): _vm(vm) { _currentFont = NULL; }
- ~FontManager();
-
- Font *getFont(const char *filename);
- void setFont(const char *filename);
-
- Font *current() {
- assert(_currentFont);
- return _currentFont;
- }
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/globals.cpp b/engines/m4/globals.cpp
deleted file mode 100644
index 7a0b776eb8..0000000000
--- a/engines/m4/globals.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/gui.h"
-#include "m4/viewmgr.h"
-#include "m4/script.h"
-#include "m4/m4_views.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-Kernel::Kernel(MadsM4Engine *vm) : _vm(vm) {
- daemonTriggerAvailable = true;
- firstFadeColorIndex = 0;
- paused = false;
- betweenRooms = false;
- currentSection = 0;
- newSection = 0;
- previousSection = 0;
- currentRoom = 0;
- newRoom = 0;
- previousRoom = 0;
- trigger = 0;
- triggerMode = KT_DAEMON;
-
- _globalDaemonFn = NULL;
- _globalParserFn = NULL;
-
- _sectionInitFn = NULL;
- _sectionDaemonFn = NULL;
- _sectionParserFn = NULL;
-
- _roomInitFn = NULL;
- _roomDaemonFn = NULL;
- _roomPreParserFn = NULL;
- _roomParserFn = NULL;
-
-}
-
-int32 Kernel::createTrigger(int32 triggerNum) {
- if (triggerNum < 0)
- return triggerNum;
- else
- return triggerNum | (currentRoom << 16) | (triggerMode << 28);
-}
-
-bool Kernel::sendTrigger(int32 triggerNum) {
- return handleTrigger(createTrigger(triggerNum));
-}
-
-bool Kernel::handleTrigger(int32 triggerNum) {
-
- debugCN(kDebugScript, "betweenRooms = %d; triggerNum = %08X\n", betweenRooms, (uint)triggerNum);
-
- if (betweenRooms)
- return true;
-
- if (triggerNum < 0)
- return false;
-
- KernelTriggerType saveTriggerMode = triggerMode;
- int32 saveTrigger = trigger;
- bool result = false;
-
- int room = (triggerNum >> 16) & 0xFFF;
-
- debugCN(kDebugScript, "room = %d; currentRoom = %d\n", room, currentRoom);
-
- if (room != currentRoom) {
- debugCN(kDebugScript, "Kernel::handleTrigger() Trigger from another room\n");
- return false;
- }
-
- trigger = triggerNum & 0xFFFF;
- KernelTriggerType mode = (KernelTriggerType)(triggerNum >> 28);
-
- switch (mode) {
-
- case KT_PREPARSE:
- if (trigger < 32000) {
- triggerMode = KT_PREPARSE;
- roomPreParser();
- result = true;
- }
- break;
-
- case KT_PARSE:
- if (trigger < 32000) {
- triggerMode = KT_PARSE;
- // TODO player.commandReady = TRUE;
- roomParser();
- /* TODO
- if (player.commandReady)
- globalParser();
- */
- result = true;
- }
- break;
-
- case KT_DAEMON:
- debugCN(kDebugScript, "KT_DAEMON\n");
- triggerMode = KT_DAEMON;
- daemonTriggerAvailable = false;
- roomDaemon();
- if (daemonTriggerAvailable) {
- daemonTriggerAvailable = false;
- sectionDaemon();
- }
- if (daemonTriggerAvailable) {
- daemonTriggerAvailable = false;
- globalDaemon();
- }
-
- break;
-
- default:
- debugCN(kDebugScript, "Kernel::handleTrigger() Unknown trigger mode %d\n", mode);
-
- }
-
- triggerMode = saveTriggerMode;
- trigger = saveTrigger;
-
- return result;
-}
-
-void Kernel::loadGlobalScriptFunctions() {
- _globalDaemonFn = _vm->_script->loadFunction("global_daemon");
- _globalParserFn = _vm->_script->loadFunction("global_parser");
-}
-
-void Kernel::loadSectionScriptFunctions() {
- Common::String tempFnName;
- tempFnName = Common::String::format("section_init_%d", currentSection);
- _sectionInitFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("section_daemon_%d", currentSection);
- _sectionDaemonFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("section_parser_%d", currentSection);
- _sectionParserFn = _vm->_script->loadFunction(tempFnName);
-}
-
-void Kernel::loadRoomScriptFunctions() {
- Common::String tempFnName;
- tempFnName = Common::String::format("room_init_%d", currentRoom);
- _roomInitFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("room_daemon_%d", currentRoom);
- _roomDaemonFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("room_pre_parser_%d", currentRoom);
- _roomPreParserFn = _vm->_script->loadFunction(tempFnName);
- tempFnName = Common::String::format("room_parser_%d", currentRoom);
- _roomParserFn = _vm->_script->loadFunction(tempFnName);
-}
-
-void Kernel::globalDaemon() {
- if (_globalDaemonFn)
- _vm->_script->runFunction(_globalDaemonFn);
- else {
- debugCN(kDebugScript, "Kernel::globalDaemon() _globalDaemonFn is NULL\n");
- }
-}
-
-void Kernel::globalParser() {
- if (_globalParserFn)
- _vm->_script->runFunction(_globalParserFn);
- else {
- debugCN(kDebugScript, "Kernel::globalParser() _globalParserFn is NULL\n");
- }
-}
-
-void Kernel::sectionInit() {
- if (_sectionInitFn)
- _vm->_script->runFunction(_sectionInitFn);
- else {
- debugCN(kDebugScript, "Kernel::sectionInit() _sectionInitFn is NULL\n");
- }
-}
-
-void Kernel::sectionDaemon() {
- if (_sectionDaemonFn)
- _vm->_script->runFunction(_sectionDaemonFn);
- else {
- debugCN(kDebugScript, "Kernel::sectionDaemon() _sectionDaemonFn is NULL\n");
- }
-}
-
-void Kernel::sectionParser() {
- if (_sectionParserFn)
- _vm->_script->runFunction(_sectionParserFn);
- else {
- debugCN(kDebugScript, "Kernel::sectionParser() _sectionParserFn is NULL\n");
- }
-}
-
-void Kernel::roomInit() {
- if (_roomInitFn)
- _vm->_script->runFunction(_roomInitFn);
- else {
- debugCN(kDebugScript, "Kernel::roomInit() _roomInitFn is NULL\n");
- }
-}
-
-void Kernel::roomDaemon() {
- if (_roomDaemonFn)
- _vm->_script->runFunction(_roomDaemonFn);
- else {
- debugCN(kDebugScript, "Kernel::roomDaemon() _roomDaemonFn is NULL\n");
- }
-}
-
-void Kernel::roomPreParser() {
- if (_roomPreParserFn)
- _vm->_script->runFunction(_roomPreParserFn);
- else {
- debugCN(kDebugScript, "Kernel::roomPreParser() _roomPreParserFn is NULL\n");
- }
-}
-
-void Kernel::roomParser() {
- if (_roomParserFn)
- _vm->_script->runFunction(_roomParserFn);
- else {
- debugCN(kDebugScript, "Kernel::roomParser() _roomParserFn is NULL\n");
- }
-}
-
-void Kernel::pauseGame(bool value) {
- paused = value;
-
- if (paused) pauseEngines();
- else unpauseEngines();
-}
-
-void Kernel::pauseEngines() {
- // TODO: A proper implementation of game pausing. At the moment I'm using a hard-coded
- // check in events.cpp on Kernel::paused to prevent any events going to the scene
-}
-
-void Kernel::unpauseEngines() {
- // TODO: A proper implementation of game unpausing
-}
-
-/*--------------------------------------------------------------------------*/
-
-Globals::Globals(MadsM4Engine *vm): _vm(vm) {
-}
-
-bool Globals::isInterfaceVisible() {
- return _m4Vm->scene()->getInterface()->isVisible();
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsGlobals::MadsGlobals(MadsEngine *vm): Globals(vm) {
- _vm = vm;
-
- playerSpriteChanged = false;
- dialogType = DIALOG_NONE;
- sceneNumber = -1;
- for (int i = 0; i < 3; ++i)
- actionNouns[i] = 0;
- _difficultyLevel = 0;
-}
-
-MadsGlobals::~MadsGlobals() {
- uint32 i;
-
- for (i = 0; i < _madsVocab.size(); i++)
- free(_madsVocab[i]);
- _madsVocab.clear();
-
- for (i = 0; i < _madsQuotes.size(); i++)
- free(_madsQuotes[i]);
- _madsQuotes.clear();
-
- _madsMessages.clear();
-}
-
-void MadsGlobals::loadMadsVocab() {
- Common::SeekableReadStream *vocabS = _vm->res()->get("vocab.dat");
- int curPos = 0;
-
- char buffer[30];
- strcpy(buffer, "");
-
- while (true) {
- uint8 b = vocabS->readByte();
- if (vocabS->eos()) break;
-
- buffer[curPos++] = b;
- if (buffer[curPos - 1] == '\0') {
- // end of string, add it to the strings list
- _madsVocab.push_back(strdup(buffer));
- curPos = 0;
- strcpy(buffer, "");
- }
- }
-
- _vm->res()->toss("vocab.dat");
-}
-
-void MadsGlobals::loadQuotes() {
- Common::SeekableReadStream *quoteS = _vm->res()->get("quotes.dat");
- int curPos = 0;
-
- char buffer[128];
- strcpy(buffer, "");
-
- while (true) {
- uint8 b = quoteS->readByte();
- if (quoteS->eos()) break;
-
- buffer[curPos++] = b;
- if (buffer[curPos - 1] == '\0') {
- // end of string, add it to the strings list
- _madsQuotes.push_back(strdup(buffer));
- curPos = 0;
- strcpy(buffer, "");
- }
- }
-
- _vm->res()->toss("quotes.dat");
-}
-
-void MadsGlobals::loadMadsMessagesInfo() {
- Common::SeekableReadStream *messageS = _vm->res()->get("messages.dat");
-
- int16 count = messageS->readUint16LE();
- //debugCN(kDebugScript, "%i messages\n", count);
-
- for (int i = 0; i < count; i++) {
- MessageItem curMessage;
- curMessage.id = messageS->readUint32LE();
- curMessage.offset = messageS->readUint32LE();
- curMessage.uncompSize = messageS->readUint16LE();
-
- if (i > 0)
- _madsMessages[i - 1].compSize = curMessage.offset - _madsMessages[i - 1].offset;
-
- if (i == count - 1)
- curMessage.compSize = messageS->size() - curMessage.offset;
-
- //debugCN(kDebugScript, "id: %i, offset: %i, uncomp size: %i\n", curMessage->id, curMessage->offset, curMessage->uncompSize);
- _madsMessages.push_back(curMessage);
- }
-
- _vm->res()->toss("messages.dat");
-}
-
-void MadsGlobals::loadMadsObjects() {
- Common::SeekableReadStream *objList = _vm->res()->get("objects.dat");
- int numObjects = objList->readUint16LE();
-
- for (int i = 0; i < numObjects; ++i)
- _madsObjects.push_back(MadsObjectArray::value_type(new MadsObject(objList)));
-
- _vm->res()->toss("objects.dat");
-}
-
-int MadsGlobals::getObjectIndex(uint16 descId) {
- for (uint i = 0; i < _madsObjects.size(); ++i) {
- if (_madsObjects[i].get()->_descId == descId)
- return i;
- }
-
- return -1;
-}
-
-int MadsGlobals::messageIndexOf(uint32 messageId) {
- for (uint i = 0; i < _madsMessages.size(); ++i)
- {
- if (_madsMessages[i].id == messageId)
- return i;
- }
- return -1;
-}
-
-const char *MadsGlobals::loadMessage(uint index) {
- if (index > _madsMessages.size() - 1) {
- warning("Invalid message index: %i", index);
- return NULL;
- }
-
- FabDecompressor fab;
- byte *compData = new byte[_madsMessages[index].compSize];
- byte *buffer = new byte[_madsMessages[index].uncompSize];
-
- Common::SeekableReadStream *messageS = _vm->res()->get("messages.dat");
- messageS->seek(_madsMessages[index].offset, SEEK_SET);
- messageS->read(compData, _madsMessages[index].compSize);
- fab.decompress(compData, _madsMessages[index].compSize, buffer, _madsMessages[index].uncompSize);
-
- for (int i = 0; i < _madsMessages[index].uncompSize - 1; i++)
- if (buffer[i] == '\0') buffer[i] = '\n';
-
- _vm->res()->toss("messages.dat");
- delete[] compData;
-
- return (char*)buffer;
-}
-
-/**
- * Adds the specified scene number to list of scenes previously visited
- */
-void MadsGlobals::addVisitedScene(int newSceneNumber) {
- if (!isSceneVisited(newSceneNumber))
- _visitedScenes.push_back(newSceneNumber);
-}
-
-/**
- * Returns true if the specified scene has been previously visited
- */
-bool MadsGlobals::isSceneVisited(int checkSceneNumber) {
- Common::List<int>::iterator i;
- for (i = _visitedScenes.begin(); i != _visitedScenes.end(); ++i)
- if (*i == checkSceneNumber)
- return true;
- return false;
-}
-
-void MadsGlobals::removeVisitedScene(int oldSceneNumber) {
- _visitedScenes.remove(oldSceneNumber);
-}
-
-/*--------------------------------------------------------------------------*/
-
-M4Globals::M4Globals(M4Engine *vm): Globals(vm) {
- _vm = vm;
-}
-
-/*--------------------------------------------------------------------------*/
-
-Player::Player(MadsM4Engine *vm) : _vm(vm) {
- commandsAllowed = true;
- needToWalk = false;
- readyToWalk = false;
- waitingForWalk = false;
- commandReady = false;
- strcpy(verb, "");
- strcpy(noun, "");
- strcpy(prep, "");
- strcpy(object, "");
-}
-
-void Player::setCommandsAllowed(bool value) {
- setCommandsAllowedFlag = true;
- commandsAllowed = value;
- if (value) {
- // Player commands are enabled again
- _vm->_mouse->lockCursor(CURSOR_ARROW);
- //_m4Vm->scene()->getInterface()->cancelSentence();
- } else {
- // Player commands are disabled, so show hourglass cursor
- _vm->_mouse->lockCursor(CURSOR_HOURGLASS);
- }
-}
-
-bool Player::said(const char *word1, const char *word2, const char *word3) {
- const char *words[3];
- words[0] = word1;
- words[1] = word2;
- words[2] = word2;
- for (int i = 0; i < 3; i++) {
- if (words[i])
- if ((scumm_stricmp(noun, words[i])) &&
- (scumm_stricmp(object, words[i])) &&
- (scumm_stricmp(verb, words[i])))
- return false;
- }
- return true;
-}
-
-bool Player::saidAny(const char *word1, const char *word2, const char *word3,
- const char *word4, const char *word5, const char *word6, const char *word7,
- const char *word8, const char *word9, const char *word10) {
- const char *words[10];
- words[0] = word1;
- words[1] = word2;
- words[2] = word3;
- words[3] = word4;
- words[4] = word5;
- words[5] = word6;
- words[6] = word7;
- words[7] = word8;
- words[8] = word9;
- words[9] = word10;
- for (int i = 0; i < 10; i++) {
- if (words[i]) {
- if (!scumm_stricmp(noun, words[i]))
- return true;
- if (!scumm_stricmp(object, words[i]))
- return true;
- if (!scumm_stricmp(verb, words[i]))
- return true;
- }
- }
- return false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsObject::MadsObject(Common::SeekableReadStream *stream) {
- load(stream);
-}
-
-void MadsObject::load(Common::SeekableReadStream *stream) {
- // Get the next data block
- uint8 obj[0x30];
- stream->read(obj, 0x30);
-
- // Extract object data fields
- _descId = READ_LE_UINT16(&obj[0]);
- _roomNumber = READ_LE_UINT16(&obj[2]);
- _article = (MADSArticles)obj[4];
- _vocabCount = obj[5] & 0x7f;
- // Phantom / Dragon
- if (_vocabCount > 3)
- warning("MadsObject::load(), vocab cound > 3 (it's %d)", _vocabCount);
-
- for (int i = 0; i < _vocabCount; ++i) {
- _vocabList[i].flags1 = obj[6 + i * 4];
- _vocabList[i].flags2 = obj[7 + i * 4];
- _vocabList[i].vocabId = READ_LE_UINT16(&obj[8 + i * 4]);
- }
-}
-
-void MadsObject::setRoom(int roomNumber) {
-
-}
-
-} // End of namespace M4
diff --git a/engines/m4/globals.h b/engines/m4/globals.h
deleted file mode 100644
index 693dc9d6c9..0000000000
--- a/engines/m4/globals.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_GLOBALS_H
-#define M4_GLOBALS_H
-
-#include "common/scummsys.h"
-#include "common/array.h"
-#include "common/hashmap.h"
-#include "common/rect.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-namespace Common {
-class SeekableReadStream;
-}
-
-namespace M4 {
-
-class MadsM4Engine;
-class M4Engine;
-class MadsEngine;
-class ScriptInterpreter;
-class ScriptFunction;
-
-// Globals
-enum WoodScriptGlobals {
- kGlobTime = 0,
- kGlobTimeDelta = 1,
- kGlobMinY = 2,
- kGlobMaxY = 3,
- kGlobMinScale = 4,
- kGlobMaxScale = 5,
- kGlobScaler = 6,
- kGlobTemp1 = 7,
- kGlobTemp2 = 8,
- kGlobTemp3 = 9,
- kGlobTemp4 = 10,
- kGlobTemp5 = 11,
- kGlobTemp6 = 12,
- kGlobTemp7 = 13,
- kGlobTemp8 = 14,
- kGlobTemp9 = 15,
- kGlobTemp10 = 16,
- kGlobTemp11 = 17,
- kGlobTemp12 = 18,
- kGlobTemp13 = 19,
- kGlobTemp14 = 20,
- kGlobTemp15 = 21,
- kGlobTemp16 = 22,
- kGlobTemp17 = 23,
- kGlobTemp18 = 24,
- kGlobTemp19 = 25,
- kGlobTemp20 = 26,
- kGlobTemp21 = 27,
- kGlobTemp22 = 28,
- kGlobTemp23 = 29,
- kGlobTemp24 = 30,
- kGlobTemp25 = 31,
- kGlobTemp26 = 32,
- kGlobTemp27 = 33,
- kGlobTemp28 = 34,
- kGlobTemp29 = 35,
- kGlobTemp30 = 36,
- kGlobTemp31 = 37,
- kGlobTemp32 = 38
-};
-
-const uint32 SERIES_FORWARD = 0;
-const uint32 SERIES_PINGPONG = 1;
-const uint32 SERIES_BACKWARD = 2;
-const uint32 SERIES_RANDOM = 4;
-const uint32 SERIES_NO_TOSS = 8;
-const uint32 SERIES_STICK = 16;
-const uint32 SERIES_LOOP_TRIGGER = 32;
-const uint32 SERIES_LOAD_PALETTE = 64;
-const uint32 SERIES_HORZ_FLIP =128;
-
-enum KernelTriggerType {
- KT_PARSE = 1,
- KT_DAEMON,
- KT_PREPARSE
-};
-
-class Kernel {
-private:
- MadsM4Engine *_vm;
- ScriptFunction *_globalDaemonFn, *_globalParserFn;
- ScriptFunction *_sectionInitFn, *_sectionDaemonFn, *_sectionParserFn;
- ScriptFunction *_roomInitFn, *_roomDaemonFn, *_roomPreParserFn, *_roomParserFn;
- void pauseEngines();
- void unpauseEngines();
-public:
- Kernel(MadsM4Engine *vm);
-
- // TODO: Move to some palette/fading class
- int fadeUpDuration, firstFadeColorIndex;
- int minPalEntry, maxPalEntry;
-
- bool paused;
- //machine* myWalker;
- bool repeatedlyCallDeamon;
- bool daemonTriggerAvailable;
- bool betweenRooms;
- int currentSection, newSection, previousSection;
- int currentRoom, newRoom, previousRoom;
-
- int32 trigger;
- KernelTriggerType triggerMode;
-
- int32 createTrigger(int32 triggerNum);
- bool sendTrigger(int32 triggerNum);
- bool handleTrigger(int32 triggerNum);
-
- void loadGlobalScriptFunctions();
- void loadSectionScriptFunctions();
- void loadRoomScriptFunctions();
-
- void globalDaemon();
- void globalParser();
-
- void sectionInit();
- void sectionDaemon();
- void sectionParser();
-
- void roomInit();
- void roomDaemon();
- void roomPreParser();
- void roomParser();
-
- void pauseGame(bool value);
-};
-
-#define TOTAL_NUM_VARIABLES 210
-
-#define PLAYER_INVENTORY 2
-
-enum MADSArticles {
- kArticleNone = 0,
- kArticleWith = 1,
- kArticleTo = 2,
- kArticleAt = 3,
- kArticleFrom = 4,
- kArticleOn = 5,
- kArticleIn = 6,
- kArticleUnder = 7,
- kArticleBehind = 8
-};
-
-struct VocabEntry {
- uint8 flags1;
- uint8 flags2;
- uint16 vocabId;
-};
-
-class MadsObject {
-public:
- MadsObject() {}
- MadsObject(Common::SeekableReadStream *stream);
- void load(Common::SeekableReadStream *stream);
- bool isInInventory() const { return _roomNumber == PLAYER_INVENTORY; }
- void setRoom(int roomNumber);
-
- uint16 _descId;
- uint16 _roomNumber;
- MADSArticles _article;
- uint8 _vocabCount;
- VocabEntry _vocabList[3];
-};
-
-typedef Common::Array<Common::SharedPtr<MadsObject> > MadsObjectArray;
-
-class Globals {
-private:
- MadsM4Engine *_vm;
-public:
- Globals(MadsM4Engine *vm);
- virtual ~Globals() {}
-
- bool isInterfaceVisible();
-
-};
-
-class M4Globals : public Globals {
-private:
- M4Engine *_vm;
-public:
- M4Globals(M4Engine *vm);
- virtual ~M4Globals() {}
-
- bool invSuppressClickSound;
-};
-
-enum RexPlayerSex { SEX_MALE = 0, SEX_FEMALE = 2, SEX_UNKNOWN = 1};
-
-enum MadsDialogType { DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3, DIALOG_OPTIONS = 4,
- DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6};
-
-struct MadsConfigData {
- bool musicFlag;
- bool soundFlag;
- bool easyMouse;
- bool invObjectsStill;
- bool textWindowStill;
- int storyMode;
- int screenFades;
-};
-
-#define GET_GLOBAL(x) (_madsVm->globals()->_globals[x])
-#define GET_GLOBAL32(x) (((uint32)_madsVm->globals()->_globals[x + 1] << 16) | _madsVm->globals()->_globals[x])
-#define SET_GLOBAL(x,y) _madsVm->globals()->_globals[x] = y
-#define SET_GLOBAL32(x,y) { _madsVm->globals()->_globals[x] = (y) & 0xffff; _madsVm->globals()->_globals[(x) + 1] = (y) >> 16; }
-
-typedef int (*IntFunctionPtr)();
-
-union DataMapEntry {
- bool *boolValue;
- uint16 *uint16Value;
- int *intValue;
- IntFunctionPtr fnPtr;
-};
-
-typedef Common::HashMap<uint16, uint16> DataMapHash;
-
-class MadsGlobals : public Globals {
-private:
- struct MessageItem {
- uint32 id;
- uint32 offset;
- uint16 uncompSize;
- uint16 compSize;
- };
-
- MadsEngine *_vm;
- Common::Array<char* > _madsVocab;
- Common::Array<char* > _madsQuotes;
- Common::Array<MessageItem> _madsMessages;
- MadsObjectArray _madsObjects;
- Common::List<int> _visitedScenes;
-public:
- MadsGlobals(MadsEngine *vm);
- ~MadsGlobals();
-
- // MADS variables
- uint16 _globals[TOTAL_NUM_VARIABLES];
- MadsConfigData _config;
- bool playerSpriteChanged;
- MadsDialogType dialogType;
- int sceneNumber;
- int previousScene;
- int16 _nextSceneId;
- uint16 actionNouns[3];
- DataMapHash _dataMap;
- int _difficultyLevel;
-
- void loadMadsVocab();
- uint32 getVocabSize() { return _madsVocab.size(); }
- const char *getVocab(uint32 index) {
- // Vocab list is 1-based, so always subtract one from index provided
- assert((index > 0) && (index <= _madsVocab.size()));
- return _madsVocab[index - 1];
- }
-
- void loadQuotes();
- uint32 getQuotesSize() { return _madsQuotes.size(); }
- const char *getQuote(uint32 index) { return _madsQuotes[index - 1]; }
- // DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs
- void clearQuotes() {}
- void loadQuoteRange(int startNum, int endNum) {}
- void loadQuoteSet(...) {}
- void loadQuote(int quoteNum) {}
-
- void loadMadsMessagesInfo();
- uint32 getMessagesSize() { return _madsMessages.size(); }
- int messageIndexOf(uint32 messageId);
- const char *loadMessage(uint index);
-
- void loadMadsObjects();
- uint32 getObjectsSize() { return _madsObjects.size(); }
- MadsObject *getObject(uint32 index) { return _madsObjects[index].get(); }
- int getObjectIndex(uint16 descId);
- int getObjectFolder(uint32 folderId) { warning("TODO: getObjectFolder"); return -1; }
-
- void addVisitedScene(int sceneNumber);
- bool isSceneVisited(int sceneNumber);
- void removeVisitedScene(int sceneNumber);
-};
-
-#define PLAYER_FIELD_LENGTH 40
-
-class Player {
-public:
- Player(MadsM4Engine *vm);
- void setCommandsAllowed(bool value);
-
- // Variables
- Common::Point position; // Player's current position
- int facing; // Facing direction
-
- char verb[PLAYER_FIELD_LENGTH]; // Action strings
- char noun[PLAYER_FIELD_LENGTH];
- char prep[PLAYER_FIELD_LENGTH];
- char object[PLAYER_FIELD_LENGTH];
- Common::String assetName, shadowName;
- int walkerType, shadowType;
- bool needToWalk, readyToWalk, waitingForWalk;
- bool commandsAllowed;
- bool commandReady;
- bool visible;
- bool beenInRoomBefore;
- bool walkerInCurrentRoom;
- int32 walkerTriggerNum;
- int walkFacing;
- bool setCommandsAllowedFlag;
-
- bool said(const char *word1, const char *word2 = NULL, const char *word3 = NULL);
- bool saidAny(const char *word1, const char *word2, const char *word3,
- const char *word4, const char *word5, const char *word6, const char *word7,
- const char *word8, const char *word9, const char *word10);
-
-private:
- MadsM4Engine *_vm;
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp
deleted file mode 100644
index 99130aee08..0000000000
--- a/engines/m4/graphics.cpp
+++ /dev/null
@@ -1,1361 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/util.h"
-#include "common/ptr.h"
-#include "common/textconsole.h"
-
-#include "graphics/palette.h"
-
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/sprite.h"
-#include "m4/m4.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-RGBList::RGBList(int numEntries, RGB8 *srcData, bool freeData) {
- _size = numEntries;
- assert(numEntries <= 256);
-
- if (srcData == NULL) {
- _data = new RGB8[numEntries];
- _freeData = true;
- } else {
- _data = srcData;
- _freeData = freeData;
- }
-
- _palIndexes = new byte[numEntries];
- Common::fill(&_palIndexes[0], &_palIndexes[numEntries], 0);
-}
-
-RGBList::~RGBList() {
- if (_freeData)
- delete[] _data;
- delete[] _palIndexes;
-}
-
-void RGBList::setRange(int start, int count, const RGB8 *src) {
- assert((start + count) <= _size);
-
- Common::copy(&src[0], &src[count], &_data[start]);
-}
-
-/**
- * Creates a duplicate of the given rgb list
- */
-RGBList *RGBList::clone() const {
- RGBList *dest = new RGBList(_size, _data, false);
- _madsVm->_palette->addRange(dest);
- return dest;
-}
-
-//--------------------------------------------------------------------------
-
-#define VGA_COLOR_TRANS(x) (x == 0x3f ? 255 : x << 2)
-
-M4Surface::~M4Surface() {
- if (_rgbList) {
- _madsVm->_palette->deleteRange(_rgbList);
- delete _rgbList;
- }
- if (_ownsData)
- free();
-}
-
-void M4Surface::loadCodesM4(Common::SeekableReadStream *source) {
- if (!source) {
- free();
- return;
- }
-
- uint16 widthVal = source->readUint16LE();
- uint16 heightVal = source->readUint16LE();
-
- create(widthVal, heightVal, Graphics::PixelFormat::createFormatCLUT8());
- source->read(pixels, widthVal * heightVal);
-}
-
-void M4Surface::loadCodesMads(Common::SeekableReadStream *source) {
- if (!source) {
- free();
- return;
- }
-
- uint16 widthVal = 320;
- uint16 heightVal = 156;
- byte *walkMap = new byte[source->size()];
-
- create(widthVal, heightVal, Graphics::PixelFormat::createFormatCLUT8());
- source->read(walkMap, source->size());
-
- byte *ptr = (byte *)getBasePtr(0, 0);
-
- for (int y = 0; y < heightVal; y++) {
- for (int x = 0; x < widthVal; x++) {
- int ofs = x + (y * widthVal);
- if ((walkMap[ofs / 8] << (ofs % 8)) & 0x80)
- *ptr++ = 1; // walkable
- else
- *ptr++ = 0;
- }
- }
-
- delete[] walkMap;
-}
-
-// Sprite related methods
-
-void M4Surface::vLine(int x, int y1, int y2) {
- Graphics::Surface::vLine(x, y1, y2, _color);
-}
-
-void M4Surface::hLine(int x1, int x2, int y) {
- Graphics::Surface::hLine(x1, y, x2, _color);
-}
-
-void M4Surface::vLineXor(int x, int y1, int y2) {
- // Clipping
- if (x < 0 || x >= w)
- return;
-
- if (y2 < y1)
- SWAP(y2, y1);
-
- if (y1 < 0)
- y1 = 0;
- if (y2 >= h)
- y2 = h - 1;
-
- byte *ptr = (byte *)getBasePtr(x, y1);
- while (y1++ <= y2) {
- *ptr ^= 0xFF;
- ptr += pitch;
- }
-
-}
-
-void M4Surface::hLineXor(int x1, int x2, int y) {
- // Clipping
- if (y < 0 || y >= h)
- return;
-
- if (x2 < x1)
- SWAP(x2, x1);
-
- if (x1 < 0)
- x1 = 0;
- if (x2 >= w)
- x2 = w - 1;
-
- if (x2 < x1)
- return;
-
- byte *ptr = (byte *)getBasePtr(x1, y);
- while (x1++ <= x2)
- *ptr++ ^= 0xFF;
-
-}
-
-void M4Surface::drawLine(int x1, int y1, int x2, int y2, byte color) {
- Graphics::Surface::drawLine(x1, y1, x2, y2, color);
-}
-
-
-void M4Surface::frameRect(int x1, int y1, int x2, int y2) {
- Graphics::Surface::frameRect(Common::Rect(x1, y1, x2, y2), _color);
-}
-
-void M4Surface::fillRect(int x1, int y1, int x2, int y2) {
- Graphics::Surface::fillRect(Common::Rect(x1, y1, x2, y2), _color);
-}
-
-void M4Surface::drawSprite(int x, int y, SpriteInfo &info, const Common::Rect &clipRect) {
-
- enum {
- kStatusSkip,
- kStatusScale,
- kStatusDraw
- };
-
- // NOTE: The current clipping code assumes that the top left corner of the clip
- // rectangle is always 0, 0
- assert(clipRect.top == 0 && clipRect.left == 0);
-
- // TODO: Put err* and scaled* into SpriteInfo
- int errX = info.hotX * info.scaleX % 100;
- int errY = info.hotY * info.scaleY % 100;
- int scaledWidth = scaleValue(info.width, info.scaleX, errX);
- int scaledHeight = scaleValue(info.height, info.scaleY, errY);
-
- /*
- debugCN(kDebugGraphics, "M4Surface::drawSprite() info.width = %d; info.scaleX = %d; info.height = %d; info.scaleY = %d; scaledWidth = %d; scaledHeight = %d\n",
- info.width, info.scaleX, info.height, info.scaleY, scaledWidth, scaledHeight);
- */
-
- int clipX = 0, clipY = 0;
- // Clip the sprite's width and height according to the clip rectangle's dimensions
- // This clips the sprite to the bottom and right
- if (x >= 0) {
- scaledWidth = MIN<int>(x + scaledWidth, clipRect.right) - x;
- } else {
- clipX = x;
- scaledWidth = x + scaledWidth;
- }
- if (y >= 0) {
- scaledHeight = MIN<int>(y + scaledHeight, clipRect.bottom) - y;
- } else {
- clipY = y;
- scaledHeight = y + scaledHeight;
- }
-
- //debugCN(kDebugGraphics, "M4Surface::drawSprite() width = %d; height = %d; scaledWidth = %d; scaledHeight = %d\n", info.width, info.height, scaledWidth, scaledHeight);
-
- // Check if sprite is inside the screen. If it's not, there's no need to draw it
- if (scaledWidth + x <= 0 || scaledHeight + y <= 0) // check left and top (in case x,y are negative)
- return;
- if (scaledWidth <= 0 || scaledHeight <= 0) // check right and bottom
- return;
- int heightAmt = scaledHeight;
-
- byte *src = info.sprite->getBasePtr();
- byte *dst = getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);
-
- int status = kStatusSkip;
- byte *scaledLineBuf = new byte[scaledWidth];
-
- while (heightAmt > 0) {
-
- if (status == kStatusSkip) {
- // Skip line
- errY -= info.scaleY;
- if (errY < 0)
- status = kStatusScale;
- else
- src += info.width;
- } else {
-
- if (status == kStatusScale) {
- // Scale current line
- byte *lineDst = scaledLineBuf;
- int curErrX = errX;
- int widthVal = scaledWidth;
- byte *tempSrc = src;
- int startX = clipX;
- while (widthVal > 0) {
- byte pixel = *tempSrc++;
- curErrX -= info.scaleX;
- while (curErrX < 0) {
- if (startX == 0) {
- *lineDst++ = pixel;
- widthVal--;
- } else {
- startX++;
- }
- curErrX += 100;
- }
- }
- src += info.width;
- status = kStatusDraw;
- }
-
- if (status == kStatusDraw && clipY == 0) {
- // Draw previously scaled line
- // TODO Implement different drawing types (depth, shadow etc.)
- byte *tempDst = dst;
- for (int lineX = 0; lineX < scaledWidth; lineX++) {
- byte pixel = scaledLineBuf[lineX];
-
- if (info.encoding & 0x80) {
-
- if (pixel == 0x80) {
- pixel = 0;
- } else {
- byte destPixel = *tempDst;
- byte r, g, b;
- r = CLIP((info.palette[destPixel].r * pixel) >> 10, 0, 31);
- g = CLIP((info.palette[destPixel].g * pixel) >> 10, 0, 31);
- b = CLIP((info.palette[destPixel].b * pixel) >> 10, 0, 31);
- pixel = info.inverseColorTable[(b << 10) | (g << 5) | r];
- }
- }
-
- if (pixel)
- *tempDst = pixel;
-
- tempDst++;
- }
- dst += pitch;
- heightAmt--;
- // TODO depth etc.
- //depthAddress += Destination -> Width;
-
- errY += 100;
- if (errY >= 0)
- status = kStatusSkip;
- } else if (status == kStatusDraw && clipY < 0) {
- clipY++;
-
- errY += 100;
- if (errY >= 0)
- status = kStatusSkip;
- }
-
- }
-
- }
-
- delete[] scaledLineBuf;
-
-}
-
-// Surface methods
-
-void M4Surface::freeData() {
-}
-
-void M4Surface::clear() {
- Common::fill((byte *)pixels, (byte *)pixels + w * h, _vm->_palette->BLACK);
-}
-
-void M4Surface::reset() {
- ::free(pixels);
- pixels = NULL;
- if (_rgbList) {
- _vm->_palette->deleteRange(_rgbList);
- delete _rgbList;
- _rgbList = NULL;
- }
-}
-
-void M4Surface::frameRect(const Common::Rect &r, uint8 color) {
- Graphics::Surface::frameRect(r, color);
-}
-
-void M4Surface::fillRect(const Common::Rect &r, uint8 color) {
- Graphics::Surface::fillRect(r, color);
-}
-
-void M4Surface::copyFrom(M4Surface *src, const Common::Rect &srcBounds, int destX, int destY,
- int transparentColor) {
- // Validation of the rectangle and position
- if ((destX >= w) || (destY >= h))
- return;
-
- Common::Rect copyRect = srcBounds;
- if (destX < 0) {
- copyRect.left += -destX;
- destX = 0;
- } else if (destX + copyRect.width() > w) {
- copyRect.right -= destX + copyRect.width() - w;
- }
- if (destY < 0) {
- copyRect.top += -destY;
- destY = 0;
- } else if (destY + copyRect.height() > h) {
- copyRect.bottom -= destY + copyRect.height() - h;
- }
-
- if (!copyRect.isValidRect())
- return;
-
- // Copy the specified area
-
- byte *data = src->getBasePtr();
- byte *srcPtr = data + (src->width() * copyRect.top + copyRect.left);
- byte *destPtr = (byte *)pixels + (destY * width()) + destX;
-
- for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
- if (transparentColor == -1)
- // No transparency, so copy line over
- Common::copy(srcPtr, srcPtr + copyRect.width(), destPtr);
- else {
- // Copy each byte one at a time checking for the transparency color
- for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr)
- if (srcPtr[xCtr] != transparentColor) destPtr[xCtr] = srcPtr[xCtr];
- }
-
- srcPtr += src->width();
- destPtr += width();
- }
-
- src->freeData();
-}
-
-/**
- * Copies a given image onto a destination surface with scaling, transferring only pixels that meet
- * the specified depth requirement on a secondary surface contain depth information
- */
-void M4Surface::copyFrom(M4Surface *src, int destX, int destY, int depth,
- M4Surface *depthsSurface, int scale, int transparentColor) {
-
- if (scale == 100) {
- // Copy the specified area
- Common::Rect copyRect(0, 0, src->width(), src->height());
-
- if (destX < 0) {
- copyRect.left += -destX;
- destX = 0;
- } else if (destX + copyRect.width() > w) {
- copyRect.right -= destX + copyRect.width() - w;
- }
- if (destY < 0) {
- copyRect.top += -destY;
- destY = 0;
- } else if (destY + copyRect.height() > h) {
- copyRect.bottom -= destY + copyRect.height() - h;
- }
-
- if (!copyRect.isValidRect())
- return;
-
- byte *data = src->getBasePtr();
- byte *srcPtr = data + (src->width() * copyRect.top + copyRect.left);
- byte *depthsData = depthsSurface->getBasePtr();
- byte *depthsPtr = depthsData + (depthsSurface->pitch * destY) + destX;
- byte *destPtr = (byte *)pixels + (destY * pitch) + destX;
-
- // 100% scaling variation
- for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
- // Copy each byte one at a time checking against the depth
- for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr) {
- if ((depth <= (depthsPtr[xCtr] & 0x7f)) && (srcPtr[xCtr] != transparentColor))
- destPtr[xCtr] = srcPtr[xCtr];
- }
-
- srcPtr += src->width();
- depthsPtr += depthsSurface->width();
- destPtr += width();
- }
-
- src->freeData();
- depthsSurface->freeData();
- return;
- }
-
- // Start of draw logic for scaled sprites
- const byte *srcPixelsP = src->getBasePtr();
-
- int destRight = this->width() - 1;
- int destBottom = this->height() - 1;
- bool normalFrame = true; // TODO: false for negative frame numbers
- int frameWidth = src->width();
- int frameHeight = src->height();
-
- int highestDim = MAX(frameWidth, frameHeight);
- bool lineDist[MADS_SURFACE_WIDTH];
- int distIndex = 0;
- int distXCount = 0, distYCount = 0;
-
- int distCtr = 0;
- do {
- distCtr += scale;
- if (distCtr < 100) {
- lineDist[distIndex] = false;
- } else {
- lineDist[distIndex] = true;
- distCtr -= 100;
-
- if (distIndex < frameWidth)
- ++distXCount;
-
- if (distIndex < frameHeight)
- ++distYCount;
- }
- } while (++distIndex < highestDim);
-
- destX -= distXCount / 2;
- destY -= distYCount - 1;
-
- // Check x bounding area
- int spriteLeft = 0;
- int spriteWidth = distXCount;
- int widthAmount = destX + distXCount - 1;
-
- if (destX < 0) {
- spriteWidth += destX;
- spriteLeft -= destX;
- }
- widthAmount -= destRight;
- if (widthAmount > 0)
- spriteWidth -= widthAmount;
-
- int spriteRight = spriteLeft + spriteWidth;
- if (spriteWidth <= 0)
- return;
- if (!normalFrame) {
- destX += distXCount - 1;
- spriteLeft = -(distXCount - spriteRight);
- spriteRight = (-spriteLeft + spriteWidth);
- }
-
- // Check y bounding area
- int spriteTop = 0;
- int spriteHeight = distYCount;
- int heightAmount = destY + distYCount - 1;
-
- if (destY < 0) {
- spriteHeight += destY;
- spriteTop -= destY;
- }
- heightAmount -= destBottom;
- if (heightAmount > 0)
- spriteHeight -= heightAmount;
- int spriteBottom = spriteTop + spriteHeight;
-
- if (spriteHeight <= 0)
- return;
-
- byte *destPixelsP = this->getBasePtr(destX + spriteLeft, destY + spriteTop);
- const byte *depthPixelsP = depthsSurface->getBasePtr(destX + spriteLeft, destY + spriteTop);
-
- spriteLeft = (spriteLeft * (normalFrame ? 1 : -1));
-
- // Loop through the lines of the sprite
- for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src->pitch) {
- if (!lineDist[yp])
- // Not a display line, so skip it
- continue;
- // Check whether the sprite line is in the display range
- ++sprY;
- if ((sprY >= spriteBottom) || (sprY < spriteTop))
- continue;
-
- // Found a line to display. Loop through the pixels
- const byte *srcP = srcPixelsP;
- const byte *depthP = depthPixelsP;
- byte *destP = destPixelsP;
- for (int xp = 0, sprX = 0; xp < frameWidth; ++xp, ++srcP) {
- if (xp < spriteLeft)
- // Not yet reached start of display area
- continue;
- if (!lineDist[sprX++])
- // Not a display pixel
- continue;
-
- if ((*srcP != transparentColor) && (depth <= (*depthP & 0x7f)))
- *destP = *srcP;
-
- ++destP;
- ++depthP;
- }
-
- // Move to the next destination line
- destPixelsP += this->pitch;
- depthPixelsP += depthsSurface->pitch;
- }
-
- src->freeData();
- depthsSurface->freeData();
- this->freeData();
-}
-
-void M4Surface::loadBackgroundRiddle(const char *sceneName) {
- char resourceName[20];
- Common::SeekableReadStream *stream;
- // Loads a Riddle scene
- sprintf(resourceName, "%s.tt", sceneName);
- stream = _vm->_resourceManager->get(resourceName);
- m4LoadBackground(stream);
- _vm->_resourceManager->toss(resourceName);
-}
-
-void M4Surface::loadBackground(int sceneNumber, RGBList **palData) {
- if (_vm->isM4() || (_vm->getGameType() == GType_RexNebular)) {
- char resourceName[20];
- Common::SeekableReadStream *stream;
-
- if (_vm->getGameType() == GType_RexNebular) {
- // Load Rex Nebular screen
- bool hasPalette = palData != NULL;
- if (!hasPalette)
- palData = &_rgbList;
-
- sprintf(resourceName, "rm%d.art", sceneNumber);
- stream = _vm->_resourceManager->get(resourceName);
- rexLoadBackground(stream, palData);
-
- if (!hasPalette) {
- _vm->_palette->addRange(_rgbList);
- this->translate(_rgbList);
- }
- } else {
- // Loads M4 game scene
- if (palData)
- *palData = NULL;
- sprintf(resourceName, "%i.tt", sceneNumber);
- stream = _vm->_resourceManager->get(resourceName);
- m4LoadBackground(stream);
- }
-
- _vm->_resourceManager->toss(resourceName);
-
- } else {
- madsLoadBackground(sceneNumber, palData);
- }
-}
-
-void M4Surface::madsLoadBackground(int roomNumber, RGBList **palData) {
- // Get a MadsPack reference to the tile set and mapping
- char resourceName[20];
- int i;
-
- // Uncompressed tile map resource
- sprintf(resourceName, "rm%d.mm", roomNumber);
- MadsPack tileMapFile(resourceName, _vm);
- Common::SeekableReadStream *mapStream = tileMapFile.getItemStream(0);
-
- // Get the details of the tiles and map
- mapStream->readUint32LE();
- int tileCountX = mapStream->readUint16LE();
- int tileCountY = mapStream->readUint16LE();
- int tileWidthMap = mapStream->readUint16LE();
- int tileHeightMap = mapStream->readUint16LE();
- int screenWidth = mapStream->readUint16LE();
- int screenHeight = mapStream->readUint16LE();
- int tileCountMap = tileCountX * tileCountY;
- delete mapStream;
-
- // Obtain tile map information
- typedef Common::List<Common::SharedPtr<M4Surface> > TileSetList;
- typedef TileSetList::iterator TileSetIterator;
- TileSetList tileSet;
- uint16 *tileMap = new uint16[tileCountMap];
- mapStream = tileMapFile.getItemStream(1);
- for (i = 0; i < tileCountMap; ++i)
- tileMap[i] = mapStream->readUint16LE();
- delete mapStream;
- _vm->res()->toss(resourceName);
-
- // --------------------------------------------------------------------------------
-
- // Tile map data, which needs to be kept compressed, as the tile offsets refer to
- // the compressed data. Each tile is then uncompressed separately
- sprintf(resourceName, "rm%d.tt", roomNumber);
- Common::SeekableReadStream *tileDataComp = _vm->_resourceManager->get(resourceName);
- MadsPack tileData(tileDataComp);
- Common::SeekableReadStream *tileDataUncomp = tileData.getItemStream(0);
-
- // Validate that the data matches between the tiles and tile map file and is valid
- int tileCount = tileDataUncomp->readUint16LE();
- int tileWidth = tileDataUncomp->readUint16LE();
- int tileHeight = tileDataUncomp->readUint16LE();
- delete tileDataUncomp;
- assert(tileCountMap == tileCount);
- assert(tileWidth == tileWidthMap);
- assert(tileHeight == tileHeightMap);
- assert(screenWidth == _vm->_screen->width());
- assert(screenHeight <= _vm->_screen->height());
-
- // --------------------------------------------------------------------------------
-
- // Get the palette to use
- tileDataUncomp = tileData.getItemStream(2);
- // Set palette
- if (!palData) {
- _vm->_palette->setMadsPalette(tileDataUncomp, 4);
- } else {
- int numColors;
- RGB8 *rgbList = _vm->_palette->decodeMadsPalette(tileDataUncomp, &numColors);
- *palData = new RGBList(numColors, rgbList, true);
- }
- delete tileDataUncomp;
-
- // --------------------------------------------------------------------------------
-
- // Get tile data
-
- tileDataUncomp = tileData.getItemStream(1);
- FabDecompressor fab;
- uint32 compressedTileDataSize = 0;
-
- for (i = 0; i < tileCount; i++) {
- tileDataUncomp->seek(i * 4, SEEK_SET);
- uint32 tileOfs = tileDataUncomp->readUint32LE();
- M4Surface* newTile = new M4Surface(tileWidth, tileHeight);
-
- if (i == tileCount - 1)
- compressedTileDataSize = tileDataComp->size() - tileOfs;
- else
- compressedTileDataSize = tileDataUncomp->readUint32LE() - tileOfs;
-
- //debugCN(kDebugGraphics, "Tile: %i, compressed size: %i\n", i, compressedTileDataSize);
-
- newTile->clear();
-
- byte *compressedTileData = new byte[compressedTileDataSize];
-
- tileDataComp->seek(tileData.getDataOffset() + tileOfs, SEEK_SET);
- tileDataComp->read(compressedTileData, compressedTileDataSize);
-
- fab.decompress(compressedTileData, compressedTileDataSize, (byte*)newTile->pixels, tileWidth * tileHeight);
- tileSet.push_back(TileSetList::value_type(newTile));
- delete[] compressedTileData;
- }
-
- delete tileDataUncomp;
-
- // --------------------------------------------------------------------------------
-
- // Loop through the mapping data to place the tiles on the screen
-
- uint16 *tIndex = &tileMap[0];
- for (int y = 0; y < tileCountY; y++) {
- for (int x = 0; x < tileCountX; x++) {
- int tileIndex = *tIndex++;
- assert(tileIndex < tileCount);
- TileSetIterator tile = tileSet.begin();
- for (i = 0; i < tileIndex; i++)
- ++tile;
- ((*tile).get())->copyTo(this, x * tileWidth, y * tileHeight);
- }
- }
- tileSet.clear();
- _vm->res()->toss(resourceName);
-}
-
-void M4Surface::rexLoadBackground(Common::SeekableReadStream *source, RGBList **palData) {
- MadsPack packData(source);
- Common::SeekableReadStream *sourceUnc = packData.getItemStream(0);
-
- int sceneWidth = sourceUnc->readUint16LE();
- int sceneHeight = sourceUnc->readUint16LE();
- int sceneSize = sceneWidth * sceneHeight;
-
- // Set palette
- if (!palData) {
- _vm->_palette->setMadsPalette(sourceUnc, 4);
- } else {
- int numColors;
- RGB8 *rgbList = _vm->_palette->decodeMadsPalette(sourceUnc, &numColors);
- *palData = new RGBList(numColors, rgbList, true);
- }
- delete sourceUnc;
-
- // Get the raw data for the background
- sourceUnc = packData.getItemStream(1);
- assert((int)sourceUnc->size() >= sceneSize);
-
- create(sceneWidth, sceneHeight, Graphics::PixelFormat::createFormatCLUT8());
- byte *pData = (byte *)pixels;
- sourceUnc->read(pData, sceneSize);
-
- freeData();
- delete sourceUnc;
-}
-
-#undef COL_TRANS
-
-void M4Surface::m4LoadBackground(Common::SeekableReadStream *source) {
- M4Surface *tileBuffer = new M4Surface();
- uint curTileX = 0, curTileY = 0;
- int clipX = 0, clipY = 0;
- RGB8 palette[256];
-
- source->readUint32LE(); // magic, unused
- /*uint32 size =*/ source->readUint32LE();
- uint32 widthVal = source->readUint32LE();
- uint32 heightVal = source->readUint32LE();
- uint32 tilesX = source->readUint32LE();
- uint32 tilesY = source->readUint32LE();
- uint32 tileWidth = source->readUint32LE();
- uint32 tileHeight = source->readUint32LE();
- uint8 blackIndex = 0;
-
- // Debug
- //debugCN(kDebugGraphics, "loadBackground(): %dx%d picture (%d bytes) - %dx%d tiles of size %dx%d\n",
- // widthVal, heightVal, size, tilesX, tilesY, tileWidth, tileHeight);
-
- // BGR data, which is converted to RGB8
- for (uint i = 0; i < 256; i++) {
- palette[i].b = source->readByte() << 2;
- palette[i].g = source->readByte() << 2;
- palette[i].r = source->readByte() << 2;
- // FIXME - Removed u field from RGB8 as the OSystem palette is now RGB.
- // If this is needed, then the system setPalette() call will need changing to skip this.
- uint8 u = source->readByte() << 2;
- if (u != 0)
- debugC(1, kDebugGraphics, "Unused u field in Palette data non-zero: %d", u);
-
- if ((blackIndex == 0) && !palette[i].r && !palette[i].g && !palette[i].b)
- blackIndex = i;
- }
-
- _vm->_palette->setPalette(palette, 0, 256);
-
- // resize or create the surface
- // note that the height of the scene in game scenes is smaller than 480, as the bottom part of the
- // screen is the inventory
- assert(width() == (int)widthVal);
- //debugCN(kDebugGraphics, "width(): %d, widthVal: %d, height(): %d, heightVal: %d\n", width(), widthVal, height(), heightVal);
-
- tileBuffer->create(tileWidth, tileHeight, Graphics::PixelFormat::createFormatCLUT8());
-
- for (curTileY = 0; curTileY < tilesY; curTileY++) {
- clipY = MIN(heightVal, (1 + curTileY) * tileHeight) - (curTileY * tileHeight);
-
- for (curTileX = 0; curTileX < tilesX; curTileX++) {
- clipX = MIN(widthVal, (1 + curTileX) * tileWidth) - (curTileX * tileWidth);
-
- // Read a tile and copy it to the destination surface
- source->read(tileBuffer->pixels, tileWidth * tileHeight);
- Common::Rect srcBounds(0, 0, clipX, clipY);
- copyFrom(tileBuffer, srcBounds, curTileX * tileWidth, curTileY * tileHeight);
- }
- }
-
- if (heightVal < (uint)height())
- fillRect(Common::Rect(0, heightVal, width(), height()), blackIndex);
-
- delete tileBuffer;
-}
-
-void M4Surface::madsLoadInterface(const Common::String &filename) {
- MadsPack intFile(filename.c_str(), _vm);
- RGB8 *palette = new RGB8[16];
-
- // Chunk 0, palette
- Common::SeekableReadStream *intStream = intFile.getItemStream(0);
-
- for (int i = 0; i < 16; i++) {
- palette[i].r = intStream->readByte() << 2;
- palette[i].g = intStream->readByte() << 2;
- palette[i].b = intStream->readByte() << 2;
- intStream->readByte();
- intStream->readByte();
- intStream->readByte();
- }
- _rgbList = new RGBList(16, palette, true);
- delete intStream;
-
- // Chunk 1, data
- intStream = intFile.getItemStream(1);
- create(320, 44, Graphics::PixelFormat::createFormatCLUT8());
- intStream->read(pixels, 320 * 44);
- delete intStream;
-
- // Translate the interface palette
- _vm->_palette->addRange(_rgbList);
- this->translate(_rgbList);
-}
-
-void M4Surface::scrollX(int xAmount) {
- if (xAmount == 0)
- return;
-
- byte buffer[80];
- int direction = (xAmount > 0) ? -1 : 1;
- int xSize = ABS(xAmount);
- assert(xSize <= 80);
-
- byte *srcP = (byte *)getBasePtr(0, 0);
-
- for (int y = 0; y < height(); ++y, srcP += pitch) {
- if (direction < 0) {
- // Copy area to be overwritten
- Common::copy(srcP, srcP + xSize, &buffer[0]);
- // Shift the remainder of the line over the given area
- Common::copy(srcP + xSize, srcP + width(), srcP);
- // Move buffered area to the end of the line
- Common::copy(&buffer[0], &buffer[xSize], srcP + width() - xSize);
- } else {
- // Copy area to be overwritten
- Common::copy_backward(srcP + width() - xSize, srcP + width(), &buffer[80]);
- // Shift the remainder of the line over the given area
- Common::copy_backward(srcP, srcP + width() - xSize, srcP + width());
- // Move buffered area to the start of the line
- Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize);
- }
- }
-}
-
-void M4Surface::scrollY(int yAmount) {
- if (yAmount == 0)
- return;
-
- int direction = (yAmount > 0) ? 1 : -1;
- int ySize = ABS(yAmount);
- assert(ySize < (height() / 2));
- assert(width() == pitch);
-
- int blockSize = ySize * width();
- byte *tempData = (byte *)malloc(blockSize);
- byte *pixelsP = (byte *)getBasePtr(0, 0);
-
- if (direction > 0) {
- // Buffer the lines to be overwritten
- byte *srcP = (byte *)getBasePtr(0, height() - ySize);
- Common::copy(srcP, srcP + (pitch * ySize), tempData);
- // Vertically shift all the lines
- Common::copy_backward(pixelsP, pixelsP + (pitch * (height() - ySize)),
- pixelsP + (pitch * height()));
- // Transfer the buffered lines top the top of the screen
- Common::copy(tempData, tempData + blockSize, pixelsP);
- } else {
- // Buffer the lines to be overwritten
- Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData);
- // Vertically shift all the lines
- Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * height()), pixelsP);
- // Transfer the buffered lines to the bottom of the screen
- Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (height() - ySize)));
- }
-
- ::free(tempData);
-}
-
-
-void M4Surface::translate(RGBList *list, bool isTransparent) {
- byte *p = getBasePtr(0, 0);
- byte *palIndexes = list->palIndexes();
-
- for (int i = 0; i < width() * height(); ++i, ++p) {
- if (!isTransparent || (*p != TRANSPARENT_COLOR_INDEX)) {
- if (*p < list->size())
- *p = palIndexes[*p];
- else
- warning("Pal index %d exceeds list size %d", *p, list->size());
- }
- }
-
- freeData();
-}
-
-M4Surface *M4Surface::flipHorizontal() const {
- M4Surface *dest = new M4Surface(width(), height());
- dest->_rgbList = (this->_rgbList == NULL) ? NULL : this->_rgbList->clone();
-
- byte *destP = dest->getBasePtr();
-
- for (int y = 0; y < height(); ++y) {
- const byte *srcP = getBasePtr(width() - 1, y);
- for (int x = 0; x < width(); ++x)
- *destP++ = *srcP--;
- }
-
- return dest;
-}
-
-//--------------------------------------------------------------------------
-// Palette class
-//
-
-#define GREEN_START 32
-#define NUM_GREENS 32
-#define GREEN_END (GREEN_START + NUM_GREENS - 1)
-#define NORMAL_START 64
-#define NORMAL_END 255
-#define NUM_NORMAL (NORMAL_END - NORMAL_START + 1)
-
-// Support function for creating a list of palette indexes to change entries in the shaded range to
-
-static void makeTranslationList(RGB8 *palData, byte transList[NUM_GREENS]) {
- int i, j, minDistance;
- byte bestIndex;
-
- for (i = 0; i < NUM_GREENS; ++i) {
- bestIndex = NORMAL_START;
- minDistance = 255;
-
- uint8 findCol = palData[GREEN_START + i].g;
-
- // Find the closest matching palette color
- for (j = NORMAL_START; j <= NORMAL_END; ++j) {
- int greenVal = palData[j].g;
- if (ABS(findCol - greenVal) < minDistance) {
- minDistance = ABS(findCol - greenVal);
- bestIndex = j;
- }
-
- if (minDistance == 0)
- break;
- }
-
- transList[i] = bestIndex;
- }
-}
-
-// Support function for fading in or out
-
-static void fadeRange(MadsM4Engine *vm, RGB8 *srcPal, RGB8 *destPal, int startIndex, int endIndex,
- int numSteps, uint delayAmount) {
- RGB8 tempPal[256];
-
- // perform the fade
- for (int stepCtr = 1; stepCtr <= numSteps; ++stepCtr) {
- // Delay the specified amount
- uint32 startTime = g_system->getMillis();
- while ((g_system->getMillis() - startTime) < delayAmount) {
- vm->_events->handleEvents();
- g_system->delayMillis(10);
- }
-
- for (int i = startIndex; i <= endIndex; ++i) {
- // Handle the intermediate rgb values for fading
- tempPal[i].r = (byte) (srcPal[i].r + (destPal[i].r - srcPal[i].r) * stepCtr / numSteps);
- tempPal[i].g = (byte) (srcPal[i].g + (destPal[i].g - srcPal[i].g) * stepCtr / numSteps);
- tempPal[i].b = (byte) (srcPal[i].b + (destPal[i].b - srcPal[i].b) * stepCtr / numSteps);
- }
-
- vm->_palette->setPalette(&tempPal[startIndex], startIndex, endIndex - startIndex + 1);
- vm->_viewManager->refreshAll();
- }
-
- // Make sure the end palette exactly matches what is wanted
- vm->_palette->setPalette(&destPal[startIndex], startIndex, endIndex - startIndex + 1);
-}
-
-Palette::Palette(MadsM4Engine *vm) : _vm(vm) {
- reset();
- _fading_in_progress = false;
- Common::fill(&_usageCount[0], &_usageCount[256], 0);
-}
-
-void Palette::setPalette(const byte *colors, uint start, uint num) {
- g_system->getPaletteManager()->setPalette(colors, start, num);
- reset();
-}
-
-void Palette::setPalette(const RGB8 *colors, uint start, uint num) {
- g_system->getPaletteManager()->setPalette((const byte *)colors, start, num);
- reset();
-}
-
-void Palette::grabPalette(byte *colors, uint start, uint num) {
- g_system->getPaletteManager()->grabPalette(colors, start, num);
-}
-
-void Palette::setEntry(uint index, uint8 r, uint8 g, uint8 b) {
- RGB8 c;
- c.r = r;
- c.g = g;
- c.b = b;
- g_system->getPaletteManager()->setPalette((const byte *)&c, index, 1);
-}
-
-uint8 Palette::palIndexFromRgb(byte r, byte g, byte b, RGB8 *paletteData) {
- byte index = 0;
- int32 minDist = 0x7fffffff;
- RGB8 palData[256];
- int Rdiff, Gdiff, Bdiff;
-
- if (paletteData == NULL) {
- g_system->getPaletteManager()->grabPalette((byte *)palData, 0, 256);
- paletteData = &palData[0];
- }
-
- for (int palIndex = 0; palIndex < 256; ++palIndex) {
- Rdiff = r - paletteData[palIndex].r;
- Gdiff = g - paletteData[palIndex].g;
- Bdiff = b - paletteData[palIndex].b;
-
- if (Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff < minDist) {
- minDist = Rdiff * Rdiff + Gdiff * Gdiff + Bdiff * Bdiff;
- index = (uint8)palIndex;
- }
- }
-
- return (uint8)index;
-}
-
-void Palette::reset() {
- RGB8 palData[256];
- g_system->getPaletteManager()->grabPalette((byte *)palData, 0, 256);
-
- BLACK = palIndexFromRgb(0, 0, 0, palData);
- BLUE = palIndexFromRgb(0, 0, 255, palData);
- GREEN = palIndexFromRgb(0, 255, 0, palData);
- CYAN = palIndexFromRgb(0, 255, 255, palData);
- RED = palIndexFromRgb(255, 0, 0, palData);
- VIOLET = palIndexFromRgb(255, 0, 255, palData);
- BROWN = palIndexFromRgb(168, 84, 84, palData);
- LIGHT_GRAY = palIndexFromRgb(168, 168, 168, palData);
- DARK_GRAY = palIndexFromRgb(84, 84, 84, palData);
- LIGHT_BLUE = palIndexFromRgb(0, 0, 127, palData);
- LIGHT_GREEN = palIndexFromRgb(0, 127, 0, palData);
- LIGHT_CYAN = palIndexFromRgb(0, 127, 127, palData);
- LIGHT_RED = palIndexFromRgb(84, 0, 0, palData);
- PINK = palIndexFromRgb(84, 0, 0, palData);
- YELLOW = palIndexFromRgb(0, 84, 84, palData);
- WHITE = palIndexFromRgb(255, 255, 255, palData);
-}
-
-void Palette::fadeToGreen(int numSteps, uint delayAmount) {
- if (_fading_in_progress)
- return;
- _fading_in_progress = true;
- byte translationList[NUM_GREENS];
-
- int i;
- byte *tempP;
- uint8 greenAmount = 0;
- RGB8 *srcPalette = (RGB8 *) &_originalPalette[0];
- RGB8 *destPalette = (RGB8 *) &_fadedPalette[0];
-
- _vm->_palette->grabPalette(srcPalette, 0, 256);
-
- // Create the destination 'greenish' palette to fade to by setting the green component
- // to the average of the RGB bytes, and leaving the Red and Blue parts as 0
-
- Common::copy(&srcPalette[0], &srcPalette[256], &destPalette[0]);
- for (i = 32; i < 256; ++i) {
- byte luminance = (byte)((destPalette[i].r + destPalette[i].g + destPalette[i].b) / 3);
- destPalette[i].g = MIN((byte)255, luminance);
- destPalette[i].r = destPalette[i].b = 0;
- }
-
- // Handle the actual fading
- fadeRange(_vm, srcPalette, destPalette, 21, 255, numSteps, delayAmount);
-
- // Create a translation table to be used in translating pixels in the game surface
- // using palette indexes in the range the range #32-63 into values from #64-255
-
- makeTranslationList(destPalette, translationList);
-
- // Use palette indexes from #32-63 for the range of possible shades
-
- for (i = GREEN_START; i <= GREEN_END; ++i, greenAmount += 8) {
- destPalette[i].g = greenAmount;
- destPalette[i].r = destPalette[i].b = 0;
- }
-
- // Remap all pixels into the #32-63 range
-
- tempP = _vm->_scene->getBasePtr();
- for (int pixelCtr = 0; pixelCtr < _vm->_scene->width() * _vm->_scene->height();
- ++pixelCtr, ++tempP) {
- // If pixel is in #32-63 range already, remap to higher palette entries
- if ((*tempP >= GREEN_START) && (*tempP <= GREEN_END))
- *tempP = translationList[*tempP - GREEN_START];
-
- *tempP = (uint8) (GREEN_START + (destPalette[*tempP].g >> 3));
- }
-
- _vm->_palette->setPalette(&destPalette[GREEN_START], GREEN_START, NUM_GREENS);
- _vm->_viewManager->refreshAll();
- _fading_in_progress = false;
-}
-
-void Palette::fadeFromGreen(int numSteps, uint delayAmount, bool fadeToBlack) {
- if (_fading_in_progress)
- return;
- _fading_in_progress = true;
- RGB8 blackPalette[256];
- RGB8 *fadedPalette = (RGB8 *) &_fadedPalette[0];
- RGB8 *destPalette = (RGB8 *) &_originalPalette[0];
-
- if (fadeToBlack) {
- Common::fill((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0);
- destPalette = &blackPalette[0];
- }
-
- // Initially restore the faded palette
- _vm->_palette->setPalette(fadedPalette, 0, 256);
- _vm->_viewManager->refreshAll();
-
- // Restore the pixel data from the original screen
- _vm->_scene->update();
-
- // Handle the actual fading
- fadeRange(_vm, fadedPalette, destPalette, GREEN_START, NORMAL_END, numSteps, delayAmount);
-
- _fading_in_progress = false;
-}
-
-void Palette::fadeIn(int numSteps, uint delayAmount, RGBList *destPalette) {
- fadeIn(numSteps, delayAmount, destPalette->data(), destPalette->size());
-}
-
-void Palette::fadeIn(int numSteps, uint delayAmount, RGB8 *destPalette, int numColors) {
- if (_fading_in_progress)
- return;
-
- _fading_in_progress = true;
- RGB8 blackPalette[256];
- Common::fill((byte *)&blackPalette[0], (byte *)&blackPalette[256], 0);
-
- // Initially set the black palette
- _vm->_palette->setPalette(blackPalette, 0, numColors);
-
- // Handle the actual fading
- fadeRange(_vm, blackPalette, destPalette, 0, numColors - 1, numSteps, delayAmount);
-
- _fading_in_progress = false;
-}
-
-RGB8 *Palette::decodeMadsPalette(Common::SeekableReadStream *palStream, int *numColors) {
- *numColors = palStream->readUint16LE();
- assert(*numColors <= 252);
-
- RGB8 *palData = new RGB8[*numColors];
- Common::fill((byte *)&palData[0], (byte *)&palData[*numColors], 0);
-
- for (int i = 0; i < *numColors; ++i) {
- byte r = palStream->readByte();
- byte g = palStream->readByte();
- byte b = palStream->readByte();
- palData[i].r = VGA_COLOR_TRANS(r);
- palData[i].g = VGA_COLOR_TRANS(g);
- palData[i].b = VGA_COLOR_TRANS(b);
-
- // The next 3 bytes are unused
- palStream->skip(3);
- }
-
- return palData;
-}
-
-int Palette::setMadsPalette(Common::SeekableReadStream *palStream, int indexStart) {
- int colorCount;
- RGB8 *palData = Palette::decodeMadsPalette(palStream, &colorCount);
- _vm->_palette->setPalette(palData, indexStart, colorCount);
- delete palData;
- return colorCount;
-}
-
-void Palette::setMadsSystemPalette() {
- // Rex Nebular default system palette
- resetColorCounts();
-
- RGB8 palData[4];
- palData[0].r = palData[0].g = palData[0].b = 0;
- palData[1].r = palData[1].g = palData[1].b = 0x54;
- palData[2].r = palData[2].g = palData[2].b = 0xb4;
- palData[3].r = palData[3].g = palData[3].b = 0xff;
-
- setPalette(palData, 0, 4);
- blockRange(0, 4);
-}
-
-void Palette::resetColorCounts() {
- Common::fill(&_usageCount[0], &_usageCount[256], 0);
-}
-
-void Palette::blockRange(int startIndex, int size) {
- // Use a reference count of -1 to signal a palette index shouldn't be used
- Common::fill(&_usageCount[startIndex], &_usageCount[startIndex + size], -1);
-}
-
-void Palette::addRange(RGBList *list) {
- RGB8 *data = list->data();
- byte *palIndexes = list->palIndexes();
- RGB8 palData[256];
- g_system->getPaletteManager()->grabPalette((byte *)&palData[0], 0, 256);
- bool paletteChanged = false;
-
- for (int colIndex = 0; colIndex < list->size(); ++colIndex) {
- // Scan through for an existing copy of the RGB value
- int palIndex = -1;
- while (++palIndex < 256) {
- if (_usageCount[palIndex] <= 0)
- // Palette index is to be skipped
- continue;
-
- if ((palData[palIndex].r == data[colIndex].r) &&
- (palData[palIndex].g == data[colIndex].g) &&
- (palData[palIndex].b == data[colIndex].b))
- // Match found
- break;
- }
-
- if (palIndex == 256) {
- // No match found, so find a free slot to use
- palIndex = -1;
- while (++palIndex < 256) {
- if (_usageCount[palIndex] == 0)
- break;
- }
-
- if (palIndex == 256)
- error("addRange - Ran out of palette space to allocate");
-
- palData[palIndex].r = data[colIndex].r;
- palData[palIndex].g = data[colIndex].g;
- palData[palIndex].b = data[colIndex].b;
- paletteChanged = true;
- }
-
- palIndexes[colIndex] = palIndex;
- ++_usageCount[palIndex];
- }
-
- if (paletteChanged) {
- g_system->getPaletteManager()->setPalette((byte *)&palData[0], 0, 256);
- reset();
- }
-}
-
-void Palette::deleteRange(RGBList *list) {
- // Release the reference count on each of the palette entries
- for (int colIndex = 0; colIndex < list->size(); ++colIndex) {
- int palIndex = list->palIndexes()[colIndex];
- assert(_usageCount[palIndex] > 0);
- --_usageCount[palIndex];
- }
-}
-
-void Palette::deleteAllRanges() {
- for (int colIndex = 0; colIndex < 255; ++colIndex)
- _usageCount[colIndex] = 0;
-}
-
-//--------------------------------------------------------------------------
-// Support methods
-
-void decompressRle(byte *rleData, int rleSize, byte *celData, int w, int h) {
- byte *src = rleData;
- byte *dst = celData;
- byte len;
- while (1) {
- len = *src++;
- if (len == 0) {
- len = *src++;
- if (len <= 2) {
- if (len == 1) // end of sprite marker
- break;
- } else {
- while (len--)
- *dst++ = *src++;
- }
- } else {
- while (len--)
- *dst++ = *src;
- src++;
- }
- }
-}
-
-int scaleValue(int value, int scale, int err) {
- int scaled = 0;
- while (value--) {
- err -= scale;
- while (err < 0) {
- scaled++;
- err += 100;
- }
- }
- return scaled;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/graphics.h b/engines/m4/graphics.h
deleted file mode 100644
index f3dde454f3..0000000000
--- a/engines/m4/graphics.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_GRAPHICS_H
-#define M4_GRAPHICS_H
-
-#include "common/rect.h"
-#include "common/system.h"
-#include "common/stream.h"
-#include "graphics/surface.h"
-
-#include "m4/globals.h"
-
-namespace M4 {
-
-#define MADS_SURFACE_WIDTH 320
-#define MADS_SURFACE_HEIGHT 156
-#define MADS_SCREEN_HEIGHT 200
-#define MADS_Y_OFFSET ((MADS_SCREEN_HEIGHT - MADS_SURFACE_HEIGHT) / 2)
-
-#define TRANSPARENT_COLOR_INDEX 0xFF
-
-struct BGR8 {
- uint8 b, g, r;
-};
-
-struct RGB8 {
- uint8 r, g, b;
-};
-
-//later use ScummVM's Rect?
-struct M4Rect {
- int32 x1, y1, x2, y2;
-};
-
-class M4Surface;
-
-// RGBList
-// Implements a list of RGB entries
-
-class RGBList {
-private:
- int _size;
- RGB8 *_data;
- byte *_palIndexes;
- bool _freeData;
-public:
- RGBList(int numEntries = 256, RGB8 *srcData = NULL, bool freeData = true);
- ~RGBList();
-
- RGB8 *data() { return _data; }
- byte *palIndexes() { return _palIndexes; }
- int size() { return _size; }
- RGB8 &operator[](int idx) { return _data[idx]; }
- void setRange(int start, int count, const RGB8 *src);
- RGBList *clone() const;
-};
-
-// M4Surface
-// Class representing either a buffered surface or the physical screen.
-
-class M4Sprite;
-
-struct SpriteInfo {
- M4Sprite *sprite;
- int hotX, hotY;
- int width, height;
- int scaleX, scaleY;
- uint8 encoding;
- byte *inverseColorTable;
- RGB8 *palette;
-};
-
-class M4Surface : protected Graphics::Surface {
-private:
- byte _color;
- bool _isScreen;
- RGBList *_rgbList;
- bool _ownsData;
-
- void rexLoadBackground(Common::SeekableReadStream *source, RGBList **palData = NULL);
- void madsLoadBackground(int roomNumber, RGBList **palData = NULL);
- void m4LoadBackground(Common::SeekableReadStream *source);
-public:
- M4Surface(bool isScreen = false) {
- create(g_system->getWidth(), isScreen ? g_system->getHeight() : MADS_SURFACE_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
- _isScreen = isScreen;
- _rgbList = NULL;
- _ownsData = true;
- }
- M4Surface(int width_, int height_) {
- create(width_, height_, Graphics::PixelFormat::createFormatCLUT8());
- _isScreen = false;
- _rgbList = NULL;
- _ownsData = true;
- }
- M4Surface(int width_, int height_, byte *srcPixels, int pitch_) {
- format = Graphics::PixelFormat::createFormatCLUT8();
- w = width_;
- h = height_;
- pitch = pitch_;
- pixels = srcPixels;
- _rgbList = NULL;
- _ownsData = false;
- }
-
- virtual ~M4Surface();
-
- // loads a .COD file into the M4Surface
- // TODO: maybe move this to the rail system? check where it makes sense
- // The sprite drawing needs this, too, so should be more global.
- void loadCodesM4(Common::SeekableReadStream *source);
- void loadCodesMads(Common::SeekableReadStream *source);
-
- // loads the specified background
- void loadBackground(int sceneNumber, RGBList **palData = NULL);
- void loadBackgroundRiddle(const char *sceneName);
- void madsLoadInterface(int index, RGBList **palData = NULL);
- void madsLoadInterface(const Common::String &filename);
-
- void setColor(byte value) { _color = value; }
- inline byte getColor() const { return _color; }
- void vLine(int x, int y1, int y2);
- void hLine(int x1, int x2, int y);
- void vLineXor(int x, int y1, int y2);
- void hLineXor(int x1, int x2, int y);
- void drawLine(int x1, int y1, int x2, int y2, byte color);
- void frameRect(int x1, int y1, int x2, int y2);
- void fillRect(int x1, int y1, int x2, int y2);
-
- void drawSprite(int x, int y, SpriteInfo &info, const Common::Rect &clipRect);
-
- // Surface methods
- inline Common::Rect bounds() const { return Common::Rect(0, 0, width(), height()); }
- inline int width() const { return w; }
- inline int height() const { return h; }
- inline int getPitch() const { return pitch; }
- void setSize(int sizeX, int sizeY) { create(sizeX, sizeY, Graphics::PixelFormat::createFormatCLUT8()); }
- inline byte *getBasePtr() {
- return (byte *)pixels;
- }
- inline byte *getBasePtr(int x, int y) {
- return (byte *)Graphics::Surface::getBasePtr(x, y);
- }
- inline const byte *getBasePtr(int x, int y) const {
- return (const byte *)Graphics::Surface::getBasePtr(x, y);
- }
- void freeData();
- void clear();
- void reset();
- void frameRect(const Common::Rect &r, uint8 color);
- void fillRect(const Common::Rect &r, uint8 color);
- void copyFrom(M4Surface *src, const Common::Rect &srcBounds, int destX, int destY, int transparentColor = -1);
- void copyFrom(M4Surface *src, int destX, int destY, int depth, M4Surface *depthSurface,
- int scale, int transparentColor = -1);
-
- void update() {
- if (_isScreen) {
- g_system->copyRectToScreen((const byte *)pixels, pitch, 0, 0, w, h);
- g_system->updateScreen();
- }
- }
-
- // copyTo methods
- inline void copyTo(M4Surface *dest, int transparentColor = -1) {
- dest->copyFrom(this, Common::Rect(width(), height()), 0, 0, transparentColor);
- }
- inline void copyTo(M4Surface *dest, int x, int y, int transparentColor = -1) {
- dest->copyFrom(this, Common::Rect(width(), height()), x, y, transparentColor);
- }
- inline void copyTo(M4Surface *dest, const Common::Rect &srcBounds, int destX, int destY,
- int transparentColor = -1) {
- dest->copyFrom(this, srcBounds, destX, destY, transparentColor);
- }
- inline void copyTo(M4Surface *dest, int destX, int destY, int depth, M4Surface *depthsSurface, int scale,
- int transparentColor = -1) {
- dest->copyFrom(this, destX, destY, depth, depthsSurface, scale, transparentColor);
- }
-
- void scrollX(int xAmount);
- void scrollY(int yAmount);
-
- void translate(RGBList *list, bool isTransparent = false);
- M4Surface *flipHorizontal() const;
-};
-
-enum FadeType {FT_TO_GREY, FT_TO_COLOR, FT_TO_BLOCK};
-
-class Palette {
-private:
- MadsM4Engine *_vm;
- bool _colorsChanged;
- bool _fading_in_progress;
- byte _originalPalette[256 * 3];
- byte _fadedPalette[256 * 3];
- int _usageCount[256];
-
- void reset();
-public:
- Palette(MadsM4Engine *vm);
-
- void setPalette(const byte *colors, uint start, uint num);
- void setPalette(const RGB8 *colors, uint start, uint num);
- void grabPalette(byte *colors, uint start, uint num);
- void grabPalette(RGB8 *colors, uint start, uint num) {
- grabPalette((byte *)colors, start, num);
- }
- void setEntry(uint index, uint8 r, uint8 g, uint8 b);
- uint8 palIndexFromRgb(byte r, byte g, byte b, RGB8 *paletteData = NULL);
-
- void fadeToGreen(int numSteps, uint delayAmount);
- void fadeFromGreen(int numSteps, uint delayAmount, bool fadeToBlack);
- void fadeIn(int numSteps, uint delayAmount, RGB8 *destPalette, int numColors);
- void fadeIn(int numSteps, uint delayAmount, RGBList *destPalette);
- static RGB8 *decodeMadsPalette(Common::SeekableReadStream *palStream, int *numColors);
- int setMadsPalette(Common::SeekableReadStream *palStream, int indexStart = 0);
- void setMadsSystemPalette();
-
- // Methods used for reference counting color usage
- void resetColorCounts();
- void blockRange(int startIndex, int size);
- void addRange(RGBList *list);
- void deleteRange(RGBList *list);
- void deleteAllRanges();
-
- // Color indexes
- uint8 BLACK;
- uint8 BLUE;
- uint8 GREEN;
- uint8 CYAN;
- uint8 RED;
- uint8 VIOLET;
- uint8 BROWN;
- uint8 LIGHT_GRAY;
- uint8 DARK_GRAY;
- uint8 LIGHT_BLUE;
- uint8 LIGHT_GREEN;
- uint8 LIGHT_CYAN;
- uint8 LIGHT_RED;
- uint8 PINK;
- uint8 YELLOW;
- uint8 WHITE;
-};
-
-void decompressRle(byte *rleData, int rleSize, byte *celData, int w, int h);
-void decompressRle(Common::SeekableReadStream &rleData, byte *celData, int w, int h);
-int scaleValue(int value, int scale, int err);
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/gui.cpp b/engines/m4/gui.cpp
deleted file mode 100644
index 6bedfa7e9b..0000000000
--- a/engines/m4/gui.cpp
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/events.h"
-#include "common/keyboard.h"
-#include "common/textconsole.h"
-
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/midi.h"
-#include "m4/scene.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-//--------------------------------------------------------------------------
-// DialogView class
-//
-// Defines a generic base class for dialogs, that some of the classes
-// in the object hierharchy require as a parent
-//--------------------------------------------------------------------------
-
-void DialogView::close() {
- // Default to simply destroying the given dialog
- _vm->_viewManager->deleteView(this);
-}
-
-//--------------------------------------------------------------------------
-// GUIObject class
-//
-// Defines a generic object that appears in a view
-//--------------------------------------------------------------------------
-
-GUIObject::GUIObject(View *owner, const Common::Rect &bounds) {
- _parent = owner;
- _bounds = bounds;
-}
-
-//--------------------------------------------------------------------------
-// MenuObject class
-//
-// Defines a specialised GUI object that appears in a dialog
-//--------------------------------------------------------------------------
-
-MenuObject::MenuObject(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool greyed, bool transparent):
- GUIObject(owner, Common::Rect(xs, ys, xs + width, ys + height)) {
-
- _objectId = objectId;
- _bounds.top = ys;
- _bounds.bottom = ys + height - 1;
- _bounds.left = xs;
- _bounds.right = xs + width - 1;
- _transparent = transparent;
- _objectState = greyed ? OS_GREYED : OS_NORMAL;
- _callback = NULL;
-
- if (transparent) {
- _background = new M4Surface(width, height);
- Common::Rect srcBounds(xs, ys, xs + width - 1, ys + height - 1);
- _background->copyFrom(owner, srcBounds, 0, 0);
- } else {
- _background = NULL;
- }
-}
-
-MenuObject::~MenuObject() {
- delete _background;
-}
-
-void MenuObject::onExecute() {
- // If a callback function has been specified, then execute it
- if (_callback)
- _callback(parent(), this);
-}
-
-//--------------------------------------------------------------------------
-// MenuButton class
-//
-// Defines a button object
-//--------------------------------------------------------------------------
-
-MenuButton::MenuButton(DialogView *owner, int buttonId, int xs, int ys, int width, int height,
- MenuButton::Callback callbackFn, bool greyed, bool transparent,
- ObjectType buttonType):
- MenuObject(owner, buttonId, xs, ys, width, height, greyed, transparent) {
-
- _objectType = buttonType;
- _callback = callbackFn;
-}
-
-bool MenuButton::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- bool redrawFlag = false;
- bool callbackFlag = false;
- bool handledFlag = true;
-
- if (_objectState == OS_GREYED)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y)) {
- _objectState = OS_PRESSED;
- if (currentItem != NULL)
- currentItem = this;
- redrawFlag = true;
- } else {
- currentItem = NULL;
- if (_objectState != OS_NORMAL) {
- _objectState = OS_PRESSED;
- redrawFlag = true;
- }
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem) {
- return true;
- }
- if (isInside(x, y)) {
- if (_objectState != OS_PRESSED) {
- _objectState = OS_PRESSED;
- redrawFlag = true;
- }
- }
- else {
- if (_objectState != OS_MOUSEOVER) {
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- }
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (isInside(x, y)) {
- if (currentItem) {
- callbackFlag = true;
- if (_objectType == OBJTYPE_OM_SWITCH_ON)
- _objectType = OBJTYPE_OM_SWITCH_OFF;
- else if (_objectType == OBJTYPE_OM_SWITCH_OFF)
- _objectType = OBJTYPE_OM_SWITCH_ON;
- }
- else {
- currentItem = this;
- }
-
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
-
- } else {
- currentItem = NULL;
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- handledFlag = false;
- }
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y)) {
- currentItem = this;
- if (_objectState != OS_MOUSEOVER) {
- _objectState = OS_MOUSEOVER;
- redrawFlag = true;
- }
- }
- else {
- currentItem = NULL;
- if (_objectState != OS_NORMAL) {
- _objectState = OS_NORMAL;
- redrawFlag = true;
- handledFlag = false;
- }
- }
- break;
-
- case MEVENT_LEFT_HOLD:
- case MEVENT_DOUBLECLICK_HOLD:
- break;
-
- default:
- break;
- }
-
- //see if we need to redraw the button
- if (redrawFlag) {
- onRefresh();
-
- // TODO: There may be a more efficient mechanism than refreshing the entire screen
- // when a menu object refreshes itself
- if (parent()->screenFlags().visible)
- _vm->_viewManager->refreshAll();
- }
-
- // If a callback is flagged, then handle it
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-void MenuButton::onRefresh() {
- M4Sprite *sprite = NULL;
- SpriteAsset &sprites = *parent()->sprites();
-
- // Switch handling for the various button types
- switch (_objectType) {
- case OBJTYPE_BUTTON:
- sprite = sprites[GM_BUTTON_GREYED + _objectState];
- break;
-
- case OBJTYPE_OM_SWITCH_ON:
- switch (_objectState) {
- case OS_MOUSEOVER:
- sprite = sprites[MENU_SS_SWITCH_ON_MOUSEOVER];
- break;
- case OS_PRESSED:
- sprite = sprites[MENU_SS_SWITCH_ON_PRESSED];
- break;
- default:
- sprite = sprites[MENU_SS_SWITCH_ON_NORMAL];
- break;
- }
- break;
-
- case OBJTYPE_OM_SWITCH_OFF:
- switch (_objectState) {
- case OS_MOUSEOVER:
- sprite = sprites[MENU_SS_SWITCH_OFF_MOUSEOVER];
- break;
- case OS_PRESSED:
- sprite = sprites[MENU_SS_SWITCH_OFF_PRESSED];
- break;
- default:
- sprite = sprites[MENU_SS_SWITCH_OFF_NORMAL];
- break;
- }
- break;
-
- case OBJTYPE_OM_DONE:
- sprite = sprites[OM_DONE_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_OM_CANCEL:
- sprite = (_objectState == OS_GREYED) ? sprites[OM_CANCEL_BTN_NORMAL] :
- sprites[OM_CANCEL_BTN_NORMAL + _objectState - 1];
- break;
-
- case OBJTYPE_SL_SAVE:
- sprite = sprites[SL_SAVE_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_SL_LOAD:
- sprite = sprites[SL_LOAD_BTN_GREYED + _objectState];
- break;
-
- case OBJTYPE_SL_CANCEL:
- sprite = (_objectState == OS_GREYED) ? sprites[SL_CANCEL_BTN_NORMAL] :
- sprites[SL_CANCEL_BTN_NORMAL + _objectState - 1];
- break;
-
- case OBJTYPE_SL_TEXT:
- switch (_objectState) {
- case OS_MOUSEOVER:
- _vm->_font->current()->setColors(TEXT_COLOR_MOUSEOVER_SHADOW, TEXT_COLOR_MOUSEOVER_FOREGROUND,
- TEXT_COLOR_MOUSEOVER_HILIGHT);
- sprite = sprites[SL_LINE_MOUSEOVER];
- break;
-
- case OS_PRESSED:
- _vm->_font->current()->setColors(TEXT_COLOR_PRESSED_SHADOW, TEXT_COLOR_PRESSED_FOREGROUND,
- TEXT_COLOR_PRESSED_HILIGHT);
- sprite = sprites[SL_LINE_PRESSED];
- break;
-
- case OS_GREYED:
- _vm->_font->current()->setColors(TEXT_COLOR_GREYED_SHADOW, TEXT_COLOR_GREYED_FOREGROUND,
- TEXT_COLOR_GREYED_HILIGHT);
- sprite = sprites[SL_LINE_NORMAL];
- break;
-
- default:
- case OS_NORMAL:
- _vm->_font->current()->setColors(TEXT_COLOR_NORMAL_SHADOW, TEXT_COLOR_NORMAL_FOREGROUND,
- TEXT_COLOR_NORMAL_HILIGHT);
- sprite = sprites[SL_LINE_NORMAL];
- break;
- }
- break;
-
- default:
- error("Unknown object type");
- break;
- }
-
- // If no sprite object was set, then exit without doing anything
- if (!sprite)
- return;
-
- // Draw the button
- if (_transparent) {
- // Transparent button, so restore original background
- if (!_background)
- return;
- else
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuHorizSlider class
-//
-// Defines a horizontal slider that allows selection of a percentage
-//--------------------------------------------------------------------------
-
-MenuHorizSlider::MenuHorizSlider(DialogView *owner, int objectId, int xs, int ys,
- int width, int height, int initialPercentage, Callback callbackFn, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _objectType = OBJTYPE_SLIDER;
- _callback = callbackFn;
-
- SpriteAsset &sprites = *owner->sprites();
- _sliderState = HSLIDER_THUMB_NORMAL;
- _thumbSize.x = sprites[OM_SLIDER_BTN_NORMAL]->width();
- _thumbSize.y = sprites[OM_SLIDER_BTN_NORMAL]->height();
- _maxThumbX = width - _thumbSize.x;
- _percent = MAX(MIN(initialPercentage, 100), 0);
- _thumbX = initialPercentage * _maxThumbX / 100;
-}
-
-void MenuHorizSlider::onRefresh() {
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Get the thumb sprite for the slider
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *sprite = sprites[OM_SLIDER_BTN_NORMAL + _sliderState];
- assert(sprite);
-
- // Fill in the area to the left of the thumbnail
- if (_thumbX > 2) {
- Common::Rect leftBounds(_bounds.left + 3, _bounds.top + 9, _bounds.left + _thumbX,
- _bounds.top + _thumbSize.y - 9);
- parent()->fillRect(leftBounds, SLIDER_BAR_COLOR);
- }
-
- // Draw the thumbnail
- sprite->copyTo(parent(), _bounds.left + _thumbX, _bounds.top, 0);
-}
-
-bool MenuHorizSlider::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- static bool movingFlag = false;
- static int movingX = 0;
- bool redrawFlag = false, handledFlag = false, callbackFlag = false;
-
- if (event == KEVENT_KEY)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- // The thumbnail has been clicked
- _sliderState = HSLIDER_THUMB_PRESSED;
- movingFlag = true;
- movingX = x;
- currentItem = this;
- redrawFlag = true;
- } else {
- currentItem = NULL;
- _sliderState = HSLIDER_THUMB_NORMAL;
- redrawFlag = true;
- }
- redrawFlag = true;
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem)
- return true;
-
- if (movingFlag) {
- if (x != movingX) {
- if (x < movingX)
- _thumbX -= MIN(_thumbX, movingX - x);
- else
- _thumbX += MIN(_maxThumbX - _thumbX, x - movingX);
- _percent = _thumbX * 100 / _maxThumbX;
- redrawFlag = callbackFlag = true;
- }
- movingX = CLIP(x, _bounds.left + _thumbX,
- _bounds.left + _thumbX + _thumbSize.x - 1);
- } else {
- currentItem = NULL;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (!currentItem)
- return true;
-
- movingFlag = false;
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- _sliderState = HSLIDER_THUMB_MOUSEOVER;
- currentItem = this;
- } else {
- _sliderState = HSLIDER_THUMB_NORMAL;
- currentItem = NULL;
- }
-
- redrawFlag = true;
- callbackFlag = true;
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y) && (x - _bounds.left >= _thumbX) &&
- (x - _bounds.left <= _thumbX + _thumbSize.x - 1)) {
- if (_sliderState != HSLIDER_THUMB_MOUSEOVER) {
- _sliderState = HSLIDER_THUMB_MOUSEOVER;
- currentItem = this;
- }
- } else {
- if (_sliderState != HSLIDER_THUMB_NORMAL) {
- _sliderState = HSLIDER_THUMB_NORMAL;
- currentItem = NULL;
- handledFlag = false;
- }
- }
- redrawFlag = true;
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-//--------------------------------------------------------------------------
-// MenuVertSlider class
-//
-// Defines a vertical slider that's used in the save/load dialog
-//--------------------------------------------------------------------------
-
-MenuVertSlider::MenuVertSlider(DialogView *owner, int objectId, int xs, int ys,
- int width, int height, int initialPercentage, Callback callbackFn, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _objectType = OBJTYPE_SLIDER;
- _callback = callbackFn;
-
- SpriteAsset &sprites = *owner->sprites();
- _sliderState = VSLIDER_NONE;
- _thumbSize.x = sprites[SL_SLIDER_BTN_NORMAL]->width();
- _thumbSize.y = sprites[SL_SLIDER_BTN_NORMAL]->height();
- _minThumbY = sprites[SL_UP_BTN_NORMAL]->height() + 1;
- _maxThumbY = sprites[SL_UP_BTN_NORMAL]->height() + sprites[SL_SCROLLBAR]->height() -
- sprites[SL_SLIDER_BTN_NORMAL]->height() - 1;
-
- _percent = MAX(MIN(initialPercentage, 100), 0);
- _thumbY = _minThumbY + ((_percent * (_maxThumbY - _minThumbY)) / 100);
-}
-
-MenuVertSliderState MenuVertSlider::getSliderArea(int y) {
- if (y < _minThumbY)
- return VSLIDER_UP;
- else if (y < _thumbY)
- return VSLIDER_PAGE_UP;
- else if (y < _thumbY + _thumbSize.y)
- return VSLIDER_THUMBNAIL;
- else if (y < _maxThumbY + _thumbSize.y)
- return VSLIDER_PAGE_DOWN;
- else
- return VSLIDER_DOWN;
-}
-
-void MenuVertSlider::onRefresh() {
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Get the various needed sprites
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *barSprite = sprites[SL_SCROLLBAR];
- M4Sprite *thumbSprite = sprites[SL_SLIDER_BTN_NORMAL];
- M4Sprite *upSprite = sprites[SL_UP_BTN_NORMAL];
- M4Sprite *downSprite = sprites[SL_DOWN_BTN_NORMAL];
-
- if (_objectState == OS_GREYED) {
- upSprite = sprites[SL_UP_BTN_GREYED];
- downSprite = sprites[SL_DOWN_BTN_GREYED];
- thumbSprite = NULL;
-
- } else if (_objectState == OS_MOUSEOVER) {
- if (_sliderState == VSLIDER_UP)
- upSprite = sprites[SL_UP_BTN_MOUSEOVER];
- else if (_sliderState == VSLIDER_THUMBNAIL)
- thumbSprite = sprites[SL_SLIDER_BTN_MOUSEOVER];
- else if (_sliderState == VSLIDER_DOWN)
- downSprite = sprites[SL_DOWN_BTN_MOUSEOVER];
- }
- else if (_objectState == OS_PRESSED) {
- if (_sliderState == VSLIDER_UP)
- upSprite = sprites[SL_UP_BTN_PRESSED];
- else if (_sliderState == VSLIDER_THUMBNAIL)
- thumbSprite = sprites[SL_SLIDER_BTN_PRESSED];
- else if (_sliderState == VSLIDER_DOWN)
- downSprite = sprites[SL_DOWN_BTN_PRESSED];
- }
-
- // Draw the sprites
- upSprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
- barSprite->copyTo(parent(), _bounds.left, _bounds.top + upSprite->height(), 0);
- downSprite->copyTo(parent(), _bounds.left, _bounds.top + upSprite->height() + barSprite->height(), 0);
- if (thumbSprite)
- thumbSprite->copyTo(parent(), _bounds.left, _bounds.top + _thumbY, 0);
-}
-
-bool MenuVertSlider::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- static bool movingFlag = false;
- static int movingY = 0;
- static uint32 callbackTime;
- MenuVertSliderState tempState;
- int delta;
- uint32 currentTime = g_system->getMillis();
- bool redrawFlag = false;
- bool handledFlag = true;
- bool callbackFlag = false;
-
- if (event == KEVENT_KEY)
- return false;
-
- if (_objectState == OS_GREYED) {
- currentItem = NULL;
- return false;
- }
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (isInside(x, y)) {
- currentItem = this;
- tempState = getSliderArea(y - _bounds.top);
- if (tempState == VSLIDER_THUMBNAIL) {
- movingFlag = true;
- movingY = y;
- }
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN)) {
- _sliderState = tempState;
- setState(OS_NORMAL);
- } else {
- _sliderState = tempState;
- setState(OS_PRESSED);
- redrawFlag = true;
- }
- callbackFlag = true;
- } else {
- currentItem = NULL;
- setState(OS_NORMAL);
- redrawFlag = true;
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (!currentItem)
- return true;
-
- if (movingFlag) {
- if (y < movingY) {
- delta = MIN(_thumbY - _minThumbY, movingY - y);
- if (delta > 0) {
- _thumbY -= delta;
- _percent = ((_thumbY - _minThumbY) * 100) / (_maxThumbY - _minThumbY);
- redrawFlag = true;
- callbackFlag = true;
- }
- }
- else if (y > movingY) {
- delta = MIN(_maxThumbY - _thumbY, y - movingY);
- if (delta > 0) {
- _thumbY += delta;
- _percent = ((_thumbY - _minThumbY) * 100) / (_maxThumbY - _minThumbY);
- redrawFlag = true;
- callbackFlag = true;
- }
- }
- movingY = y;
-
- if (movingY < (_thumbY + _bounds.top))
- movingY = _thumbY + _bounds.top;
- else if (movingY > (_bounds.top + _thumbY + _thumbSize.y - 1))
- movingY = _bounds.top + _thumbY + _thumbSize.y - 1;
-
- } else {
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
- if (_sliderState == tempState) {
- if ((tempState != VSLIDER_PAGE_UP) && (tempState != VSLIDER_PAGE_DOWN) &&
- (_objectState != OS_PRESSED)) {
- _sliderState = tempState;
- setState(OS_PRESSED);
- redrawFlag = true;
- }
- if (currentTime - callbackTime > 100)
- callbackFlag = true;
-
- } else {
- if (_objectState != OS_MOUSEOVER)
- setState(OS_MOUSEOVER);
- redrawFlag = true;
- }
- callbackFlag = true;
-
- } else {
- if (_objectState != OS_MOUSEOVER) {
- setState(OS_MOUSEOVER);
- redrawFlag = true;
- }
- }
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- movingFlag = false;
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN))
- setState(OS_NORMAL);
- else {
- setState(OS_MOUSEOVER);
- currentItem = this;
- }
- } else {
- setState(OS_NORMAL);
- currentItem = NULL;
- }
-
- redrawFlag = true;
- if (parent()->getMenuType() == LOAD_MENU)
- updateThumbnails();
- break;
-
- case MEVENT_MOVE:
- if (isInside(x, y)) {
- currentItem = this;
- tempState = getSliderArea(y - _bounds.top);
- if (_sliderState != tempState) {
- if ((tempState == VSLIDER_PAGE_UP) || (tempState == VSLIDER_PAGE_DOWN))
- _objectState = OS_NORMAL;
- else {
- _sliderState = tempState;
- _objectState = OS_MOUSEOVER;
- }
- redrawFlag = true;
- }
- } else {
- currentItem = NULL;
-
- if (_objectState != OS_NORMAL) {
- _objectState = OS_NORMAL;
- redrawFlag = true;
- handledFlag = false;
- }
- }
- break;
-
- case MEVENT_LEFT_HOLD:
- case MEVENT_DOUBLECLICK_HOLD:
- if (!currentItem)
- return true;
-
- if (isInside(x, y)) {
- tempState = getSliderArea(y - _bounds.top);
-
- if (_sliderState == tempState) {
- if (currentTime - callbackTime > 100)
- callbackFlag = true;
- }
- }
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag) {
- callbackTime = currentTime;
- onExecute();
- }
-
- return handledFlag;
-}
-
-void MenuVertSlider::setPercentage(int value) {
- _percent = value;
- _thumbY = _minThumbY + ((_percent * (_maxThumbY - _minThumbY)) / 100);
- onRefresh();
-}
-
-//--------------------------------------------------------------------------
-// MenuMessage class
-//
-// Defines a message menu object
-//--------------------------------------------------------------------------
-
-MenuMessage::MenuMessage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-}
-
-void MenuMessage::onRefresh() {
- SpriteAsset &sprites = *parent()->sprites();
- M4Surface *sprite = NULL;
-
- // Get the correct sprite to use
- switch (_objectId) {
- case SLTAG_SAVELOAD_LABEL:
- sprite = (parent()->getMenuType() == SAVE_MENU) ? sprites[SL_SAVE_LABEL] :
- sprites[SL_LOAD_LABEL];
- break;
- }
- assert(sprite);
-
- // Draw the sprite
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- // Restore original background and then do a transparent copy of the sprite
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuImage class
-//
-// Defines a menu item that displays a given surface
-//--------------------------------------------------------------------------
-
-MenuImage::MenuImage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- M4Surface *image, bool transparent):
- MenuObject(owner, objectId, xs, ys, width, height, false, transparent) {
-
- _sprite = image;
-}
-
-void MenuImage::onRefresh() {
- if (!_sprite)
- return;
-
- // Draw the sprite
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- // Restore original background and then do a transparent copy of the sprite
- _background->copyTo(parent(), _bounds.left, _bounds.top);
- }
-
- _sprite->copyTo(parent(), _bounds.left + (_bounds.width() - _sprite->width()) / 2,
- _bounds.top + (_bounds.height() - _sprite->height()) / 2, 0);
-}
-
-//--------------------------------------------------------------------------
-// MenuSaveLoadText class
-//
-// Defines a save/load dialog text entry
-//--------------------------------------------------------------------------
-
-MenuSaveLoadText::MenuSaveLoadText(DialogView *owner, int textId, int xs, int ys,
- int width, int height, Callback callbackFn, bool greyed, bool transparent,
- bool loadFlag, const char *displayText, int displayValue):
- MenuButton(owner, textId, xs, ys, width, height, callbackFn, greyed, transparent, OBJTYPE_SL_TEXT) {
-
- _loadFlag = loadFlag;
- _displayText = displayText;
- _displayValue = displayValue;
- _index = textId - SLTAG_SLOTS_START;
- _visible = true;
-}
-
-void MenuSaveLoadText::onRefresh() {
- if (!_visible) return;
- _vm->_font->setFont(FONT_MENU);
- MenuButton::onRefresh();
-
- if ((_objectType == OBJTYPE_SL_TEXT) && (_displayText != NULL)) {
- int xp = _bounds.left + 4;
- if (_displayValue != 0) {
- char tempBuffer[5];
- sprintf(tempBuffer, "%02d", _displayValue);
- _vm->_font->current()->writeString(_parent, tempBuffer, xp, _bounds.top + 1, 0, -1);
- xp = _bounds.left + 26;
- }
-
- _vm->_font->current()->writeString(_parent, _displayText, xp, _bounds.top + 1, 0, -1);
- }
-}
-
-bool MenuSaveLoadText::onEvent(M4::M4EventType event, int32 param, int x, int y, M4::MenuObject *&currentItem) {
- if (!_visible) return false;
- bool handledFlag = MenuButton::onEvent(event, param, x, y, currentItem);
-
- // Further handling will only be done when in load mode and a slot hasn't been selected
- if (!_loadFlag || (parent()->_selectedSlot != -1))
- return handledFlag;
-
- // Only handling for certain event types
- if ((event != MEVENT_MOVE) && (event != MEVENT_LEFT_DRAG) &&
- (event != MEVENT_LEFT_RELEASE) && (event != MEVENT_DOUBLECLICK_DRAG) &&
- (event != MEVENT_DOUBLECLICK_RELEASE))
- return handledFlag;
-
- MenuImage *thumbnail = (MenuImage *) parent()->getItem(SLTAG_THUMBNAIL);
-
- // Check whether the cursor is over the button
- if ((_objectState == OS_MOUSEOVER) || (_objectState == OS_PRESSED)) {
- if (_index != parent()->_highlightedSlot) {
- // Selected slot has changed
- if (parent()->_savegameThumbnail != NULL)
- delete parent()->_savegameThumbnail;
-
- parent()->_highlightedSlot = _index;
- parent()->_savegameThumbnail = _vm->_saveLoad->getThumbnail(_index + 1);
- thumbnail->setSprite(parent()->_savegameThumbnail);
- }
-
- } else {
- // If the mouse has moved outside the area of all the save slots, then the
- // thumbnail needs to be removed
-
- Common::Rect slotArea(50, 256, 288, 377);
- if (isInside(x, y) || !slotArea.contains(x, y)) {
- if (parent()->_savegameThumbnail) {
- delete parent()->_savegameThumbnail;
- parent()->_savegameThumbnail = NULL;
- }
-
- thumbnail->setSprite(parent()->sprites()->getFrame(SL_EMPTY_THUMBNAIL));
- parent()->_highlightedSlot = -1;
- }
- }
-
- return handledFlag;
-}
-
-void MenuSaveLoadText::setVisible(bool value) {
- _visible = value;
- parent()->refresh(_bounds);
-}
-
-//--------------------------------------------------------------------------
-// MenuTextField class
-//
-// Defines a text entry field
-//--------------------------------------------------------------------------
-
-MenuTextField::MenuTextField(DialogView *owner, int fieldId, int xs, int ys, int width,
- int height, bool greyed, Callback callbackFn,
- const char *displayText, int displayValue, bool transparent):
- MenuObject(owner, fieldId, xs, ys, width, height, greyed, transparent) {
-
- _displayValue = displayValue;
- _callback = callbackFn;
- _pixelWidth = width - 27;
- if (displayText) {
- strcpy(_displayText, displayText);
- _promptEnd = &_displayText[strlen(_displayText)];
- } else {
- _displayText[0] = '\0';
- _promptEnd = &_displayText[0];
- }
- _cursor = _promptEnd;
-}
-
-void MenuTextField::onRefresh() {
- bool focused = _objectState != OS_GREYED;
-
- // Get the thumb sprite for the slider
- SpriteAsset &sprites = *parent()->sprites();
- M4Sprite *sprite = sprites[SL_LINE_NORMAL + OS_MOUSEOVER - 1];
-
- // If the slider is transparent, first copy in the background
- if (_transparent) {
- // Transparent button
- if (!_background)
- return;
-
- _background->copyTo(parent(), _bounds.left, _bounds.top, 0);
- }
-
- // Draw the sprite
- sprite->copyTo(parent(), _bounds.left, _bounds.top, 0);
-
- // Draw the text
-
- _vm->_font->setFont(FONT_MENU);
- _vm->_font->current()->setColors(TEXT_COLOR_NORMAL_SHADOW, TEXT_COLOR_NORMAL_FOREGROUND,
- TEXT_COLOR_NORMAL_HILIGHT);
- int xp = _bounds.left + 4;
-
- if (_displayValue != 0) {
- char tempBuffer[5];
- sprintf(tempBuffer, "%02d", _displayValue);
- _vm->_font->current()->writeString(_parent, tempBuffer, xp, _bounds.top + 1, 0, -1);
- xp = _bounds.left + 26;
- }
-
- _vm->_font->current()->writeString(_parent, _displayText, xp, _bounds.top + 1, 0, -1);
-
- if (focused) {
- // Draw in the cursor
-
- if (_cursor) {
- // Get the width of the string up to the cursor position
- char tempCh = *_cursor;
- *_cursor = '\0';
- int stringWidth = _vm->_font->current()->getWidth(_displayText);
- *_cursor = tempCh;
-
- parent()->setColor(TEXT_COLOR_MOUSEOVER_FOREGROUND);
- parent()->vLine(xp + stringWidth + 1, _bounds.top + 1, _bounds.top + 12);
- }
- }
-}
-
-bool MenuTextField::onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) {
- char tempStr[MAX_SAVEGAME_NAME];
- int tempLen;
- char *tempP;
- bool handledFlag = false, redrawFlag = false, callbackFlag = false;
-
- if (_objectState == OS_GREYED)
- return false;
-
- switch (event) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- parent()->_deleteSaveDesc = false;
- if (isInside(x, y))
- currentItem = this;
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- if (!currentItem)
- return true;
- currentItem = NULL;
-
- if (isInside(x, y)) {
- if (_objectState == OS_MOUSEOVER) {
- tempLen = strlen(_displayText);
- if (tempLen > 0) {
- strcpy(tempStr, _displayText);
- tempP = &tempStr[tempLen];
- _vm->_font->setFont(FONT_MENU);
-
- tempLen = _vm->_font->current()->getWidth(tempStr);
- while ((tempP != &tempStr[0]) && (tempLen > x - _bounds.left - 26)) {
- *--tempP = '\0';
- tempLen = _vm->_font->current()->getWidth(tempStr);
- }
-
- _cursor = &_displayText[tempP - &tempStr[0]];
- redrawFlag = true;
- }
- } else if (event == MEVENT_DOUBLECLICK_RELEASE) {
- callbackFlag = true;
- }
- }
- break;
-
- case KEVENT_KEY:
- switch (param) {
- case Common::KEYCODE_RETURN:
- case Common::KEYCODE_KP_ENTER:
- parent()->_deleteSaveDesc = false;
- callbackFlag = true;
- break;
- break;
-
- case Common::KEYCODE_HOME:
- parent()->_deleteSaveDesc = false;
- _cursor = &_displayText[0];
- redrawFlag = true;
- break;
-
- case Common::KEYCODE_END:
- parent()->_deleteSaveDesc = false;
- _cursor = _promptEnd;
- redrawFlag = true;
- break;
-
- case Common::KEYCODE_LEFT:
- case Common::KEYCODE_KP4:
- parent()->_deleteSaveDesc = false;
- if (_cursor > &_displayText[0]) {
- --_cursor;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_RIGHT:
- case Common::KEYCODE_KP6:
- parent()->_deleteSaveDesc = false;
- if (_cursor < _promptEnd) {
- ++_cursor;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_DELETE:
- if (parent()->_deleteSaveDesc) {
- _displayText[0] = '\0';
- _promptEnd = &_displayText[0];
- _cursor = _promptEnd;
- redrawFlag = true;
- } else if (_cursor < _promptEnd) {
- strcpy(tempStr, _cursor + 1);
- strcpy(_cursor, tempStr);
- --_promptEnd;
- redrawFlag = true;
- }
- break;
-
- case Common::KEYCODE_BACKSPACE:
- parent()->_deleteSaveDesc = false;
- if (_cursor > &_displayText[0]) {
- strcpy(tempStr, _cursor);
- --_promptEnd;
- --_cursor;
- strcpy(_cursor, tempStr);
- redrawFlag = true;
- }
- break;
-
- default:
- parent()->_deleteSaveDesc = false;
- _vm->_font->setFont(FONT_MENU);
-
- tempLen = _vm->_font->current()->getWidth(_displayText);
- if ((strlen(_displayText) < MAX_SAVEGAME_NAME - 1) &&
- (tempLen < _pixelWidth - 12) && (param >= 32) && (param <= 127)) {
-
- // Valid displayable character
- if (_cursor < _promptEnd) {
- strcpy(tempStr, _cursor);
- sprintf(_cursor, "%c%s", (char)param, tempStr);
- } else {
- *_cursor = (char)param;
- *(_cursor + 1) = '\0';
- }
- ++_cursor;
- ++_promptEnd;
-
- redrawFlag = true;
- }
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (redrawFlag)
- onRefresh();
-
- if (callbackFlag)
- onExecute();
-
- return handledFlag;
-}
-
-//--------------------------------------------------------------------------
-
-
-GUITextField::GUITextField(View *owner, const Common::Rect &bounds): GUIRect(owner, bounds, 0) {
-}
-
-void GUITextField::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
- _vm->_font->current()->setColors(3, 3, 3);
- _vm->_font->setFont(FONT_INTERFACE);
- _vm->_font->current()->writeString(_parent, _text.c_str(), _bounds.left, _bounds.top, 0, 1);
-}
-
-//--------------------------------------------------------------------------
-
-GUIButton::GUIButton(View *owner, const Common::Rect &bounds, int tag,
- M4Surface *normalSprite, M4Surface *mouseOverSprite, M4Surface *pressedSprite):
- GUIRect(owner, bounds, tag) {
-
- _normalSprite = normalSprite;
- _mouseOverSprite = mouseOverSprite;
- _pressedSprite = pressedSprite;
- _visible = true;
- _tracking = false;
-}
-
-void GUIButton::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
-
- if (_visible) {
- switch (_buttonState) {
- case BUTTON_MOUSEOVER:
- _mouseOverSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- case BUTTON_PRESSED:
- _pressedSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- default:
- _normalSprite->copyTo(_parent, _bounds.left, _bounds.top, 0);
- break;
- }
- }
-}
-
-bool GUIButton::onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) {
- bool result = false;
- bool isPressed = (eventType == MEVENT_LEFT_CLICK) || (eventType == MEVENT_LEFT_HOLD) ||
- (eventType == MEVENT_LEFT_DRAG);
- bool isOver = isInside(x, y);
- GUIButtonState oldState = _buttonState;
-
- if (isOver) {
- if (isPressed) {
- // Button is pressed
- if (!_tracking) {
- _tracking = true;
- _buttonState = BUTTON_PRESSED;
- }
-
- if (_vm->isM4())
- _m4Vm->globals()->invSuppressClickSound = false;
- } else {
- // Button isn't pressed
- if (_tracking)
- result = true;
- else {
- result = false;
- _buttonState = BUTTON_MOUSEOVER;
- _tracking = false;
- }
- }
- } else {
- _tracking = false;
- _buttonState = BUTTON_NORMAL;
- }
-
- if (oldState != _buttonState)
- onRefresh();
-
- return result;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/gui.h b/engines/m4/gui.h
deleted file mode 100644
index 2b673d624c..0000000000
--- a/engines/m4/gui.h
+++ /dev/null
@@ -1,453 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_GUI_H
-#define M4_GUI_H
-
-#include "common/list.h"
-#include "common/rect.h"
-
-#include "m4/viewmgr.h"
-#include "m4/events.h"
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/saveload.h"
-#include "m4/sprite.h"
-#include "m4/assets.h"
-
-namespace M4 {
-
-class GUIObject;
-class MenuObject;
-class GUIObjectButton;
-class SpriteAsset;
-class View;
-
-enum MenuType {GAME_MENU, OPTIONS_MENU, SAVE_MENU, LOAD_MENU, MAIN_MENU};
-
-enum {
- BTNID_QUIT = 1,
- BTNID_OPTIONS = 2,
- BTNID_RESUME = 3,
- BTNID_SAVE = 4,
- BTNID_LOAD = 5,
- BTNID_MAIN = 6,
-
- OPTIONID_DONE = 1,
- OPTIONID_CANCEL = 2,
- OPTIONID_HSLIDER_DIGI = 3,
- OPTIONID_HSLIDER_MIDI = 4,
-
- SAVELOADID_SAVE = 1,
- SAVELOADID_CANCELSAVE = 2,
- SAVELOADID_LOAD = 3,
- SAVELOADID_CANCELLOAD = 4,
-
- SLTAG_SAVELOAD = 100,
- SLTAG_SAVELOAD_LABEL = 101,
- SLTAG_CANCEL = 102,
- SLTAG_VSLIDER = 103,
- SLTAG_THUMBNAIL = 104,
-
- SLTAG_SLOTS_START = 1001,
- SLTAG_TEXTFIELD = 2000
-};
-
-enum ObjectType {
- OBJTYPE_BUTTON,
-
- OBJTYPE_SLIDER,
- OBJTYPE_OM_SWITCH_ON,
- OBJTYPE_OM_SWITCH_OFF,
- OBJTYPE_OM_DONE,
- OBJTYPE_OM_CANCEL,
-
- OBJTYPE_SL_SAVE,
- OBJTYPE_SL_LOAD,
- OBJTYPE_SL_CANCEL,
- OBJTYPE_SL_TEXT
-};
-
-enum GameMenuSpriteType {
- GM_DIALOG_BOX,
-
- GM_BUTTON_GREYED,
- GM_BUTTON_NORMAL,
- GM_BUTTON_MOUSEOVER,
- GM_BUTTON_PRESSED
-};
-
-enum OptionMenuSpriteType {
- OM_DIALOG_BOX,
-
- OM_SLIDER_BTN_NORMAL,
- OM_SLIDER_BTN_MOUSEOVER,
- OM_SLIDER_BTN_PRESSED,
- OM_SLIDER_BAR,
- OM_DONE_BTN_GREYED,
- OM_DONE_BTN_NORMAL,
- OM_DONE_BTN_MOUSEOVER,
- OM_DONE_BTN_PRESSED,
- OM_CANCEL_BTN_NORMAL,
- OM_CANCEL_BTN_MOUSEOVER,
- OM_CANCEL_BTN_PRESSED
-};
-
-
-enum SaveLoadSpriteType {
- SL_DIALOG_BOX,
- SL_EMPTY_THUMBNAIL,
-
- SL_SAVE_BTN_GREYED,
- SL_SAVE_BTN_NORMAL,
- SL_SAVE_BTN_MOUSEOVER,
- SL_SAVE_BTN_PRESSED,
-
- SL_LOAD_BTN_GREYED,
- SL_LOAD_BTN_NORMAL,
- SL_LOAD_BTN_MOUSEOVER,
- SL_LOAD_BTN_PRESSED,
-
- SL_CANCEL_BTN_NORMAL,
- SL_CANCEL_BTN_MOUSEOVER,
- SL_CANCEL_BTN_PRESSED,
-
- SL_UP_BTN_GREYED,
- SL_UP_BTN_NORMAL,
- SL_UP_BTN_MOUSEOVER,
- SL_UP_BTN_PRESSED,
-
- SL_DOWN_BTN_GREYED,
- SL_DOWN_BTN_NORMAL,
- SL_DOWN_BTN_MOUSEOVER,
- SL_DOWN_BTN_PRESSED,
-
- SL_SAVE_LABEL,
- SL_LOAD_LABEL,
-
- SL_SLIDER_BTN_NORMAL,
- SL_SLIDER_BTN_MOUSEOVER,
- SL_SLIDER_BTN_PRESSED,
-
- SL_LINE_NORMAL,
- SL_LINE_MOUSEOVER,
- SL_LINE_PRESSED,
-
- SL_SCROLLBAR
-};
-
-enum TextColors {
- TEXT_COLOR_NORMAL = 1,
- TEXT_COLOR_GREYED = 1,
- TEXT_COLOR_MOUSEOVER = 2,
- TEXT_COLOR_PRESSED = 2,
-
- TEXT_COLOR_GREYED_HILIGHT = 236,
- TEXT_COLOR_GREYED_FOREGROUND = 131,
- TEXT_COLOR_GREYED_SHADOW = 186,
-
- TEXT_COLOR_NORMAL_HILIGHT = 129,
- TEXT_COLOR_NORMAL_FOREGROUND = 130,
- TEXT_COLOR_NORMAL_SHADOW = 236,
-
- TEXT_COLOR_MOUSEOVER_HILIGHT = 129,
- TEXT_COLOR_MOUSEOVER_FOREGROUND = 130,
- TEXT_COLOR_MOUSEOVER_SHADOW = 236,
-
- TEXT_COLOR_PRESSED_HILIGHT = 236,
- TEXT_COLOR_PRESSED_FOREGROUND = 130,
- TEXT_COLOR_PRESSED_SHADOW = 129
-};
-
-#define MENU_SS_FIELD_NORMAL 5
-#define MENU_SS_FIELD_MOUSEOVER 6
-
-#define MENU_SS_H_SLIDER_NORMAL 5
-#define MENU_SS_H_SLIDER_MOUSE_OVER 6
-#define MENU_SS_H_SLIDER_PRESSED 7
-
-#define MENU_SS_SWITCH_ON_NORMAL 8
-#define MENU_SS_SWITCH_ON_MOUSEOVER 9
-#define MENU_SS_SWITCH_ON_PRESSED 13
-
-#define MENU_SS_SWITCH_OFF_PRESSED 10
-#define MENU_SS_SWITCH_OFF_NORMAL 11
-#define MENU_SS_SWITCH_OFF_MOUSEOVER 12
-
-#define MENU_GUI "gui menu"
-#define MENU_GAME "gamemenu"
-#define MENU_OPTIONS "opmenu"
-#define MENU_ERROR "errmenu"
-#define MENU_SAVELOAD "slmenu"
-#define MENU_BURGMAIN "903menu"
-#define MENU_BURGDEMOMAIN "901menu"
-
-#define SL_NUM_VISIBLE_SLOTS 8
-#define SL_THUMBNAIL_WIDTH 215
-#define SL_THUMBNAIL_HEIGHT 162
-
-enum MenuObjectState {OS_GREYED = 0, OS_NORMAL = 1, OS_MOUSEOVER = 2, OS_PRESSED = 3};
-
-class DialogView : public View {
-public:
- DialogView(MadsM4Engine *Vm, const Common::Rect &viewBounds, bool transparent = false):
- View(Vm, viewBounds, transparent) {}
- DialogView(MadsM4Engine *Vm, int x = 0, int y = 0, bool transparent = false):
- View(Vm, x, y, transparent) {}
-
- MadsM4Engine *vm() { return _vm; }
- virtual SpriteAsset *sprites() = 0;
- virtual MenuType getMenuType() = 0;
- virtual MenuObject *getItem(int objectId) { return NULL; }
- virtual void refresh(const Common::Rect &areaRect) {}
- virtual void close();
-
- int _topSaveSlotIndex, _selectedSlot;
- int _highlightedSlot;
- bool _deleteSaveDesc;
- M4Surface *_savegameThumbnail;
-};
-
-class GUIObject {
-protected:
- View *_parent;
- Common::Rect _bounds;
- M4Surface *_background;
-public:
- GUIObject(View *owner, const Common::Rect &bounds);
- virtual ~GUIObject() {}
-
- bool isInside(int x, int y) { return _bounds.contains(x, y); }
- Common::Rect getBounds() const { return _bounds; }
-
- virtual void onRefresh() {}
-};
-
-class MenuObject : public GUIObject {
-public:
- typedef void (*Callback)(DialogView *view, MenuObject *item);
-protected:
- MenuObject::Callback _callback;
- ObjectType _objectType;
- MenuObjectState _objectState;
- bool _transparent;
- int _objectId;
-public:
- MenuObject(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- bool greyed = false, bool transparent = false);
- ~MenuObject();
-
- DialogView *parent() { return (DialogView *)_parent; }
- MenuObjectState getState() { return _objectState; }
- virtual void setState(MenuObjectState state) {
- _objectState = state;
- onRefresh();
- }
- int getObjectId() { return _objectId; }
-
- void onExecute();
- virtual bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem) { return false; }
-};
-
-class MenuButton : public MenuObject {
-public:
- MenuButton(DialogView *owner, int buttonId, int xs, int ys, int width, int height,
- Callback callbackFn = NULL, bool greyed = false, bool transparent = false,
- ObjectType buttonType = OBJTYPE_BUTTON);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- bool getToggled() { return _objectType == OBJTYPE_OM_SWITCH_ON; }
-};
-
-enum MenuHorizSliderState {HSLIDER_THUMB_NORMAL = 0, HSLIDER_THUMB_MOUSEOVER = 1, HSLIDER_THUMB_PRESSED = 2};
-#define SLIDER_BAR_COLOR 129
-
-class MenuHorizSlider : public MenuObject {
-protected:
- MenuHorizSliderState _sliderState;
- Common::Point _thumbSize;
- int _maxThumbX;
- int _percent;
- int _thumbX;
-public:
- MenuHorizSlider(DialogView *owner, int sliderId, int xs, int ys, int width, int height,
- int initialPercentage, Callback callbackFn = NULL, bool transparent = false);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- int percent() { return _percent; }
-};
-
-enum MenuVertSliderState {
- VSLIDER_NONE = 0x0000,
- VSLIDER_UP = 0x0010,
- VSLIDER_PAGE_UP = 0x0020,
- VSLIDER_THUMBNAIL = 0x0030,
- VSLIDER_PAGE_DOWN = 0x0040,
- VSLIDER_DOWN = 0x0050
-};
-
-class MenuVertSlider : public MenuObject {
-protected:
- MenuVertSliderState _sliderState;
- Common::Point _thumbSize;
- int _percent;
- int _thumbY;
- int _minThumbY;
- int _maxThumbY;
-
- MenuVertSliderState getSliderArea(int y);
- void updateThumbnails() {}
-public:
- MenuVertSlider(DialogView *owner, int sliderId, int xs, int ys, int width, int height,
- int initialPercentage, Callback callbackFn = NULL, bool transparent = false);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- MenuVertSliderState sliderState() { return _sliderState; }
- int percent() { return _percent; }
- void setPercentage(int value);
-};
-
-class MenuMessage : public MenuObject {
-public:
- MenuMessage(DialogView *owner, int objectId, int x, int y, int w, int h, bool transparent = false);
-
- void onRefresh();
-};
-
-class MenuImage : public MenuObject {
-private:
- M4Surface *_sprite;
-public:
- MenuImage(DialogView *owner, int objectId, int xs, int ys, int width, int height,
- M4Surface *image, bool transparent = false);
-
- void onRefresh();
- const M4Surface *sprite() { return _sprite; }
- void setSprite(M4Surface *v) {
- _sprite = v;
- onRefresh();
- }
-};
-
-class MenuSaveLoadText : public MenuButton {
-private:
- bool _loadFlag;
- const char *_displayText;
- int _displayValue;
- int _index;
- bool _visible;
-public:
- MenuSaveLoadText(DialogView *owner, int textId, int xs, int ys, int width, int height,
- Callback callbackFn = NULL, bool greyed = false, bool transparent = false,
- bool loadFlag = false, const char *displayText = NULL, int displayValue = 0);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
- void setDisplay(int value, const char *text) { _displayValue = value; _displayText = text; }
- int getIndex() { return _index; }
- const char *getText() { return _displayText; }
- bool getVisible() const { return _visible; }
- void setVisible(bool value);
-};
-
-class MenuTextField : public MenuObject {
-private:
- int _displayValue;
- char _displayText[MAX_SAVEGAME_NAME];
- int _pixelWidth;
- char *_promptEnd;
- char *_cursor;
-public:
- MenuTextField(DialogView *owner, int fieldId, int xs, int ys, int width, int height,
- bool greyed, Callback callbackFn = NULL, const char *displayText = NULL,
- int displayValue = 0, bool transparent = true);
-
- void onRefresh();
- bool onEvent(M4EventType event, int32 param, int x, int y, MenuObject *&currentItem);
-
- const char *getText() { return _displayText; }
- int getDisplayValue() { return _displayValue; }
-
-};
-
-class GUIRect : public GUIObject {
-private:
- int _tag;
-public:
- GUIRect(View *owner, const Common::Rect &bounds, int tag): GUIObject(owner, bounds) { _tag = tag; }
-
- virtual bool onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) { return false; }
- int getTag() const { return _tag; }
-};
-
-enum GUIButtonState {BUTTON_NORMAL, BUTTON_MOUSEOVER, BUTTON_PRESSED};
-
-class GUIButton : public GUIRect {
-protected:
- M4Surface *_normalSprite, *_mouseOverSprite, *_pressedSprite;
- GUIButtonState _buttonState;
- bool _visible;
- bool _tracking;
-public:
- GUIButton(View *owner, const Common::Rect &bounds, int tag,
- M4Surface *normalSprite, M4Surface *mouseOverSprite, M4Surface *pressedSprite);
-
- void onRefresh();
- bool onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem);
- GUIButtonState getState() const { return _buttonState; }
-};
-
-class GUITextField : public GUIRect {
-private:
- Common::String _text;
-public:
- GUITextField(View *owner, const Common::Rect &bounds);
- void setText(const char *value) {
- _text = value;
- onRefresh();
- }
-
- void onRefresh();
-};
-
-
-class Dialogs {
-public:
- void keyMouseCollision() {}
-};
-
-class GameInterfaceView : public View {
-public:
- GameInterfaceView(MadsM4Engine *vm, const Common::Rect &rect): View(vm, rect) {}
- ~GameInterfaceView() {}
-
- virtual void initialize() {}
- virtual void setSelectedObject(int objectNumber) {}
- virtual void addObjectToInventory(int objectNumber) {}
-};
-
-}
-
-#endif
diff --git a/engines/m4/hotspot.cpp b/engines/m4/hotspot.cpp
deleted file mode 100644
index a424d9fa23..0000000000
--- a/engines/m4/hotspot.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/m4.h"
-#include "m4/events.h"
-#include "m4/hotspot.h"
-#include "gui/debugger.h"
-
-namespace M4 {
-
-/*
- HotSpot
-*/
-
-HotSpot::HotSpot(int x1, int y1, int x2, int y2) :
- _vocab(NULL), _verb(NULL), _prep(NULL), _sprite(NULL) {
-
- _rect.left = x1;
- _rect.top = y1;
- _rect.right = x2 + 1;
- _rect.bottom = y2 + 1;
- _active = true;
-
- _syntax = 0;
- _cursor = 0;
- _facing = 5;
- _feetX = 32767;
- _feetY = 32767;
-}
-
-HotSpot::~HotSpot() {
- free(_vocab);
-}
-
-void HotSpot::setRect(int x1, int y1, int x2, int y2) {
- _rect.left = x1;
- _rect.top = y1;
- _rect.right = x2 + 1;
- _rect.bottom = y2 + 1;
-}
-
-void HotSpot::setFeet(int x, int y) {
- _feetX = x;
- _feetY = y;
-}
-
-void HotSpot::setVocab(const char *value) {
- free(_vocab);
- _vocab = strdup(value);
-}
-
-void HotSpot::setVerb(const char *value) {
- free(_verb);
- _verb = strdup(value);
-}
-
-void HotSpot::setPrep(const char *value) {
- free(_prep);
- _prep = strdup(value);
-}
-
-void HotSpot::setSprite(const char *value) {
- free(_sprite);
- _sprite = strdup(value);
-}
-
-Common::Rect HotSpot::getRect() const {
- Common::Rect tempRect;
- tempRect.left = _rect.left;
- tempRect.top = _rect.top;
- tempRect.right = _rect.right - 1;
- tempRect.bottom = _rect.bottom - 1;
-
- return tempRect;
-}
-
-/*
- HotSpotList
-*/
-
-HotSpotList::HotSpotList() {
-}
-
-HotSpotList::~HotSpotList() {
- clear();
-}
-
-int HotSpotList::add(HotSpot *hotspot, bool head) {
- if (head || _hotspots.size() == 0) {
- _hotspots.insert_at(0, hotspot);
- return 0;
- } else {
- int32 area = hotspot->area();
- int index = _hotspots.size();
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (area < _hotspots[i]->area()) {
- index = i;
- break;
- }
- }
- _hotspots.insert_at(index, hotspot);
- return index;
- }
-}
-
-void HotSpotList::remove(HotSpot *hotspot) {
- unlinkItem(hotspot);
- delete hotspot; //TODO: check this?
-}
-
-void HotSpotList::unlinkItem(HotSpot *hotspot) {
- uint index = 0;
- while (index < _hotspots.size()) {
- if (_hotspots[index] == hotspot) {
- _hotspots.remove_at(index);
- } else {
- index++;
- }
- }
-}
-
-void HotSpotList::clear() {
- for (uint i = 0; i < _hotspots.size(); i++)
- delete _hotspots[i];
- _hotspots.clear();
-}
-
-HotSpot *HotSpotList::findByXY(int x, int y) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (_hotspots[i]->getActive() && _hotspots[i]->pointInside(x, y)) {
- return _hotspots[i];
- }
- }
- return NULL;
-}
-
-void HotSpotList::setActive(const char *name, bool active) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (!scumm_stricmp(_hotspots[i]->_vocab, name)) {
- _hotspots[i]->setActive(active);
- }
- }
-}
-
-void HotSpotList::setActiveXY(const char *name, int x, int y, bool active) {
- for (uint i = 0; i < _hotspots.size(); i++) {
- if (_hotspots[i]->pointInside(x, y) && !scumm_stricmp(_hotspots[i]->_vocab, name)) {
- _hotspots[i]->setActive(active);
- }
- }
-}
-
-void HotSpotList::dump() {
- _vm->_events->getConsole()->DebugPrintf("%d hotspots in the list\n", _hotspots.size());
-
- for (uint index = 0; index < _hotspots.size(); index++) {
- _vm->_events->getConsole()->DebugPrintf("(%d): %p x1 = %d; y1 = %d; x2 = %d; y2 = %d\n",
- index, (void *)_hotspots[index],
- _hotspots[index]->_rect.left, _hotspots[index]->_rect.top,
- _hotspots[index]->_rect.right - 1, _hotspots[index]->_rect.bottom - 1);
- }
-}
-
-uint32 HotSpotList::readHotSpotInteger(Common::SeekableReadStream* hotspotStream) {
- if (_vm->isM4())
- return hotspotStream->readSint32LE();
- else
- return hotspotStream->readSint16LE();
-}
-
-void HotSpotList::loadHotSpots(Common::SeekableReadStream* hotspotStream, int hotspotCount) {
- HotSpot *currentHotSpot;
- uint32 x1, y1, x2, y2;
- char buffer[256];
- uint32 strLength = 0;
- uint32 index = 0;
- int feetX, feetY;
- int cursorOffset = (_vm ->isM4()) ? 0 : 1;
-
- for (int i = 0; i < hotspotCount; i++) {
- x1 = readHotSpotInteger(hotspotStream);
- y1 = readHotSpotInteger(hotspotStream);
- x2 = readHotSpotInteger(hotspotStream);
- y2 = readHotSpotInteger(hotspotStream);
- index = add(new HotSpot(x1, y1, x2, y2), i == 0);
- currentHotSpot = get(index);
- currentHotSpot->setIndex(index);
- feetX = readHotSpotInteger(hotspotStream);
- feetY = readHotSpotInteger(hotspotStream);
- currentHotSpot->setFeet(feetX, feetY);
- currentHotSpot->setFacing((uint8)hotspotStream->readByte());
- currentHotSpot->setActive(hotspotStream->readByte() != 0);
-
- if (!_vm->isM4())
- hotspotStream->readByte(); // unused (always 255)
-
- index = hotspotStream->readByte(); // cursor
- if (index == 0)
- currentHotSpot->setCursor(0);
- else
- currentHotSpot->setCursor(index - cursorOffset);
-
- // Rex Nebular doesn't have this field
- if (!_vm->isM4() && _vm->getGameType() != GType_RexNebular) {
- // This looks to be some sort of bitmask. Perhaps it signifies
- // the valid verbs for this hotspot
- index = hotspotStream->readUint16LE(); // unknown
- //debugC(kDebugCore, "%i ", index);
- }
-
- if (_vm->isM4())
- hotspotStream->readByte(); // syntax (unused)
-
- currentHotSpot->setVocabID(readHotSpotInteger(hotspotStream));
- currentHotSpot->setVerbID(readHotSpotInteger(hotspotStream));
-
- // Load hotspot related strings (verb, vocab/noun etc)
- // These are loaded inside the hotspot data in M4 games,
- // and inside the global vocab data (vocab.dat) in MADS games
- if (_vm->isM4()) {
- strLength = hotspotStream->readUint32LE(); // vocabLength
- hotspotStream->read(buffer, strLength); // vocab (the hotspot's name)
- // Capitalize the hotspot's name here
- str_upper(buffer);
- currentHotSpot->setVocab(buffer);
- // Verbs are used internally by the game scripts in Orion Burger
- strLength = hotspotStream->readUint32LE(); // verbLength
- hotspotStream->read(buffer, strLength); // verb
- // Capitalize the hotspot's verb here
- str_upper(buffer);
- currentHotSpot->setVerb(buffer);
-
- /* Hotspot names for non-English versions are stored in prep.
- Prep can be set two ways: For English versions, copy the
- text from vocab. For non-English versions, use the prep text
- from the room file.
- */
- strLength = hotspotStream->readUint32LE(); // prepLength
- hotspotStream->read(buffer, strLength); // prep
- str_upper(buffer);
-
- if (buffer[0] != '\0' && strcmp(buffer, "--") != 0 && strcmp(buffer, "ON") != 0)
- currentHotSpot->setPrep(buffer);
- else
- currentHotSpot->setPrep(currentHotSpot->getVocab());
-
- // The following values are not used at all by Orion Burger
- strLength = hotspotStream->readUint32LE(); // spriteLength
- hotspotStream->read(buffer, strLength); // sprite
- hotspotStream->readUint16LE(); // sprite hash
- } else {
- currentHotSpot->setVocab("");
- currentHotSpot->setVerb("");
-
- if (currentHotSpot->getVocabID() > 0)
- currentHotSpot->setVocab(_madsVm->globals()->getVocab(currentHotSpot->getVocabID()));
-
- if (currentHotSpot->getVerbID() > 0)
- currentHotSpot->setVerb(_madsVm->globals()->getVocab(currentHotSpot->getVerbID()));
- }
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/hotspot.h b/engines/m4/hotspot.h
deleted file mode 100644
index 86fe21bcab..0000000000
--- a/engines/m4/hotspot.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_HOTSPOT_H
-#define M4_HOTSPOT_H
-
-#include "common/array.h"
-#include "common/rect.h"
-#include "common/util.h"
-
-/*
- TODO:
- - check if hotspot_duplicate is needed
- NOTES:
- - hotspot_add_dynamic unused in Orion Burger
-*/
-
-//???: should String be used instead of char* here?
-
-namespace M4 {
-
-class HotSpot {
- friend class HotSpotList;//just for debugging, to be removed later
-public:
-
- HotSpot(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0);
- ~HotSpot();
-
- void setVocab(const char *value);
- void setVocabID(int32 value) { _vocabID = value; }
- void setVerb(const char *value);
- void setVerbID(int32 value) { _verbID = value; }
- void setPrep(const char *value);
- void setSprite(const char *value);
- void setActive(bool value) { _active = value; }
- void setCursor(uint8 value) { _cursor = value; }
- void setRect(int x1, int y1, int x2, int y2);
- void setFeet(int x, int y);
- void setFacing(uint8 facing) { _facing = facing; }
- void setArticle(int8 v) { _articleNumber = v; }
- char *getVocab() const { return _vocab; }
- int32 getVocabID() { return _vocabID; }
- char *getVerb() const { return _verb; }
- int32 getVerbID() { return _verbID; }
- char *getPrep() const { return _prep; }
- char *getSprite() const { return _sprite; }
- uint8 getCursor() const { return _cursor; }
- bool getActive() const { return _active; }
- uint8 getFacing() const { return _facing; }
- int getFeetX() { return _feetX; }
- int getFeetY() { return _feetY; }
- int8 getArticle() const { return _articleNumber; }
- Common::Rect getRect() const;
- int getIndex() const { return _index; }
- void setIndex(int index) { _index = index; }
-
- int32 area() const { return (_rect.width() - 1) * (_rect.height() - 1); }
- bool pointInside(int x, int y) { return _rect.contains(x, y); }
-
-private:
- char *_vocab, *_verb, *_prep, *_sprite;
- Common::Rect _rect;
- bool _active;
- int _feetX, _feetY;
- uint8 _facing, _cursor;
- int _index;
-
- // Unused in Orion Burger, used in MADS games
- uint8 _syntax;
- int32 _vocabID, _verbID;
- int8 _articleNumber;
-
- //TODO: check if this is actually needed by the game
- int16 _hash;
-};
-
-class HotSpotList {
-public:
- HotSpotList();
- ~HotSpotList();
-
- int add(HotSpot *hotspot, bool head = false);
- HotSpot *get(int index) { return _hotspots[index]; }
- HotSpot &operator[](int idx) { return *get(idx); }
- int size() const { return _hotspots.size(); }
- void remove(HotSpot *hotspot);
- void unlinkItem(HotSpot *hotspot);
- void clear();
- HotSpot *findByXY(int x, int y);
- void setActive(const char *name, bool active);
- void setActiveXY(const char *name, int x, int y, bool active);
-
- void dump();
-
- void loadHotSpots(Common::SeekableReadStream* hotspotStream, int hotspotCount);
-
- uint32 readHotSpotInteger(Common::SeekableReadStream* hotspotStream);
-private:
- typedef Common::Array<HotSpot*> HotSpotArray;
- HotSpotArray _hotspots;
-};
-
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
deleted file mode 100644
index efc7943114..0000000000
--- a/engines/m4/m4.cpp
+++ /dev/null
@@ -1,606 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-//#define SCRIPT_TEST
-//#define INTRO_TEST
-
-#include "m4/globals.h"
-#include "m4/burger_data.h"
-#include "m4/m4.h"
-#include "m4/resource.h"
-#include "m4/hotspot.h"
-#include "m4/font.h"
-#include "m4/rails.h"
-#include "m4/midi.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/woodscript.h"
-#include "m4/actor.h"
-#include "m4/sound.h"
-#include "m4/script.h"
-#include "m4/compression.h"
-#include "m4/animation.h"
-#include "m4/m4_menus.h"
-#include "m4/m4_views.h"
-#include "m4/mads_anim.h"
-#include "m4/mads_menus.h"
-
-#include "common/error.h"
-#include "common/file.h"
-#include "common/fs.h"
-#include "common/system.h"
-#include "common/config-manager.h"
-#include "common/debug-channels.h"
-#include "common/textconsole.h"
-#include "engines/util.h"
-
-namespace M4 {
-
-// FIXME: remove global
-MadsM4Engine *_vm;
-MadsEngine *_madsVm;
-M4Engine *_m4Vm;
-
-void escapeHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // For now, simply exit the game
- vm->_events->quitFlag = true;
-}
-
-// Temporary hotkey handler for use in testing the TextviewView class
-
-void textviewHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // Deactivate the scene if it's currently active
- View *sceneView = vm->_viewManager->getView(VIEWID_SCENE);
- if (sceneView != NULL)
- vm->_viewManager->deleteView(sceneView);
-
- // Activate the textview view
- vm->_font->setFont(FONT_CONVERSATION_MADS);
- TextviewView *textView = new TextviewView(vm);
- vm->_viewManager->addView(textView);
- textView->setScript("quotes", NULL);
-}
-
-void saveGameHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // TODO: See CreateF2SaveMenu - save menu should only be activated when
- // certain conditions are met, such as player_commands_allowed, and isInterfaceVisible
- vm->loadMenu(SAVE_MENU, true);
-}
-
-void loadGameHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- // TODO: See CreateF3LoadMenu - save menu should only be activated when
- // certain conditions are met, such as player_commands_allowed, and isInterfaceVisible
- vm->loadMenu(LOAD_MENU, true);
-}
-
-void gameMenuHotkeyHandler(MadsM4Engine *vm, View *view, uint32 key) {
- vm->loadMenu(GAME_MENU);
-}
-
-MadsM4Engine::MadsM4Engine(OSystem *syst, const M4GameDescription *gameDesc) :
- Engine(syst), _gameDescription(gameDesc) {
- // Setup mixer
- syncSoundSettings();
-
- // FIXME
- _vm = this;
- _madsVm = NULL;
-
- const Common::FSNode gameDataDir(ConfMan.get("path"));
-
- SearchMan.addSubDirectoryMatching(gameDataDir, "goodstuf");
- SearchMan.addSubDirectoryMatching(gameDataDir, "resource");
- SearchMan.addSubDirectoryMatching(gameDataDir, "option1");
-
- DebugMan.addDebugChannel(kDebugScript, "script", "Script debug level");
- DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics debug level");
- DebugMan.addDebugChannel(kDebugConversations, "conversations", "Conversations debugging");
- DebugMan.addDebugChannel(kDebugSound, "sound", "Sounds debug level");
- DebugMan.addDebugChannel(kDebugCore, "core", "Core debug level");
-
- _resourceManager = NULL;
- _globals = NULL;
-}
-
-
-MadsM4Engine::~MadsM4Engine() {
- delete _midi;
- delete _saveLoad;
- delete _kernel;
- delete _player;
- delete _mouse;
- delete _events;
- delete _font;
- delete _actor;
-// delete _scene; // deleted by the viewmanager
- delete _dialogs;
- delete _screen;
- delete _inventory;
- delete _viewManager;
- delete _rails;
- delete _script;
- delete _ws;
- delete _random;
- delete _palette;
- delete _globals;
- delete _sound;
- delete _resourceManager;
-}
-
-Common::Error MadsM4Engine::run() {
- // Initialize backend
- _screen = new M4Surface(true); // Special form for creating screen reference
-
- _midi = new MidiPlayer(this);
- _midi->setGM(true); // FIXME: Really? Always?
-
- _saveLoad = new SaveLoad(this);
- _palette = new Palette(this);
- _mouse = new Mouse(this);
- _events = new Events(this);
- _kernel = new Kernel(this);
- _player = new Player(this);
- _font = new FontManager(this);
- if (getGameType() == GType_Burger) {
- _actor = new Actor(this);
- _conversationView = new ConversationView(this);
- } else {
- _actor = NULL;
- }
- _rails = new Rails(); // needs to be initialized before _scene
- _dialogs = new Dialogs();
- _viewManager = new ViewManager(this);
- _inventory = new Inventory(this);
- _sound = new Sound(this, _mixer, 255);
- _script = new ScriptInterpreter(this);
- _ws = new WoodScript(this);
- //_callbacks = new Callbacks(this);
- _random = new Common::RandomSource("m4");
-
- return Common::kNoError;
-}
-
-void MadsM4Engine::eventHandler() {
- M4EventType event;
- uint32 keycode = 0;
-
- if ((event = _events->handleEvents()) != MEVENT_NO_EVENT) {
- if (_viewManager->containsViews())
- _viewManager->handleMouseEvents(event);
- }
-
- if (_events->kbdCheck(keycode))
- _viewManager->handleKeyboardEvents(keycode);
-}
-
-bool MadsM4Engine::delay(int duration, bool keyAborts, bool clickAborts) {
- uint32 endTime = g_system->getMillis() + duration;
- M4EventType event;
- uint32 keycode = 0;
-
- while (!_events->quitFlag && (g_system->getMillis() < endTime)) {
- event = _events->handleEvents();
- if (clickAborts && ((event == MEVENT_LEFT_RELEASE) || (event == MEVENT_RIGHT_RELEASE)))
- return true;
-
- if (_events->kbdCheck(keycode)) {
- if (keyAborts)
- return true;
- }
-
- g_system->delayMillis(10);
- }
-
- return false;
-}
-
-void MadsM4Engine::loadMenu(MenuType menuType, bool loadSaveFromHotkey, bool calledFromMainMenu) {
- if (isM4() && (menuType != MAIN_MENU)) {
- bool menuActive = _viewManager->getView(VIEWID_MENU) != NULL;
-
- if (!menuActive)
- _palette->fadeToGreen(M4_DIALOG_FADE_STEPS, M4_DIALOG_FADE_DELAY);
- }
-
- View *view;
-
- switch (menuType) {
- case MAIN_MENU:
- if (getGameType() == GType_RexNebular)
- view = new RexMainMenuView(this);
- else if (getGameType() == GType_DragonSphere)
- view = new DragonMainMenuView(this);
- else
- view = new MadsMainMenuView(this);
- break;
- case GAME_MENU:
- view = new OrionMenuView(this, 200, 100, GAME_MENU, calledFromMainMenu, loadSaveFromHotkey);
- break;
- case OPTIONS_MENU:
- view = new OrionMenuView(this, 172, 160, OPTIONS_MENU, calledFromMainMenu, loadSaveFromHotkey);
- break;
- case LOAD_MENU:
- case SAVE_MENU:
- view = new OrionMenuView(this, 145, 10, menuType, calledFromMainMenu, loadSaveFromHotkey);
- break;
- default:
- error("Unknown menu type");
- break;
- }
-
- _viewManager->addView(view);
- _viewManager->moveToFront(view);
-}
-
-#define DUMP_BUFFER_SIZE 1024
-
-void MadsM4Engine::dumpFile(const char *filename, bool uncompress) {
- Common::DumpFile f;
- byte buffer[DUMP_BUFFER_SIZE];
- Common::SeekableReadStream *fileS = res()->get(filename);
-
- if (!f.open(filename))
- error("Could not open '%s' for writing", filename);
-
- int bytesRead = 0;
- warning("Dumping %s, size: %i\n", filename, fileS->size());
-
- if (!uncompress) {
- while (!fileS->eos()) {
- bytesRead = fileS->read(buffer, DUMP_BUFFER_SIZE);
- f.write(buffer, bytesRead);
- }
- } else {
- MadsPack packData(fileS);
- Common::SeekableReadStream *sourceUnc;
- for (int i = 0; i < packData.getCount(); i++) {
- sourceUnc = packData.getItemStream(i);
- debugCN(kDebugCore, "Dumping compressed chunk %i of %i, size is %i\n", i + 1, packData.getCount(), sourceUnc->size());
- while (!sourceUnc->eos()) {
- bytesRead = sourceUnc->read(buffer, DUMP_BUFFER_SIZE);
- f.write(buffer, bytesRead);
- }
- delete sourceUnc;
- }
- }
-
- f.close();
- res()->toss(filename);
- res()->purge();
-}
-
-/*--------------------------------------------------------------------------*/
-
-M4Engine::M4Engine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4Engine(syst, gameDesc) {
- // FIXME
- _m4Vm = this;
-
- _globals = new M4Globals(this);
-}
-
-M4Engine::~M4Engine() {
- delete _converse;
-}
-
-Common::Error M4Engine::run() {
- // Set up the graphics mode
- initGraphics(640, 480, true);
-
- // Necessary pre-initialisation
- _resourceManager = new M4ResourceManager(this);
-
- // Set up needed common functionality
- MadsM4Engine::run();
-
- // M4 specific initialisation
- _converse = new Converse(this);
-
- _scene = new M4Scene(this);
- _script->open("m4.dat");
-
-#ifdef SCRIPT_TEST
-
-#if 0
- ScriptFunction *func = _script->loadFunction("room_parser_142");
- _script->runFunction(func);
-#endif
-
-#if 1
- ScriptFunction *func = _script->loadFunction("room_daemon_951");
- for (int i = 1; i < 58; i++) {
- _vm->_kernel->trigger = i;
- _script->runFunction(func);
- debugCN(kDebugCore, "=================================\n");
- }
-#endif
-
- return Common::kNoError;
-#endif
-
- // Set up the inventory
-
- // Set up the game interface view
- //_interfaceView->inventoryAdd("Money", "", 55); // Sample item
-
- if (getGameType() == GType_Burger) {
- for (int i = 0; i < ARRAYSIZE(burger_inventory); i++) {
- char* itemName = strdup(burger_inventory[i].name);
- _inventory->registerObject(itemName, burger_inventory[i].scene,
- burger_inventory[i].icon);
- _inventory->addToBackpack(i); // debug: this adds ALL objects to the player's backpack
- }
- }
-
- // Show intro
-
- if (getGameType() == GType_Burger) {
- _kernel->newRoom = TITLE_SCENE_BURGER;
- } else {
- _scene->getBackgroundSurface()->loadBackgroundRiddle("main menu");
- _ws->setBackgroundSurface(_scene->getBackgroundSurface());
- }
-
- _viewManager->addView(_scene);
-
- // Setup game wide hotkeys. Note that Orion Burger used F2/F3 for Save/Restore,
- // but for standardisation with most other games, F5/F7 are also mapped
-
- _viewManager->systemHotkeys().add(Common::KEYCODE_ESCAPE, &escapeHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F2, &saveGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F3, &loadGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F5, &saveGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F7, &loadGameHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_F9, &gameMenuHotkeyHandler);
-
- // Start playing Orion Burger intro music
- //_midi->playMusic("999intro", 255, false, -1, -1);
-
- // TODO: start playing intro animations
-
- // TODO: Master Lu
-
- // Test for mouse
- _mouse->init("cursor", NULL);
- _mouse->setCursorNum(0);
- _mouse->cursorOn();
-
- _ws->assets()->loadAsset("SHOW SCRIPT", NULL);
- _ws->assets()->loadAsset("STREAM SCRIPT", NULL);
-
-#ifdef INTRO_TEST
- int curPart = 0;
- Machine *mach = NULL;
-#endif
-
- _ws->setSurfaceView(_scene);
-
- uint32 nextFrame = g_system->getMillis();
- while (!_events->quitFlag) {
-
- // This should probably be moved to either Scene or Kernel
- if (_kernel->currentRoom != _kernel->newRoom) {
-
- _ws->clear();
-
- _kernel->currentSection = _kernel->newRoom / 100;
- _kernel->currentRoom = _kernel->newRoom;
-
- _scene->loadScene(_kernel->currentRoom);
-
- _ws->setBackgroundSurface(_scene->getBackgroundSurface());
- _ws->setInverseColorTable(scene()->getInverseColorTable());
-
- _kernel->loadSectionScriptFunctions();
- _kernel->loadRoomScriptFunctions();
-
- _kernel->roomInit();
-
- _scene->show();
-
-#ifdef INTRO_TEST
- if (_kernel->currentRoom == 951) {
- curPart = 0;
- mach = _ws->streamSeries("PLANET X HILLTOP A", 1, 0x1000, 0);
- }
-#endif
-
- }
-
- eventHandler();
-
- // Call the updateState method of all views
- _viewManager->updateState();
-
- // Handle frame updates
- if (g_system->getMillis() >= nextFrame) {
-#ifdef INTRO_TEST
- // Orion Burger intro test (scene 951)
- // This is ugly and bad, machine is not deleted so there's a huge memory
- // leak too. But hey, we can see some of the intro!
- if (mach && mach->getState() == -1) {
- if (curPart == 0)
- mach = _ws->streamSeries("Planet X Low Ground Shot", 1, 0x1000, 0);
- else if (curPart == 1)
- mach = _ws->streamSeries("Planet X Hilltop B", 1, 0x1000, 0);
- else if (curPart == 2)
- mach = _ws->streamSeries("Space Station Panorama A", 1, 0x1000, 0);
- else if (curPart == 3)
- mach = _ws->streamSeries("Cargo Transfer Area A", 1, 0x1000, 0);
- else if (curPart == 4)
- mach = _ws->streamSeries("VP's Office A", 1, 0x1000, 0);
- else if (curPart == 5)
- mach = _ws->streamSeries("Hologram", 1, 0x1000, 0);
- else if (curPart == 6)
- mach = _ws->streamSeries("VP's Office B", 1, 0x1000, 0);
- else if (curPart == 7)
- mach = _ws->streamSeries("Cargo Transfer Area B", 1, 0x1000, 0);
- else if (curPart == 8)
- mach = _ws->streamSeries("Cargo Transfer Controls", 1, 0x1000, 0);
- else if (curPart == 9)
- mach = _ws->streamSeries("Space Station Panorama B", 1, 0x1000, 0);
- // This last scene is from the rolling demo
- //else if (curPart == 10)
- // mach = _ws->streamSeries("Call To Action", 1, 0x1000, 0);
- curPart++;
- }
-#endif
- _ws->update();
- _viewManager->refreshAll();
- nextFrame = g_system->getMillis();// + GAME_FRAME_DELAY;
-
- // TEST STUFF ONLY
- if (_player->commandReady) {
- _kernel->roomParser();
- _player->commandReady = false;
- }
-
- }
-
- g_system->delayMillis(10);
- }
-
- return Common::kNoError;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsEngine::MadsEngine(OSystem *syst, const M4GameDescription *gameDesc): MadsM4Engine(syst, gameDesc) {
- // FIXME
- _madsVm = this;
-
- _globals = new MadsGlobals(this);
- _currentTimer = 0;
-}
-
-MadsEngine::~MadsEngine() {
-}
-
-Common::Error MadsEngine::run() {
- // Set up the graphics mode
- initGraphics(320, 200, false);
-
- // Necessary pre-initialisation
- _resourceManager = new MADSResourceManager(this);
-
- // Set up needed common functionality
- MadsM4Engine::run();
-
- _palette->setMadsSystemPalette();
-
- _mouse->init("cursor.ss", NULL);
- _mouse->setCursorNum(0);
-
- // Load MADS data files
- MadsGlobals *globs = (MadsGlobals *)_globals;
- globs->loadMadsVocab(); // vocab.dat
- globs->loadQuotes(); // quotes.dat
- globs->loadMadsMessagesInfo(); // messages.dat
- globs->loadMadsObjects();
-
- // Setup globals
- globs->_config.easyMouse = true;
- globs->_config.invObjectsStill = false;
- globs->_config.textWindowStill = false;
- globs->_config.storyMode = 1; // Naughty
- globs->_config.screenFades = 0;
-
- // Test code to dump all messages to the console
- //for (int i = 0; i < _globals->getMessagesSize(); i++)
- //debugCN(kDebugCore, "%s\n----------\n", _globals->loadMessage(i));
-
- if (getGameType() == GType_RexNebular) {
- MadsGameLogic::initializeGlobals();
-
- _scene = NULL;
- loadMenu(MAIN_MENU);
- } else {
- // Test code
- _scene = new MadsScene(this);
-
- startScene(FIRST_SCENE);
- RGBList *_bgPalData;
- _scene->loadBackground(FIRST_SCENE, &_bgPalData);
- _palette->addRange(_bgPalData);
- _scene->translate(_bgPalData);
-
- _scene->show();
-
- _font->setFont(FONT_MAIN_MADS);
- _font->current()->setColors(2, 1, 3);
- _font->current()->writeString(_scene->getBackgroundSurface(), "Testing the M4/MADS ScummVM engine", 5, 160, 310, 2);
- _font->current()->writeString(_scene->getBackgroundSurface(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 5, 180, 310, 2);
-
- if (getGameType() == GType_DragonSphere) {
- //_scene->showMADSV2TextBox("Test", 10, 10, NULL);
- }
-
- _mouse->cursorOn();
- }
-
- _viewManager->systemHotkeys().add(Common::KEYCODE_ESCAPE, &escapeHotkeyHandler);
- _viewManager->systemHotkeys().add(Common::KEYCODE_KP_MULTIPLY, &textviewHotkeyHandler);
-
- uint32 nextFrame = g_system->getMillis();
- while (!_events->quitFlag) {
- eventHandler();
-
- if (g_system->getMillis() >= nextFrame) {
- nextFrame = g_system->getMillis() + GAME_FRAME_DELAY;
- ++_currentTimer;
-
- // Call the updateState method of all views
- _viewManager->updateState();
-
- // Refresh the display
- _viewManager->refreshAll();
- }
-
- g_system->delayMillis(10);
-
- if (globals()->dialogType != DIALOG_NONE)
- showDialog();
- }
-
- return Common::kNoError;
-}
-
-void MadsEngine::showDialog() {
- // Switch to showing the given dialog
- RexDialogView *dlg = NULL;
- switch (globals()->dialogType) {
- case DIALOG_GAME_MENU:
- dlg = new RexGameMenuDialog();
- break;
- case DIALOG_OPTIONS:
- dlg = new RexOptionsDialog();
- break;
- default:
- error("Unknown dialog type");
- };
-
- globals()->dialogType = DIALOG_NONE;
- _viewManager->addView(dlg);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/m4.h b/engines/m4/m4.h
deleted file mode 100644
index b40ba0e878..0000000000
--- a/engines/m4/m4.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_H
-#define M4_H
-
-#include "common/scummsys.h"
-#include "common/util.h"
-#include "common/random.h"
-
-#include "engines/engine.h"
-
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/resource.h"
-#include "m4/saveload.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/scene.h"
-#include "m4/mads_player.h"
-#include "m4/mads_scene.h"
-#include "m4/m4_scene.h"
-#include "m4/actor.h"
-#include "m4/sound.h"
-#include "m4/rails.h"
-#include "m4/converse.h"
-#include "m4/animation.h"
-
-//#define DUMP_SCRIPTS
-
-/**
- * This is the namespace of the M4 engine.
- *
- * Status of this engine:
- * This engine is eventually intended to compromise two evolutions of the same engine: 'MADS' for the
- * first generation of the engine, and 'M4' for the second generation. This engine is called M4 overall
- * simply because work first began on the M4 side (focusing on the game 'Orion Burger').
- *
- * MADS Status: The current game being focused on is 'Rex Nebular' by DreamMaster, who is implementing
- * functionality as he disassembles the games original executables. Currently the engine has no particular
- * game logic implemented, although it does have the title screen implemented, and displays the initial
- * game screen and some game interface elements
- *
- * M4 Status: Work on this engine began with the game 'Orion Burger'. Some of the user interface
- * functionality has been implemented. No further work has been done on this for some time, so progress
- * on this part of the engine can be considered frozen.
- *
- * Games using this engine:
- * MADS Games: Dragonsphere, Return of the Phantom, Rex Nebular and the Cosmic Gender Bender
- * M4 Games: Orion Burger, The Riddle of Master Lu
- */
-namespace M4 {
-
-class MidiPlayer;
-class FileSystem;
-class ResourceManager;
-class Mouse;
-class Events;
-class Scene;
-class ViewManager;
-class View;
-class Inventory;
-class M4InterfaceView;
-class ConversationView;
-class Actor;
-class Converse;
-class MadsConversation;
-class ScriptInterpreter;
-class WoodScript;
-class Animation;
-
-enum M4GameType {
- GType_Riddle = 1,
- GType_Burger = 2,
- GType_RexNebular = 3,
- GType_DragonSphere = 4,
- GType_Phantom = 5
-};
-
-enum Features {
- kFeaturesNone = 0,
- kFeaturesCD = 1 << 0,
- kFeaturesDemo = 1 << 1
-};
-
-enum {
- kFileTypeHash,
- kFileTypeHAG
-};
-
-enum {
- kDebugScript = 1 << 0,
- kDebugConversations = 1 << 1,
- kDebugGraphics = 1 << 2,
- kDebugSound = 1 << 3,
- kDebugCore = 1 << 4
-};
-
-#define MESSAGE_BASIC 1
-#define MESSAGE_INTERMEDIATE 2
-#define MESSAGE_DETAILED 3
-
-struct M4GameDescription;
-
-#define GAME_FRAME_DELAY 20
-
-#define VALIDATE_MADS assert(!_vm->isM4())
-
-inline void str_lower(char *s) { while (*s) { *s = tolower(*s); s++; } }
-inline void str_upper(char *s) { while (*s) { *s = toupper(*s); s++; } }
-
-inline long FixedMul(long a, long b) { return (long)(((float)a * (float)b) / 65536.0); }
-inline long FixedDiv(long a, long b) { return (long)(((float)a / (float)b) * 65536.0); }
-
-class MadsM4Engine : public Engine {
-private:
- Common::Error goMADS();
- Common::Error goM4();
-
-protected:
- // Engine APIs
- virtual Common::Error run();
-
- void shutdown();
-
- MidiPlayer *_midi;
-
-public:
- MadsM4Engine(OSystem *syst, const M4GameDescription *gameDesc);
- virtual ~MadsM4Engine();
-
- int getGameType() const;
- uint32 getFeatures() const;
- Common::Language getLanguage() const;
- Common::Platform getPlatform() const;
- bool isM4() const { return (getGameType() == GType_Riddle) || (getGameType() == GType_Burger); }
-
- const char *getGameFile(int fileType);
- Common::EventManager *eventMan() { return _eventMan; }
-
- const M4GameDescription *_gameDescription;
-
- ResourceManager *res() const { return _resourceManager; }
- MidiPlayer *midi() { return _midi; }
- Common::SaveFileManager *saveManager() { return _saveFileMan; }
- void dumpFile(const char *filename, bool uncompress);
- void eventHandler();
- bool delay(int duration, bool keyAborts = true, bool clickAborts = true);
- void loadMenu(MenuType menuType, bool loadSaveFromHotkey = false,
- bool calledFromMainMenu = false);
-
- // TODO: eventually these have to be removed
- int32 seed;
- void imath_seed(int32 seednum) { seed = seednum; }
- uint32 imath_random() { return(seed = (25173*seed + 13849) & 0xffff); }
- int32 imath_ranged_rand(int32 a, int32 b) { return (a + (((1 + ABS<int32>(b-a))*imath_random())>>16)); }
- long imath_ranged_rand16(long a, long b) { return ((a + FixedMul(1+ABS<int32>(b-a),imath_random()))); }
- //
-
- ResourceManager *_resourceManager;
- Globals *_globals;
-
- SaveLoad *_saveLoad;
- ViewManager *_viewManager;
- Palette *_palette;
- Kernel *_kernel;
- Player *_player;
- Mouse *_mouse;
- Events *_events;
- FontManager *_font;
- Actor *_actor;
- Scene *_scene;
- Dialogs *_dialogs;
- M4Surface *_screen;
- Inventory *_inventory;
- ConversationView *_conversationView;
- Sound *_sound;
- Rails *_rails;
- ScriptInterpreter *_script;
- WoodScript *_ws;
- Common::RandomSource *_random;
-
- Scene *scene() { return _scene; }
-};
-
-class MadsEngine : public MadsM4Engine {
-private:
- void showDialog();
-public:
- MadsConversation _converse;
- uint32 _currentTimer;
- MadsPlayer _player;
-public:
- MadsEngine(OSystem *syst, const M4GameDescription *gameDesc);
- virtual ~MadsEngine();
-
- virtual Common::Error run();
-
- MadsGlobals *globals() { return (MadsGlobals *)_globals; }
- MadsScene *scene() { return (MadsScene *)_scene; }
- void startScene(int sceneNum) {
- if (!_scene) {
- _scene = new MadsScene(this);
- ((MadsScene *)_scene)->initialize();
- }
- _scene->show();
- _scene->loadScene(101);
- }
-};
-
-class M4Engine : public MadsM4Engine {
-public:
- Converse *_converse;
-public:
- M4Engine(OSystem *syst, const M4GameDescription *gameDesc);
- virtual ~M4Engine();
-
- virtual Common::Error run();
-
- M4Globals *globals() { return (M4Globals *)_globals; }
- M4Scene *scene() { return (M4Scene *)_scene; }
-};
-
-// FIXME: remove globals
-extern MadsM4Engine *_vm;
-extern MadsEngine *_madsVm;
-extern M4Engine *_m4Vm;
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/m4_menus.cpp b/engines/m4/m4_menus.cpp
deleted file mode 100644
index 3384a82c8b..0000000000
--- a/engines/m4/m4_menus.cpp
+++ /dev/null
@@ -1,724 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/algorithm.h" // for find()
-#include "common/textconsole.h"
-#include "common/translation.h"
-#include "gui/dialog.h"
-#include "gui/message.h"
-
-#include "m4/m4_menus.h"
-#include "m4/m4_views.h"
-#include "m4/woodscript.h"
-#include "m4/midi.h"
-
-namespace M4 {
-
-const char *EmptySaveString = "<empty>";
-
-//--------------------------------------------------------------------------
-// Callback methods
-//
-// Following is a set of callback methods used to handle the execution
-// of buttons in the various dialogs
-//--------------------------------------------------------------------------
-
-// General function which simply closes the active menu
-
-void OrionCallbacks::closeMenuFn(DialogView *view, MenuObject *item) {
- view->close();
-}
-
-void OrionCallbacks::closeMenuFn(OrionMenuView *view) {
- closeMenuFn(view, NULL);
-}
-
-/* Game menu functions */
-
-void OrionCallbacks::gameOptionsMenuFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(OPTIONS_MENU);
- view->close();
-}
-
-void OrionCallbacks::gameSaveGameFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(SAVE_MENU);
- view->close();
-}
-
-void OrionCallbacks::gameLoadGameFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(LOAD_MENU);
- view->close();
-}
-
-void OrionCallbacks::gameExitFn(DialogView *view, MenuObject *item) {
- view->vm()->_events->quitFlag = true;
- view->close();
-}
-
-/* Options menu */
-
-void OrionCallbacks::optionsDigiSliderFn(DialogView *view, MenuObject *item) {
- // Digi volume slider changed
- int percent = ((MenuHorizSlider *) item)->percent();
-
- view->vm()->_sound->setVolume(percent * 255 / 100);
-}
-
-void OrionCallbacks::optionsMidiSliderFn(DialogView *view, MenuObject *item) {
- // Midi volume slider changed
- int percent = ((MenuHorizSlider *) item)->percent();
-
- view->vm()->midi()->setVolume(percent * 255 / 100);
-}
-
-void OrionCallbacks::optionsScrollingFn(DialogView *view, MenuObject *item) {
- // TODO: Change current Digi volume settings here
-}
-
-void OrionCallbacks::optionsCancelFn(DialogView *view, MenuObject *item) {
- // TODO: Reset original option settings here
- OrionMenuView *vw = (OrionMenuView *) view;
-
- vw->vm()->midi()->setVolume(vw->_originalMidiVolume);
-
- vw->vm()->loadMenu(GAME_MENU);
- vw->close();
-}
-
-void OrionCallbacks::optionsDoneFn(DialogView *view, MenuObject *item) {
- view->vm()->loadMenu(GAME_MENU);
- view->close();
-}
-
-void OrionCallbacks::optionsReturnFn(OrionMenuView *view) {
- optionsDoneFn(view, NULL);
-}
-
-void OrionCallbacks::optionsEscapeFn(OrionMenuView *view) {
- optionsCancelFn(view, NULL);
-}
-
-/* Save/Load dialog functions */
-
-// Save the current game
-
-void OrionCallbacks::saveLoadSaveFn(DialogView *view, MenuObject *item) {
- if (view->_selectedSlot == -1)
- return;
-
- MenuTextField *textItem = (MenuTextField *) view->getItem(SLTAG_TEXTFIELD);
- if (!textItem)
- return;
-
- textItem->setState(OS_NORMAL);
-
- // Save the game
- bool succeeded = view->vm()->_saveLoad->save(view->_selectedSlot + 1, textItem->getText());
-
- if (!succeeded) {
- GUI::MessageDialog dialog(_("Save game failed!"));
- dialog.runModal();
- }
-
- // Close the menu
- closeMenuFn(view, item);
-}
-
-void OrionCallbacks::saveLoadLoadFn(DialogView *view, MenuObject *item) {
- // TODO: load the selected save game
- closeMenuFn(view, item);
-}
-
-void OrionCallbacks::saveLoadSlotFn(DialogView *view, MenuObject *item) {
- OrionMenuView *vw = (OrionMenuView *) view;
- MenuSaveLoadText *button = (MenuSaveLoadText *) item;
-
- view->_selectedSlot = button->getIndex();
- view->_deleteSaveDesc = true;
-
- // Disable all the slots except the selected one
- for (int index = 0; index < SL_NUM_VISIBLE_SLOTS; ++index) {
- MenuSaveLoadText *currentItem = (MenuSaveLoadText *) view->getItem(SLTAG_SLOTS_START + index);
- if (currentItem->getIndex() != button->getIndex()) {
- currentItem->setState(OS_GREYED);
- }
- }
-
- // Get a copy of the slot bounds
- Common::Rect slotBounds = button->getBounds();
-
- if (view->getMenuType() == SAVE_MENU) {
- // Add in a text field for entry of the savegame name
- vw->items().push_back(new MenuTextField(view, SLTAG_TEXTFIELD,
- slotBounds.left, slotBounds.top, slotBounds.width(), slotBounds.height(), false,
- saveLoadSaveFn, (button->getText() == EmptySaveString) ? NULL : button->getText(),
- button->getIndex() + 1));
-
- } else {
- vw->items().push_back(new MenuTextField(view, SLTAG_TEXTFIELD,
- slotBounds.left, slotBounds.top, slotBounds.width(), slotBounds.height(), true,
- saveLoadLoadFn, button->getText(), button->getIndex() + 1));
- }
-
- // Hide the existing slot
- button->setVisible(false);
-
- // Disable the slider
-
- MenuVertSlider *slider = (MenuVertSlider *) view->getItem(SLTAG_VSLIDER);
- slider->setState(OS_GREYED);
-
- // Enable the save/load button
- MenuButton *btn = (MenuButton *) view->getItem(SLTAG_SAVELOAD);
- btn->setState(OS_NORMAL);
-}
-
-void OrionCallbacks::saveLoadCancelFn(DialogView *view, MenuObject *item) {
- OrionMenuView *vw = (OrionMenuView *) view;
-
- if (view->_selectedSlot != -1) {
- // Pressed cancel with a save selected, so revert back to no selection
-
- // Re-enable all the other slots
-
- for (int index = 0; index < SL_NUM_VISIBLE_SLOTS; ++index) {
- if (index != view->_selectedSlot) {
- MenuSaveLoadText *currentItem = (MenuSaveLoadText *) view->getItem(SLTAG_SLOTS_START + index);
- currentItem->setState(OS_NORMAL);
- }
- }
-
- // Show the previously hidden slot again
- MenuSaveLoadText *slot = (MenuSaveLoadText *) view->getItem(SLTAG_SLOTS_START + view->_selectedSlot);
- slot->setVisible(true);
- slot->setState(OS_NORMAL);
-
- // Remove the text selection
- MenuTextField *textField = (MenuTextField *) view->getItem(SLTAG_TEXTFIELD);
- delete textField;
- vw->items().remove(textField);
-
- // Set button enablement
- MenuButton *btn = (MenuButton *) view->getItem(SLTAG_SAVELOAD);
- btn->setState(OS_GREYED);
- btn = (MenuButton *) view->getItem(SLTAG_CANCEL);
- btn->setState(OS_NORMAL);
-
- // Re-enable the slider
-
- MenuVertSlider *slider = (MenuVertSlider *) view->getItem(SLTAG_VSLIDER);
- slider->setState(OS_NORMAL);
-
- view->_selectedSlot = -1;
-
- } else {
- // Close the dialog
- if (vw->_loadSaveFromHotkey)
- // Since dialog was called from hotkey, return directly to the game
- closeMenuFn(view, item);
- else {
- // Return to the game menu
- view->vm()->loadMenu(GAME_MENU);
- view->close();
- }
- }
-}
-
-void OrionCallbacks::saveLoadSliderFn(DialogView *view, MenuObject *item) {
- OrionMenuView *vw = (OrionMenuView *) view;
- MenuVertSlider *slider = (MenuVertSlider *) item;
-
- if (slider->sliderState() == VSLIDER_THUMBNAIL) {
- // Callback generated by slider thumb, so set top slot using slider percentage
- vw->setTopSaveSlot(slider->percent() * 89 / 100);
-
- } else {
- int newIndex = view->_topSaveSlotIndex;
-
- switch (slider->sliderState()) {
- case VSLIDER_UP:
- if (newIndex > 0)
- --newIndex;
- break;
-
- case VSLIDER_PAGE_UP:
- if (newIndex > 0)
- newIndex = MAX(newIndex - 10, 0);
- break;
-
- case VSLIDER_PAGE_DOWN:
- if (newIndex < 89)
- newIndex = MIN(newIndex + 10, 89);
- break;
-
- case VSLIDER_DOWN:
- if (newIndex < 89)
- ++newIndex;
- break;
-
- default:
- break;
- }
-
- if (newIndex != view->_topSaveSlotIndex) {
- // Set the new top slot
- vw->setTopSaveSlot(newIndex);
-
- // Set the new slider position
- slider->setPercentage(newIndex * 100 / 89);
- }
- }
-}
-
-void OrionCallbacks::saveLoadEscapeFn(OrionMenuView *view) {
- saveLoadCancelFn(view, NULL);
-}
-
-void OrionCallbacks::saveLoadReturnFn(OrionMenuView *view) {
- MenuTextField *textItem = (MenuTextField *) view->getItem(SLTAG_TEXTFIELD);
- if (textItem) {
- if (view->getMenuType() == SAVE_MENU)
- saveLoadSaveFn(view, NULL);
- else
- saveLoadLoadFn(view, NULL);
- }
-}
-
-//--------------------------------------------------------------------------
-
-OrionMenuView::OrionMenuView(MadsM4Engine *Vm, int x, int y, MenuType menuType, bool calledFromMainMenu,
- bool loadSaveFromHotkey): DialogView(Vm, x, y, true) {
- _menuType = menuType;
- _screenType = VIEWID_MENU;
- _screenFlags.layer = LAYER_MENU;
- _screenFlags.get = SCREVENT_ALL;
- _screenFlags.blocks = SCREVENT_ALL;
- _screenFlags.immovable = true;
- //_screenFlags.immovable = false; // uncomment to make menu movable
- _coords.left = x;
- _coords.top = y;
- _currentItem = NULL;
- _escapeHandler = &OrionCallbacks::closeMenuFn;
- _returnHandler = NULL;
- _saveNames = NULL;
- _savegameThumbnail = NULL;
- _deleteSaveDesc = false;
- _closeFlag = false;
-
- _calledFromMainMenu = calledFromMainMenu;
- _loadSaveFromHotkey = loadSaveFromHotkey;
-
- _interfaceWasVisible = _m4Vm->scene()->getInterface()->isVisible();
- if (_interfaceWasVisible)
- _m4Vm->scene()->getInterface()->hide();
-
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- switch (menuType) {
- case GAME_MENU:
- loadSprites(MENU_GAME);
-
- // Add menu contents
- _menuObjects.push_back(new MenuButton(this, BTNID_MAIN, 45, 53, 24, 24, &OrionCallbacks::closeMenuFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_OPTIONS, 45, 94, 24, 24, &OrionCallbacks::gameOptionsMenuFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_RESUME, 45, 135, 24, 24, &OrionCallbacks::closeMenuFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_QUIT, 141, 135, 24, 24, &OrionCallbacks::gameExitFn));
- _menuObjects.push_back(new MenuButton(this, BTNID_SAVE, 141, 53, 24, 24, &OrionCallbacks::gameSaveGameFn, _calledFromMainMenu));
- _menuObjects.push_back(new MenuButton(this, BTNID_LOAD, 141, 94, 24, 24, &OrionCallbacks::gameLoadGameFn,
- !_vm->_saveLoad->hasSaves()));
-
- _escapeHandler = &OrionCallbacks::closeMenuFn;
- _returnHandler = &OrionCallbacks::closeMenuFn;
- break;
-
- case OPTIONS_MENU:
- loadSprites(MENU_OPTIONS);
-
- // Store the original settings in case user aborts dialog
- _originalMidiVolume = _vm->midi()->getVolume();
-
- // Add menu contents
- // TODO: Currently the Digi slider isn't hooked up to anything
- _menuObjects.push_back(new MenuButton(this, OPTIONID_CANCEL, 93, 141, 74, 43,
- &OrionCallbacks::optionsCancelFn, false, false, OBJTYPE_OM_CANCEL));
- _menuObjects.push_back(new MenuButton(this, OPTIONID_DONE, 168, 141, 74, 43,
- &OrionCallbacks::optionsDoneFn, false, false, OBJTYPE_OM_DONE));
- _menuObjects.push_back(new MenuHorizSlider(this, OPTIONID_HSLIDER_MIDI, 47, 64, 212, 24,
- _originalMidiVolume * 100 / 255, &OrionCallbacks::optionsMidiSliderFn, true));
- _menuObjects.push_back(new MenuHorizSlider(this, OPTIONID_HSLIDER_DIGI, 47, 104, 212, 24,
- 0, &OrionCallbacks::optionsDigiSliderFn, true));
-
- _escapeHandler = &OrionCallbacks::optionsEscapeFn;
- _returnHandler = &OrionCallbacks::optionsReturnFn;
- break;
-
- case SAVE_MENU:
- case LOAD_MENU:
- loadSprites(MENU_SAVELOAD);
-
- // Set up the defaults for the window
- _topSaveSlotIndex = 0;
- _selectedSlot = -1;
- _highlightedSlot = -1;
- _saveNames = _vm->_saveLoad->getSaves();
-
- // Set up menu elements
- _menuObjects.push_back(new MenuMessage(this, SLTAG_SAVELOAD_LABEL, 50, 241, 70, 16));
- _menuObjects.push_back(new MenuButton(this, SLTAG_SAVELOAD, 214, 384, 72, 41,
- (menuType == SAVE_MENU) ? &OrionCallbacks::saveLoadSaveFn : &OrionCallbacks::saveLoadLoadFn,
- true, true, (menuType == SAVE_MENU) ? OBJTYPE_SL_SAVE : OBJTYPE_SL_LOAD));
- _menuObjects.push_back(new MenuButton(this, SLTAG_CANCEL, 139, 384, 74, 43,
- &OrionCallbacks::saveLoadCancelFn, false, false, OBJTYPE_SL_CANCEL));
- _menuObjects.push_back(new MenuVertSlider(this, SLTAG_VSLIDER, 291, 255, 23, 127, 0,
- &OrionCallbacks::saveLoadSliderFn));
-
- if (_menuType == SAVE_MENU)
- _savegameThumbnail = createThumbnail();
-
- _menuObjects.push_back(new MenuImage(this, SLTAG_THUMBNAIL, 66, 28, 215, 162,
- (_savegameThumbnail == NULL) ? _sprites->getFrame(SL_EMPTY_THUMBNAIL) : _savegameThumbnail));
-
-
- {
- SaveGameIterator slot = _saveNames->begin();
- for (uint slotIndex = 0; slotIndex < SL_NUM_VISIBLE_SLOTS; ++slotIndex, ++slot) {
- // Get save slot
- bool isEmpty = (slotIndex >= _saveNames->size()) || (*slot).empty();
-
- _menuObjects.push_back(new MenuSaveLoadText(this, SLTAG_SLOTS_START + slotIndex,
- 50, 256 + slotIndex * 15, 238, 15, &OrionCallbacks::saveLoadSlotFn,
- (menuType == LOAD_MENU) && isEmpty, true, (menuType == LOAD_MENU),
- isEmpty ? EmptySaveString : slot->c_str(), slotIndex + 1));
- }
- }
-
- _escapeHandler = &OrionCallbacks::saveLoadEscapeFn;
- _returnHandler = &OrionCallbacks::saveLoadReturnFn;
- break;
-
- default:
- error("Unknown menu type");
- break;
- }
-
- // Draw all the items onto the background surface
- for (MenuObjectsIterator i = _menuObjects.begin(); i != _menuObjects.end(); ++i)
- (*i)->onRefresh();
-}
-
-OrionMenuView::~OrionMenuView() {
- delete _sprites;
-
- for (MenuObjectList::iterator i = _menuObjects.begin(); i != _menuObjects.end(); ++i)
- delete *i;
- _menuObjects.clear();
-
- delete _saveNames;
- delete _savegameThumbnail;
-}
-
-bool OrionMenuView::loadSprites(const char *seriesName) {
- Common::SeekableReadStream *data = _vm->res()->get(seriesName);
- RGB8 *palette;
-
- _sprites = new SpriteAsset(_vm, data, data->size(), seriesName);
- palette = _sprites->getPalette();
- _vm->_palette->setPalette(palette, 0, _sprites->getColorCount());
-
- _vm->res()->toss(seriesName);
-
- // Update the palette
- //_vm->setPalette((byte *) _menuPalette, 59, 197);
-
- // The first sprite is the menu background
-
- M4Sprite *bg = _sprites->getFrame(0);
- this->setSize(bg->width(), bg->height());
- _coords.setWidth(bg->width());
- _coords.setHeight(bg->height());
- bg->copyTo(this);
-
- return true;
-}
-
-// Creates a thumbnail based on the current background screen
-
-M4Surface *OrionMenuView::createThumbnail() {
- M4Surface srcSurface(_vm->_screen->width(), _vm->_screen->height());
- M4Surface *result = new M4Surface(_vm->_screen->width() / 3, _vm->_screen->height() / 3);
-
- // Translate the scene data
-
- _vm->_scene->onRefresh(NULL, &srcSurface);
- byte *srcP = srcSurface.getBasePtr(0, 0);
- byte *destP = result->getBasePtr(0, 0);
-
- for (int yCtr = 0; yCtr < _vm->_scene->height() / 3; ++yCtr, srcP += g_system->getWidth() * 3) {
- byte *src0P = srcP;
- byte *src1P = srcP + _vm->_screen->width();
- byte *src2P = src1P + _vm->_screen->width();
-
- for (int xCtr = 0; xCtr < result->width(); ++xCtr) {
- *destP = (byte)((uint32)((
- *src0P + *(src0P + 1) + *(src0P + 2) +
- *src1P + *(src1P + 1) + *(src1P + 2) +
- *src2P + *(src2P + 1) + *(src2P + 2)) / 9));
- if (*destP == 0)
- *destP = 21;
-
- ++destP;
- src0P += 3;
- src1P += 3;
- src2P += 3;
- }
- }
-
- // Translate the game interface view - since it's using standard colors that can't be
- // averaged, simply take the top left pixel of every 3x3 pixel block
-
- _m4Vm->scene()->getInterface()->onRefresh(NULL, &srcSurface);
- destP = result->getBasePtr(0, 0) + (_vm->_screen->width() / 3) * (_m4Vm->scene()->getInterface()->bounds().top / 3);
-
- int yStart = _m4Vm->scene()->getInterface()->bounds().top;
- int yEnd = MIN(_vm->_screen->height() - 1, (int) _m4Vm->scene()->getInterface()->bounds().bottom - 1);
- for (int yCtr = yStart; yCtr <= yEnd; yCtr += 3) {
- srcP = (byte *)srcSurface.getBasePtr(0, yCtr) + (yCtr * _vm->_screen->width());
-
- for (int xCtr = 0; xCtr < result->width(); ++xCtr, srcP += 3)
- *destP++ = *srcP;
- }
-
- return result;
-}
-
-void OrionMenuView::destroyView() {
- MadsM4Engine *engine = _vm;
- bool interfaceVisible = _interfaceWasVisible;
- engine->_viewManager->deleteView(this);
-
- // Fade the game back in if no menu views are active (such as if a button was pressed in one menu
- // to activate another menu dialog)
- bool fadeIn = engine->_viewManager->getView(VIEWID_MENU) == NULL;
-
- if (fadeIn) {
- bool fadeToBlack = engine->_events->quitFlag;
- engine->_ws->update();
- engine->_palette->fadeFromGreen(M4_DIALOG_FADE_STEPS, M4_DIALOG_FADE_DELAY, fadeToBlack);
-
- if (interfaceVisible)
- engine->scene()->showInterface();
- }
-}
-
-bool OrionMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- static Common::Point movingPos(0, 0);
- static bool movingFlag = false;
-
- bool handledFlag = false;
- int localX, localY;
- MenuObjectsIterator i;
-
- if (!_screenFlags.visible)
- return false;
-
- if (!movingFlag)
- captureEvents = false;
-
- // If the escape key is pressed, then pass onto the Escape handler
-
- if (eventType == KEVENT_KEY) {
- if ((param == Common::KEYCODE_ESCAPE) && (_escapeHandler != NULL)) {
- // Execute the Escape handler function
- _currentItem = NULL;
- captureEvents = false;
- _escapeHandler(this);
- destroyView();
- return true;
- }
-
- if (((param == Common::KEYCODE_RETURN) || (param == Common::KEYCODE_KP_ENTER)) &&
- (_returnHandler != NULL)) {
- // Execute the Return handler function
- _currentItem = NULL;
- captureEvents = false;
- _returnHandler(this);
- return true;
- }
-
- MenuTextField *textItem = (MenuTextField *) getItem(SLTAG_TEXTFIELD);
- if (textItem && textItem->onEvent(KEVENT_KEY, param, x, y, _currentItem))
- return true;
- }
-
- // Convert the screen position to a relative position within the menu surface
- localX = x - _coords.left;
- localY = y - _coords.top;
-
- // If there is an active object handling events, pass it on until it releases control
-
- if (_currentItem) {
- handledFlag = _currentItem->onEvent(eventType, param, localX, localY, _currentItem);
-
- if (_closeFlag) {
- // Dialog has been flagged to be closed
- captureEvents = false;
- destroyView();
- return true;
- }
-
- if (_currentItem) {
- captureEvents =
- (Common::find(_menuObjects.begin(), _menuObjects.end(), _currentItem) != _menuObjects.end());
- if (!captureEvents)
- // The menu object is no longer active, so reset current item
- _currentItem = NULL;
- } else {
- captureEvents = false;
- }
-
- if (handledFlag)
- return true;
- }
-
- if (eventType == KEVENT_KEY) {
- // Handle keypresses by looping through the item list to see if any of them want it
-
- for (i = _menuObjects.begin(); (i != _menuObjects.end()) && !handledFlag; ++i) {
- MenuObject *menuObj = *i;
- MenuObject *dummyItem;
- handledFlag = menuObj->onEvent(eventType, param, localX, localY, dummyItem);
- }
-
- return handledFlag;
-
- } else {
- // Handle mouse events by scanning the item list to see if the cursor is within any
-
- for (i = _menuObjects.begin(); (i != _menuObjects.end()) && !handledFlag; ++i) {
- MenuObject *menuObj = *i;
-
- if (menuObj->isInside(localX, localY)) {
- // Found an item, so pass it the event
- menuObj->onEvent(eventType, param, localX, localY, _currentItem);
-
- if (_closeFlag) {
- // Dialog has been flagged to be closed
- captureEvents = false;
- destroyView();
- return true;
- }
-
- if (_currentItem) {
- captureEvents =
- (Common::find(_menuObjects.begin(), _menuObjects.end(), _currentItem) != _menuObjects.end());
- if (!captureEvents)
- // The menu object is no longer active, so reset current item
- _currentItem = NULL;
- } else {
- captureEvents = false;
- }
-
- return true;
- }
- }
- }
-
- // None of the items have handled the event, so fall back on menu-wide event handling
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_DOUBLECLICK:
- if (!_screenFlags.immovable) {
- // Move the entire dialog
- captureEvents = true;
- movingFlag = true;
- movingPos.x = x;
- movingPos.y = y;
- }
- break;
-
- case MEVENT_LEFT_DRAG:
- case MEVENT_DOUBLECLICK_DRAG:
- if (movingFlag) {
- moveRelative(x - movingPos.x, y - movingPos.y);
- movingPos.x = x;
- movingPos.y = y;
- }
- break;
-
- case MEVENT_LEFT_RELEASE:
- case MEVENT_DOUBLECLICK_RELEASE:
- captureEvents = false;
- movingFlag = false;
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-MenuObject *OrionMenuView::getItem(int objectId) {
- MenuObjectsIterator i;
- for (i = _menuObjects.begin(); i != _menuObjects.end(); ++i) {
- MenuObject *obj = *i;
- if (obj->getObjectId() == objectId)
- return obj;
- }
-
- return NULL;
-}
-
-void OrionMenuView::setTopSaveSlot(int slotNumber) {
- _topSaveSlotIndex = MAX(MIN(slotNumber, 89), 0);
-
- // Update the details of the load/save slots
-
- // Get save slot
- SaveGameIterator slot = _saveNames->begin();
- for (int i = 0; i < _topSaveSlotIndex; ++i)
- ++slot;
-
- for (uint index = 0; index < SL_NUM_VISIBLE_SLOTS; ++index, ++slot) {
- MenuSaveLoadText *item = (MenuSaveLoadText *) getItem(SLTAG_SLOTS_START + index);
- uint slotIndex = _topSaveSlotIndex + index;
-
- bool isEmpty = (slotIndex >= _saveNames->size()) || slot->empty();
- item->setDisplay(slotIndex + 1, isEmpty ? EmptySaveString : slot->c_str());
-
- item->setState((_menuType == SAVE_MENU) || !isEmpty ? OS_NORMAL : OS_GREYED);
- }
-}
-
-void OrionMenuView::refresh(const Common::Rect &areaRect) {
- // Copy the selected portion of the background
- _sprites->getFrame(0)->copyTo(this, areaRect, areaRect.left, areaRect.top);
-
- for (MenuObjectsIterator i = _menuObjects.begin(); i != _menuObjects.end(); ++i) {
- MenuObject *obj = *i;
- if (obj->getBounds().intersects(areaRect))
- obj->onRefresh();
- }
-}
-
-}
diff --git a/engines/m4/m4_menus.h b/engines/m4/m4_menus.h
deleted file mode 100644
index 9abf71e9db..0000000000
--- a/engines/m4/m4_menus.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_M4_MENUS_H
-#define M4_M4_MENUS_H
-
-#include "common/list.h"
-#include "common/ptr.h"
-
-#include "m4/viewmgr.h"
-#include "m4/m4.h"
-#include "m4/gui.h"
-#include "m4/saveload.h"
-
-namespace M4 {
-
-#define M4_DIALOG_FADE_STEPS 5
-#define M4_DIALOG_FADE_DELAY 30
-
-typedef Common::List<MenuObject *> MenuObjectList;
-
-class OrionMenuView : public DialogView {
- typedef MenuObjectList::iterator MenuObjectsIterator;
-private:
- MenuType _menuType;
- SpriteAsset *_sprites;
- MenuObjectList _menuObjects;
- MenuObject *_currentItem;
- typedef void (*Callback)(OrionMenuView *view);
- OrionMenuView::Callback _escapeHandler, _returnHandler;
- bool _closeFlag;
- bool _calledFromMainMenu;
- bool _interfaceWasVisible;
- int _firstSlotIndex;
-
- bool loadSprites(const char *seriesName);
- M4Surface *createThumbnail();
- void destroyView();
-public:
- OrionMenuView(MadsM4Engine *vm, int x, int y, MenuType menuType, bool calledFromMainMenu,
- bool loadSaveFromHotkey);
- ~OrionMenuView();
- MenuType getMenuType() { return _menuType; }
- SpriteAsset *sprites() { return _sprites; }
- MenuObjectList &items() { return _menuObjects; }
- MenuObject *getItem(int objectId);
- void setTopSaveSlot(int slotNumber);
- void refresh(const Common::Rect &areaRect);
- void close() { _closeFlag = true; }
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
-
- int _originalMidiVolume;
- SaveGameList *_saveNames;
- bool _loadSaveFromHotkey;
-};
-
-class OrionCallbacks {
-public:
- static void closeMenuFn(DialogView *view, MenuObject *item);
- static void closeMenuFn(OrionMenuView *view);
- static void gameOptionsMenuFn(DialogView *view, MenuObject *item);
- static void gameSaveGameFn(DialogView *view, MenuObject *item);
- static void gameLoadGameFn(DialogView *view, MenuObject *item);
- static void gameExitFn(DialogView *view, MenuObject *item);
- static void optionsDigiSliderFn(DialogView *view, MenuObject *item);
- static void optionsMidiSliderFn(DialogView *view, MenuObject *item);
- static void optionsScrollingFn(DialogView *view, MenuObject *item);
- static void optionsCancelFn(DialogView *view, MenuObject *item);
- static void optionsDoneFn(DialogView *view, MenuObject *item);
- static void optionsReturnFn(OrionMenuView *view);
- static void optionsEscapeFn(OrionMenuView *view);
- static void saveLoadSaveFn(DialogView *view, MenuObject *item);
- static void saveLoadLoadFn(DialogView *view, MenuObject *item);
- static void saveLoadSlotFn(DialogView *view, MenuObject *item);
- static void saveLoadCancelFn(DialogView *view, MenuObject *item);
- static void saveLoadSliderFn(DialogView *view, MenuObject *item);
- static void saveLoadEscapeFn(OrionMenuView *view);
- static void saveLoadReturnFn(OrionMenuView *view);
-};
-
-}
-
-#endif
diff --git a/engines/m4/m4_scene.cpp b/engines/m4/m4_scene.cpp
deleted file mode 100644
index 1a2e00e50d..0000000000
--- a/engines/m4/m4_scene.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/textconsole.h"
-
-#include "m4/m4_scene.h"
-#include "m4/dialogs.h"
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/rails.h"
-#include "m4/font.h"
-#include "m4/m4_views.h"
-#include "m4/mads_views.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-M4Scene::M4Scene(M4Engine *vm): _sceneResources(), Scene(vm, &_sceneResources) {
- _vm = vm;
- _sceneSprites = NULL;
- _inverseColorTable = NULL;
-
- _sceneResources.hotspots = new HotSpotList();
- _sceneResources.parallax = new HotSpotList();
- _sceneResources.dynamicHotspots = new HotSpotList();
- _interfaceSurface = new M4InterfaceView(vm);
-}
-
-M4Scene::~M4Scene() {
- delete _sceneSprites;
-}
-
-void M4Scene::loadSceneSprites(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- sprintf(filename, "%i.ssb", sceneNumber);
-
- Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
- _sceneSprites = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
- _vm->res()->toss(filename);
-
- debugCN(kDebugGraphics, "Scene has %d sprites, each one having %d colors\n", _sceneSprites->getCount(), _sceneSprites->getColorCount());
-}
-
-void M4Scene::loadSceneResources(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- int i = 0, x = 0, y = 0;
- sprintf(filename, "%i.chk", sceneNumber);
-
- Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
-
- if (sceneS != NULL) {
- sceneS->read(_sceneResources.artBase, MAX_CHK_FILENAME_SIZE);
- sceneS->read(_sceneResources.pictureBase, MAX_CHK_FILENAME_SIZE);
- int hotspotCount = sceneS->readUint32LE();
- _sceneResources.parallaxCount = sceneS->readUint32LE();
- int dynHotspotCount = sceneS->readUint32LE();
- _sceneResources.frontY = sceneS->readUint32LE();
- _sceneResources.backY = sceneS->readUint32LE();
- _sceneResources.frontScale = sceneS->readUint32LE();
- _sceneResources.backScale = sceneS->readUint32LE();
- for (i = 0; i < 16; i++)
- _sceneResources.depthTable[i] = sceneS->readUint16LE();
- _sceneResources.railNodeCount = sceneS->readUint32LE();
-
- // Clear rails from previous scene
- _vm->_rails->clearRails();
-
- for (i = 0; i < _sceneResources.railNodeCount; i++) {
- x = sceneS->readUint32LE();
- y = sceneS->readUint32LE();
- if (_vm->_rails->addRailNode(x, y, true) < 0) {
- warning("Too many rail nodes defined for scene");
- }
- }
-
- // Clear current hotspot lists
- _sceneResources.hotspots->clear();
- _sceneResources.parallax->clear();
- _sceneResources.dynamicHotspots->clear();
-
- _sceneResources.hotspots->loadHotSpots(sceneS, hotspotCount);
- _sceneResources.parallax->loadHotSpots(sceneS, _sceneResources.parallaxCount);
- _sceneResources.dynamicHotspots->loadHotSpots(sceneS, dynHotspotCount);
-
- // Note that toss() deletes the MemoryReadStream
- _vm->res()->toss(filename);
- }
-}
-
-void M4Scene::loadSceneInverseColorTable(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- Common::SeekableReadStream *iplS;
-
- sprintf(filename, "%i.ipl", sceneNumber);
- iplS = _vm->res()->openFile(filename);
- delete[] _inverseColorTable;
- _inverseColorTable = new byte[iplS->size()];
- iplS->read(_inverseColorTable, iplS->size());
- _vm->res()->toss(filename);
-}
-
-void M4Scene::loadSceneSpriteCodes(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- sprintf(filename, "%i.ssc", sceneNumber);
-
- Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
-
- // TODO
-
- if (sceneS != NULL) {
- SpriteAsset* _sceneSpriteCodes = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
- int colorCount = _sceneSpriteCodes->getColorCount();
-// RGB8* spritePalette = _sceneSpriteCodes->getPalette();
- //_vm->_palette->setPalette(spritePalette, 0, colorCount);
-
- debugCN(kDebugGraphics, "Scene has %d sprite codes, each one having %d colors\n", _sceneSpriteCodes->getCount(), colorCount);
-
- // Note that toss() deletes the MemoryReadStream
- _vm->res()->toss(filename);
- }
-}
-
-void M4Scene::loadScene(int sceneNumber) {
- Scene::loadScene(sceneNumber);
-
- _backgroundSurface->loadBackground(sceneNumber);
- _palData = NULL;
-
- if (_vm->getGameType() == GType_Burger &&
- sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER)
- setStatusText("");
-
- // Load scene def file (*.CHK)
- loadSceneResources(sceneNumber);
-
- // TODO: set walker scaling
- // TODO: destroy woodscript buffer
-
- // Load scene walk path file (*.COD/*.WW?)
- loadSceneCodes(sceneNumber);
-
- // Load inverse color table file (*.IPL)
- loadSceneInverseColorTable(sceneNumber);
-
- if (_vm->getGameType() != GType_Burger) {
- // Load scene sprites file (*.SSB)
- loadSceneSprites(sceneNumber);
-
- // Load scene sprite codes file (*.SSC)
- loadSceneSpriteCodes(sceneNumber);
- }
-
-
- if (sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER) {
- _m4Vm->scene()->getInterface()->show();
- showSprites();
- }
-
- // Purge resources
- _vm->res()->purge();
-}
-
-void M4Scene::loadSceneCodes(int sceneNumber, int index) {
- char filename[kM4MaxFilenameSize];
- Common::SeekableReadStream *sceneS;
-
- sprintf(filename, "%i.cod", sceneNumber);
- sceneS = _vm->res()->openFile(filename);
- _walkSurface->loadCodesM4(sceneS);
- _vm->res()->toss(filename);
-}
-
-void M4Scene::show() {
- Scene::show();
- _vm->_viewManager->addView(_interfaceSurface);
-}
-
-void M4Scene::leaveScene() {
- _sceneResources.parallax->clear();
-
- delete _sceneResources.parallax;
- delete[] _inverseColorTable;
-
- Scene::leaveScene();
-}
-
-void M4Scene::mouseMove(int x, int y) {
- if (_vm->getGameType() == GType_Riddle)
- return;
-
- // TODO: loads of things to do here, only the mouse cursor and the status
- // text is changed for now
-
- // Only scene hotspots are checked for now, not parallax/props, as the
- // latter ones are not used by Orion Burger
- HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
- if (currentHotSpot != NULL && currentHotSpot->getActive()) {
- if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
- _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
- _vm->_mouse->getCursorNum() != CURSOR_USE &&
- _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- _vm->_mouse->setCursorNum(currentHotSpot->getCursor());
- }
- _m4Vm->scene()->getInterface()->setStatusText(currentHotSpot->getPrep());
- } else {
- if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
- _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
- _vm->_mouse->getCursorNum() != CURSOR_USE &&
- _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- _vm->_mouse->setCursorNum(0);
- } else {
-
- }
- }
-}
-
-void M4Scene::leftClick(int x, int y) {
- if (_vm->getGameType() == GType_Burger) {
- // Place a Wilbur sprite with the correct facing
- HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
- if (currentHotSpot != NULL && currentHotSpot->getActive()) {
- update();
- _vm->_actor->setWalkerDirection(currentHotSpot->getFacing());
- /*
- int posX = currentHotSpot->getFeetX();
- int posY = currentHotSpot->getFeetY() -
- scaleValue(_vm->_actor->getWalkerHeight(), _vm->_actor->getWalkerScaling(), 0);
- //_vm->_actor->placeWalkerSpriteAt(0, posX, posY);
- */
-
- // Player said.... (for scene scripts)
- debugCN(kDebugGraphics, "Player said: %s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
-
- // FIXME: This should be moved somewhere else, and is incomplete
- if (_m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- if (_vm->_mouse->getVerb() == NULL) {
- strcpy(_vm->_player->verb, currentHotSpot->getVerb());
- } else {
- strcpy(_vm->_player->verb, _vm->_mouse->getVerb());
- }
- } else {
- strcpy(_vm->_player->verb, _m4Vm->scene()->getInterface()->_inventory.getSelectedObjectName());
- }
- strcpy(_vm->_player->noun, currentHotSpot->getVocab());
- strcpy(_vm->_player->object, "");
- _vm->_player->commandReady = true;
-
- debugCN(kDebugGraphics, "## Player said: %s %s\n", _vm->_player->verb, _vm->_player->noun);
-
- }
- }
-}
-
-void M4Scene::rightClick(int x, int y) {
- if (_vm->getGameType() == GType_Burger) {
- nextCommonCursor();
- _m4Vm->scene()->getInterface()->_inventory.clearSelected();
- }
-}
-
-void M4Scene::setAction(int action, int objectId) {
-}
-
-void M4Scene::setStatusText(const char *text) {
- getInterface()->setStatusText(text);
-}
-
-void M4Scene::update() {
-
-}
-
-void M4Scene::nextCommonCursor() {
- int cursorIndex = _vm->_mouse->getCursorNum();
-
- switch (cursorIndex) {
- case CURSOR_ARROW:
- cursorIndex = CURSOR_LOOK;
- break;
- case CURSOR_LOOK:
- cursorIndex = CURSOR_TAKE;
- break;
- case CURSOR_TAKE:
- cursorIndex = CURSOR_USE;
- break;
- case CURSOR_USE:
- cursorIndex = CURSOR_ARROW;
- break;
- default:
- cursorIndex = CURSOR_ARROW;
- }
-
- _vm->_mouse->setCursorNum(cursorIndex);
-}
-
-void M4Scene::showHotSpots() {
- Scene::showHotSpots();
-
- // parallax (yellow)
- for (int i = 0; i < _sceneResources.parallaxCount; i++) {
- HotSpot *currentHotSpot = _sceneResources.parallax->get(i);
- _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->YELLOW);
- }
-}
-
-} // End of namespace M4
diff --git a/engines/m4/m4_scene.h b/engines/m4/m4_scene.h
deleted file mode 100644
index a0ba497cf7..0000000000
--- a/engines/m4/m4_scene.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_M4_SCENE_H
-#define M4_M4_SCENE_H
-
-class View;
-
-#include "m4/scene.h"
-
-namespace M4 {
-
-#define TITLE_SCENE_BURGER 951 // 951 = intro, 901 = demo menu, 971 = first scene
-#define MAINMENU_SCENE_BURGER 903
-#define FIRST_SCENE 101
-
-class M4SceneResources : public SceneResources {
-public:
- int32 frontY, backY;
- int32 frontScale, backScale;
- int16 depthTable[16];
- int32 railNodeCount; // # of rails
-
- int32 parallaxCount;
- HotSpotList *parallax;
-};
-
-class M4Scene : public Scene {
-private:
- M4Engine *_vm;
- M4SceneResources _sceneResources;
- SpriteAsset *_sceneSprites;
- SpriteAsset *_walkerSprite;
- byte *_inverseColorTable;
-
- void loadSceneSprites(int sceneNumber);
- void loadSceneResources(int sceneNumber);
- void loadSceneInverseColorTable(int sceneNumber);
- void loadSceneSpriteCodes(int sceneNumber);
- void nextCommonCursor();
-public:
- M4Scene(M4Engine *vm);
- virtual ~M4Scene();
-
- // Methods that differ between engines
- virtual void loadScene(int sceneNumber);
- virtual void leaveScene();
- virtual void loadSceneCodes(int sceneNumber, int index = 0);
- virtual void show();
- virtual void mouseMove(int x, int y);
- virtual void leftClick(int x, int y);
- virtual void rightClick(int x, int y);
- virtual void update();
- virtual void showHotSpots();
-
- byte *getInverseColorTable() const { return _inverseColorTable; }
- M4InterfaceView *getInterface() { return (M4InterfaceView *)_interfaceSurface; }
- M4SceneResources &getSceneResources() { return _sceneResources; }
- void setStatusText(const char *text);
- void setAction(int action, int objectId = -1);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/m4_views.cpp b/engines/m4/m4_views.cpp
deleted file mode 100644
index 1324526ab5..0000000000
--- a/engines/m4/m4_views.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4_views.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/globals.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-GUIInventory::GUIInventory(View *owner, MadsM4Engine *vm, const Common::Rect &bounds, int horizCells,
- int vertCells, int cellWidth, int cellHeight, int tag): GUIRect(owner, bounds, tag) {
-
- _vm = vm;
- _cellCount.x = horizCells;
- _cellCount.y = vertCells;
- _cellSize.x = cellWidth;
- _cellSize.y = cellHeight;
-
- // Validate the cell settings
- if ((_cellCount.x * _cellSize.x > _bounds.width()) ||
- (_cellCount.y * _cellSize.y > _bounds.height()))
- error("Cell settings for inventory display exceeded control size");
-
- _visible = true;
- _scrollPosition = 0;
- _scrollable = false;
- _highlightedIndex = -1;
- _selectedIndex = -1;
-}
-
-void GUIInventory::onRefresh() {
- _parent->fillRect(_bounds, _vm->_palette->BLACK);
- //_parent->frameRect(_bounds, _vm->_palette->LIGHT_GRAY);
-
- if (_visible) {
- //kernel_trigger_dispatch(kernel_trigger_create(TRIG_INV_CLICK));
-
- _scrollable = false;
-
- // Get to the starting inventory position for display
- ItemsIterator i = _inventoryItems.begin();
- int index = _scrollPosition;
- while (index-- > 0) ++i;
-
- // Loop through displaying entries
- for (index = 0; (i != _inventoryItems.end()) && (index < _cellCount.x * _cellCount.y); ++index, ++i) {
- GUIInventoryItem *item = (*i).get();
- const Common::Point cellPos = getCellPosition(index);
-/* Common::Rect cellBounds(_bounds.left + cellPos.x + xOffset,
- _bounds.top + cellPos.y + yOffset,
- _bounds.left + cellPos.x + xOffset + _cellSize.x,
- _bounds.top + cellPos.y + _cellSize.y);*/
- Common::Rect cellBounds(_bounds.left + cellPos.x, _bounds.top + cellPos.y,
- _bounds.left + cellPos.x + _cellSize.x, _bounds.top + cellPos.y + _cellSize.y);
-
- Common::Point iconPt(
- cellBounds.left + (cellBounds.width() - item->icon->width()) / 2,
- cellBounds.top + (cellBounds.height() - item->icon->height()) / 2);
-
- item->icon->copyTo(_parent, iconPt.x, iconPt.y, 0);
-
- if (_highlightedIndex == index)
- _parent->frameRect(Common::Rect(iconPt.x - 2, iconPt.y - 2,
- iconPt.x + item->icon->width() + 2, iconPt.y + item->icon->height() + 2),
- _vm->_palette->LIGHT_GRAY);
- }
- }
-}
-
-bool GUIInventory::onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem) {
- bool result = false;
- int overIndex = getInsideIndex(x, y);
- bool isPressed = (eventType == MEVENT_LEFT_CLICK) || (eventType == MEVENT_LEFT_HOLD) ||
- (eventType == MEVENT_LEFT_DRAG);
- ItemsIterator curItem = _inventoryItems.begin();
-
- if (isPressed) {
- if (_selectedIndex == -1 && overIndex != -1) {
- setHighlight(overIndex);
- _selectedIndex = overIndex;
- for (int i = 0; i < _scrollPosition + _selectedIndex; i++)
- ++curItem;
- if (_scrollPosition + _selectedIndex < (int)_inventoryItems.size())
- _vm->_mouse->setCursorNum(curItem->get()->iconIndex);
- result = true;
- } else {
- // We are over something being tracked
- if (_selectedIndex == overIndex) {
- setHighlight(overIndex);
- result = true;
- } else {
- // Otherwise reset highlighting
- setHighlight(-1);
- result = false;
- }
- }
- } else {
- // No button pressed
- if (_selectedIndex == overIndex) {
- result = (_selectedIndex != -1);
- } else {
- result = (overIndex + _scrollPosition < (int)_inventoryItems.size());
- if (result) {
- for (int i = 0; i < overIndex + _scrollPosition; i++)
- ++curItem;
- _m4Vm->scene()->getInterface()->setStatusText(curItem->get()->name);
- }
- }
-
- // Stop tracking anything
- setHighlight(overIndex);
- }
-
- return result;
-}
-
-void GUIInventory::add(const char *name, const char *verb, M4Surface *icon, int iconIndex) {
- // First scan through the list to prevent duplicate objects
- for (ItemsIterator i = _inventoryItems.begin(); i != _inventoryItems.end(); ++i) {
- if (!strcmp(name, ((*i).get())->name))
- return;
- }
-
- _inventoryItems.push_back(InventoryList::value_type(new GUIInventoryItem(name, verb, icon, iconIndex)));
-}
-
-bool GUIInventory::remove(const char *name) {
- for (ItemsIterator i = _inventoryItems.begin(); i != _inventoryItems.end(); ++i) {
- if (!strcmp(name, ((*i).get())->name)) {
- _inventoryItems.erase(i);
- _scrollPosition = 0;
- return true;
- }
- }
-
- return false;
-}
-
-int GUIInventory::getInsideIndex(int x, int y) {
- if (!_bounds.contains(x, y))
- return -1;
-
- int localX = x - _bounds.left;
- int localY = y - _bounds.top;
- return (localX / _cellSize.x) * _cellCount.y + (localY / _cellSize.y);
-}
-
-const char *GUIInventory::getSelectedObjectName() {
- if (_selectedIndex != -1) {
- ItemsIterator curItem = _inventoryItems.begin();
- for (int i = 0; i < _selectedIndex; i++)
- ++curItem;
- return curItem->get()->name;
- } else {
- return NULL;
- }
-}
-
-const Common::Point &GUIInventory::getCellPosition(int index) {
- static Common::Point result;
-
- if (_cellCount.x > _cellCount.y) {
- // Horizontal orientation
- result.x = (index / _cellCount.y) * _cellSize.x;
- result.y = (index % _cellCount.y) * _cellSize.x;
- } else {
- // Vertical orientation
- result.x = (index / _cellCount.x) * _cellSize.y;
- result.y = (index % _cellCount.x) * _cellSize.y;
- }
-
- return result;
-}
-
-void GUIInventory::setHighlight(int index) {
- if (_highlightedIndex == index)
- return;
-
- _highlightedIndex = index;
-}
-
-void GUIInventory::setScrollPosition(int value) {
- if (value < 0)
- return;
- else if (value >= (int)_inventoryItems.size() - (_cellCount.x * _cellCount.y))
- return;
-
- _scrollPosition = value;
-}
-
-//--------------------------------------------------------------------------
-
-const char *INTERFACE_SERIES = "999intr";
-
-#define SPR(x) _sprites->getFrame(x)
-
-M4InterfaceView::M4InterfaceView(MadsM4Engine *vm):
- GameInterfaceView(vm, Common::Rect(0, vm->_screen->height() - INTERFACE_HEIGHT,
- vm->_screen->width(), vm->_screen->height())),
- _statusText(GUITextField(this, Common::Rect(200, 1, 450, 21))),
- _inventory(GUIInventory(this, vm, Common::Rect(188, 22, 539, 97), 9, 1, 39, 75, 3)) {
-
- _screenType = VIEWID_INTERFACE;
- _screenFlags.layer = LAYER_INTERFACE;
- _screenFlags.visible = false;
- _screenFlags.get = SCREVENT_MOUSE;
- _highlightedIndex = -1;
- _selected = false;
-
- Common::SeekableReadStream *data = _vm->res()->get(INTERFACE_SERIES);
- _sprites = new SpriteAsset(_vm, data, data->size(), INTERFACE_SERIES);
-
- //RGB8 *palette = _sprites->getPalette();
- //Palette.setPalette(palette, 0, _sprites->getColorCount());
-
- _vm->res()->toss(INTERFACE_SERIES);
-
- // Setup the interface buttons
-
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(15, 35, 47, 66), 0, SPR(0), SPR(1), SPR(2)))); // look
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(60, 35, 92, 66), 1, SPR(3), SPR(4), SPR(5)))); // take
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(105, 35, 137, 66), 2, SPR(6), SPR(7), SPR(8)))); // manipulate
-
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(580, 10, 620, 69), 3, SPR(69), SPR(70), SPR(71)))); // abduction
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(582, 70, 619, 105), 4, SPR(76), SPR(77), SPR(78)))); // menu
-
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(168, 22, 188, 97), 5, SPR(60), SPR(61), SPR(62)))); // Scroll left
- _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(539, 22, 559, 97), 6, SPR(64), SPR(65), SPR(66)))); // Scroll right
-}
-
-#undef SPR
-
-M4InterfaceView::~M4InterfaceView() {
- delete _sprites;
-}
-
-void M4InterfaceView::setHighlightedButton(int index) {
- if (index == _highlightedIndex)
- return;
-
- _selected = (index == -1);
- _highlightedIndex = index;
-}
-
-bool M4InterfaceView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- static bool selectionFlag = false;
- if (eventType == MEVENT_LEFT_RELEASE)
- selectionFlag = false;
-
- captureEvents = isInside(x, y);
- if (!captureEvents)
- return false;
-
- int localX = x - _coords.left;
- int localY = y - _coords.top;
- GUIObject *currentItem;
-
- _statusText.onEvent(eventType, param, localX, localY, currentItem);
- _inventory.onEvent(eventType, param, localX, localY, currentItem);
-
- if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
- _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
- _vm->_mouse->getCursorNum() != CURSOR_USE &&
- _m4Vm->scene()->getInterface()->_inventory.getSelectedIndex() == -1) {
- if (_vm->_mouse->getCursorNum() != 0)
- _vm->_mouse->setCursorNum(0);
- }
-
- for (ButtonsIterator i = _buttons.begin(); i != _buttons.end(); ++i) {
- GUIButton *btn = (*i).get();
- btn->onEvent(eventType, param, localX, localY, currentItem);
- if ((btn->getState() == BUTTON_PRESSED) && !selectionFlag) {
- selectionFlag = true;
- _highlightedIndex = btn->getTag();
-
- switch (_highlightedIndex) {
- case 0:
- _vm->_mouse->setCursorNum(CURSOR_LOOK);
- break;
- case 1:
- _vm->_mouse->setCursorNum(CURSOR_TAKE);
- break;
- case 2:
- _vm->_mouse->setCursorNum(CURSOR_USE);
- break;
- case 3:
- // TODO: Jump to abduction
- break;
- case 4:
- _vm->loadMenu(GAME_MENU);
- break;
- case 5:
- _inventory.scrollLeft();
- break;
- case 6:
- _inventory.scrollRight();
- break;
- default:
- break;
- }
- }
- }
-
- return true;
-}
-
-void M4InterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
- clear();
-
- _statusText.onRefresh();
- _inventory.onRefresh();
- for (ButtonsIterator i = _buttons.begin(); i != _buttons.end(); ++i)
- ((*i).get())->onRefresh();
-
- View::onRefresh(rects, destSurface);
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/m4_views.h b/engines/m4/m4_views.h
deleted file mode 100644
index 4ca2a74593..0000000000
--- a/engines/m4/m4_views.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_M4_VIEWS_H
-#define M4_M4_VIEWS_H
-
-#include "m4/gui.h"
-#include "m4/viewmgr.h"
-#include "common/rect.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-namespace M4 {
-
-class GUIInventoryItem {
-public:
- const char *name;
- const char *verb;
- M4Surface *icon;
- int iconIndex;
-
- GUIInventoryItem(const char *_name, const char *_verb, M4Surface *_icon, int _iconIndex) {
- name = _name; verb = _verb; icon = _icon; iconIndex = _iconIndex;
- }
-};
-
-class GUIInventory : public GUIRect {
- typedef Common::List<Common::SharedPtr<GUIInventoryItem> > InventoryList;
- typedef InventoryList::iterator ItemsIterator;
-private:
- InventoryList _inventoryItems;
- Common::Point _cellSize;
- Common::Point _cellCount;
- bool _visible;
- bool _scrollable;
- int _scrollPosition;
- int _highlightedIndex;
- int _selectedIndex;
- MadsM4Engine *_vm;
-public:
- GUIInventory(View *owner, MadsM4Engine *vm, const Common::Rect &bounds,
- int horizCells, int vertCells, int cellWidth, int cellHeight, int tag);
-
- void onRefresh();
- bool onEvent(M4EventType eventType, int32 param, int x, int y, GUIObject *&currentItem);
-
- void add(const char *name, const char *verb, M4Surface *icon, int iconIndex);
- bool remove(const char *name);
- int getInsideIndex(int x, int y);
- int getSelectedIndex() { return _selectedIndex; }
- const char *getSelectedObjectName();
- void clearSelected() {
- _selectedIndex = -1;
- setHighlight(-1);
- }
- const Common::Point &getCellPosition(int index);
- void setHighlight(int index);
- bool needLeftButton() { return _scrollPosition != 0; }
- bool needRightButton() {
- return (uint)(_inventoryItems.size() - _scrollPosition) > (uint)(_cellCount.x * _cellCount.y);
- }
- void setScrollPosition(int value);
- void scrollLeft() { setScrollPosition(_scrollPosition - 1); }
- void scrollRight() { setScrollPosition(_scrollPosition + 1); }
- void setVisible(bool value) { _visible = value; }
-};
-
-class M4InterfaceView : public GameInterfaceView {
- typedef Common::List<Common::SharedPtr<GUIButton> > ButtonList;
- typedef ButtonList::iterator ButtonsIterator;
-public:
- SpriteAsset *_sprites;
- ButtonList _buttons;
- GUITextField _statusText;
- GUIInventory _inventory;
- int _highlightedIndex;
- bool _selected;
-private:
- void setHighlightedButton(int index);
-public:
- M4InterfaceView(MadsM4Engine *vm);
- ~M4InterfaceView();
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void setStatusText(const char *text) { _statusText.setText(text); }
- void cancelSentence() { setStatusText(NULL); }
- void inventoryAdd(const char *name, const char *verb, int iconIndex) {
- _inventory.add(name, verb, _sprites->getFrame(iconIndex), iconIndex);
- }
- bool inventoryRemove(const char *name) { return _inventory.remove(name); }
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_anim.cpp b/engines/m4/mads_anim.cpp
deleted file mode 100644
index aac21ae65d..0000000000
--- a/engines/m4/mads_anim.cpp
+++ /dev/null
@@ -1,745 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/mads_anim.h"
-#include "m4/m4.h"
-#include "m4/compression.h"
-
-namespace M4 {
-
-#define TEXTVIEW_LINE_SPACING 2
-#define TEXT_ANIMATION_DELAY 100
-#define TV_NUM_FADE_STEPS 40
-#define TV_FADE_DELAY_MILLI 50
-
-TextviewView::TextviewView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())),
- _bgSurface(vm->_screen->width(), MADS_SURFACE_HEIGHT),
- _textSurface(vm->_screen->width(), MADS_SURFACE_HEIGHT + vm->_font->current()->getHeight() +
- TEXTVIEW_LINE_SPACING) {
-
- _screenType = VIEWID_TEXTVIEW;
- _screenFlags.layer = LAYER_BACKGROUND;
- _screenFlags.visible = true;
- _screenFlags.get = SCREVENT_ALL;
- _callback = NULL;
- _script = NULL;
- _spareScreen = NULL;
- _bgCurrent = NULL;
- _bgSpare = NULL;
- reset();
-
- // Set up system palette colors and the two colors for text display
- _vm->_palette->setMadsSystemPalette();
- RGB8 palData[3];
- palData[0].r = palData[0].g = palData[0].b = 0;
- palData[1].r = 0; palData[1].g = palData[1].b = 252;
- palData[2].r = 0; palData[2].g = palData[2].b = 180;
- _vm->_palette->setPalette(&palData[0], 4, 3);
- _vm->_palette->blockRange(4, 3);
-
- _vm->_font->current()->setColors(5, 6, 4);
-
- clear();
- _bgSurface.clear();
- _textSurface.clear();
-
- int y = (height() - MADS_SURFACE_HEIGHT) / 2;
- setColor(2);
- hLine(0, width() - 1, y - 2);
- hLine(0, width() - 1, height() - y + 1);
-}
-
-TextviewView::~TextviewView() {
- if (_script)
- _vm->res()->toss(_resourceName);
- delete _spareScreen;
- delete _bgCurrent;
- delete _bgSpare;
-}
-
-void TextviewView::reset() {
- _bgSurface.clear();
- _textSurface.clear();
- _animating = false;
- _panX = 0;
- _panY = 0;
- _panSpeed = 0;
- _soundDriverLoaded = false;
- Common::fill(&_spareScreens[0], &_spareScreens[10], 0);
- _scrollCount = 0;
- _lineY = -1;
- _scrollTimeout = 0;
- _panCountdown = 0;
- _processEvents = true;
-}
-
-void TextviewView::setScript(const char *resourceName, TextviewCallback callback) {
- _callback = callback;
- if (_script)
- _vm->res()->toss(_resourceName);
- if (_spareScreen) {
- delete _spareScreen;
- _spareScreen = NULL;
- }
-
- reset();
-
- strncpy(_resourceName, resourceName, 15);
- _resourceName[15] = '\0';
- if (!strchr(_resourceName, '.'))
- strcat(_resourceName, ".txr");
-
- _script = _vm->res()->get(_resourceName);
-
- processLines();
-}
-
-bool TextviewView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- if (!_processEvents)
- return false;
-
- // Wait for the Escape key or a mouse press
- if (((eventType == KEVENT_KEY) && (param == Common::KEYCODE_ESCAPE)) ||
- (eventType == MEVENT_LEFT_RELEASE) || (eventType == MEVENT_RIGHT_RELEASE)) {
- scriptDone();
- captureEvents = false;
- return true;
- }
-
- return false;
-}
-
-void TextviewView::updateState() {
- if (!_animating)
- return;
-
- // Only update state if wait period has expired
- uint32 currTime = g_system->getMillis();
-
- // If a screen transition is in progress and it's time for another column, handle it
- if (_spareScreen) {
- byte *srcP = _spareScreen->getBasePtr(_translationX, 0);
- byte *destP = _bgSurface.getBasePtr(_translationX, 0);
-
- for (int y = 0; y < _bgSurface.height(); ++y, srcP += _spareScreen->width(),
- destP += _bgSurface.width()) {
- *destP = *srcP;
- }
-
- if (++_translationX >= _bgSurface.width()) {
- // Surface transition is complete
- delete _spareScreen;
- _spareScreen = NULL;
-
- _vm->_palette->deleteRange(_bgCurrent);
- delete _bgCurrent;
- _bgCurrent = _bgSpare;
- _bgSpare = NULL;
- }
- }
-
- // Make sure it's time for an update
- if (currTime < _scrollTimeout)
- return;
- _scrollTimeout = g_system->getMillis() + TEXT_ANIMATION_DELAY;
-
- // If any panning values are set, pan the background surface
- if ((_panX != 0) || (_panY != 0)) {
- if (_panCountdown > 0) {
- --_panCountdown;
- return;
- }
-
- // Handle horizontal panning
- if (_panX != 0) {
- byte *lineTemp = new byte[_panX];
- for (int y = 0; y < _bgSurface.height(); ++y) {
- byte *pixelsP = _bgSurface.getBasePtr(0, y);
-
- // Copy the first X pixels into temp buffer, move the rest of the line
- // to the start of the line, and then move temp buffer pixels to end of line
- Common::copy(pixelsP, pixelsP + _panX, lineTemp);
- Common::copy(pixelsP + _panX, pixelsP + _bgSurface.width(), pixelsP);
- Common::copy(lineTemp, lineTemp + _panX, pixelsP + _bgSurface.width() - _panX);
- }
-
- delete[] lineTemp;
- }
-
- // Handle vertical panning
- if (_panY != 0) {
- // Store the bottom Y lines into a temp buffer, move the rest of the lines down,
- // and then copy the stored lines back to the top of the screen
- byte *linesTemp = new byte[_panY * _bgSurface.width()];
- byte *pixelsP = _bgSurface.getBasePtr(0, _bgSurface.height() - _panY);
- Common::copy(pixelsP, pixelsP + _bgSurface.width() * _panY, linesTemp);
-
- for (int y = _bgSurface.height() - 1; y >= _panY; --y) {
- byte *destP = _bgSurface.getBasePtr(0, y);
- byte *srcP = _bgSurface.getBasePtr(0, y - _panY);
- Common::copy(srcP, srcP + _bgSurface.width(), destP);
- }
-
- Common::copy(linesTemp, linesTemp + _panY * _bgSurface.width(), _bgSurface.getBasePtr(0, 0));
- delete[] linesTemp;
- }
- }
-
- // Scroll the text surface up by one row
- byte *pixelsP = _textSurface.getBasePtr(0, 0);
- Common::copy(pixelsP + width(), pixelsP + _textSurface.width() * _textSurface.height(), pixelsP);
- pixelsP = _textSurface.getBasePtr(0, _textSurface.height() - 1);
- Common::fill(pixelsP, pixelsP + _textSurface.width(), _vm->_palette->BLACK);
-
- if (_scrollCount > 0) {
- // Handling final scrolling of text off of screen
- if (--_scrollCount == 0) {
- scriptDone();
- return;
- }
- } else {
- // Handling a text row
- if (++_lineY == (_vm->_font->current()->getHeight() + TEXTVIEW_LINE_SPACING))
- processLines();
- }
-
- // Refresh the view
- int yp = (height() - _bgSurface.height()) / 2;
- _bgSurface.copyTo(this, 0, yp);
- _textSurface.copyTo(this, Common::Rect(0, 0, _textSurface.width(), _bgSurface.height()),
- 0, yp, _vm->_palette->BLACK);
-}
-
-void TextviewView::scriptDone() {
- TextviewCallback fn = _callback;
- MadsM4Engine *vm = _vm;
-
- // Remove this view from manager and destroy it
- _vm->_viewManager->deleteView(this);
-
- if (fn)
- fn(vm);
-}
-
-void TextviewView::processLines() {
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- if (_script->eos() || _script->err())
- error("Attempted to read past end of response file");
-
- while (!_script->eos() && !_script->err()) {
- // Commented out line, so go loop for another
- if (_currentLine[0] == '#') {
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- continue;
- }
-
- // Process the line
- char *cStart = strchr(_currentLine, '[');
- if (cStart) {
- while (cStart) {
- // Loop for possible multiple commands on one line
- char *cEnd = strchr(_currentLine, ']');
- if (!cEnd)
- error("Unterminated command '%s' in response file", _currentLine);
-
- *cEnd = '\0';
- processCommand();
-
- // Copy rest of line (if any) to start of buffer
- strcpy(_currentLine, cEnd + 1);
-
- cStart = strchr(_currentLine, '[');
- }
-
- if (_currentLine[0]) {
- processText();
- break;
- }
-
- } else {
- processText();
- break;
- }
-
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- }
-}
-
-void TextviewView::processCommand() {
- char commandStr[80];
- char *paramP;
- strcpy(commandStr, _currentLine + 1);
- str_upper(commandStr);
-
- if (!strncmp(commandStr, "BACKGROUND", 10)) {
- // Set the background
- paramP = commandStr + 10;
- int screenId = getParameter(&paramP);
- _bgSurface.loadBackground(screenId, &_bgCurrent);
- _vm->_palette->addRange(_bgCurrent);
- _bgSurface.translate(_bgCurrent);
-
- } else if (!strncmp(commandStr, "GO", 2)) {
- _animating = true;
-
- // Grab what the final palete will be
- RGB8 destPalette[256];
- _vm->_palette->grabPalette(destPalette, 0, 256);
-
- // Copy the loaded background, if any, to the view surface
- int yp = (height() - _bgSurface.height()) / 2;
- _bgSurface.copyTo(this, 0, yp);
-
- // Handle fade-in
- _processEvents = false; // stop processing events during fade-in
- _vm->_palette->fadeIn(TV_NUM_FADE_STEPS, TV_FADE_DELAY_MILLI, destPalette, 256);
- _processEvents = true;
-
- } else if (!strncmp(commandStr, "PAN", 3)) {
- // Set panning values
- paramP = commandStr + 3;
- int panX = getParameter(&paramP);
- int panY = getParameter(&paramP);
- int panSpeed = getParameter(&paramP);
-
- if ((panX != 0) || (panY != 0)) {
- _panX = panX;
- _panY = panY;
- _panSpeed = panSpeed;
- }
-
- } else if (!strncmp(commandStr, "DRIVER", 6)) {
- // Set the driver to use
- // TODO: Handling of the sound drivers
-
- } else if (!strncmp(commandStr, "SOUND", 5)) {
- // Set sound number
- paramP = commandStr + 5;
- //int soundId = getParameter(&paramP);
-
- //TODO: Proper handling of the sound drivers/sounds
- //if (!_soundDriverLoaded)
- // error("Attempted to set sound without loading any driver");
-
- } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') || (commandStr[5] == '1'))) {
- // Set the text colors
- int index = commandStr[5] - '0';
- paramP = commandStr + 6;
-
- RGB8 palEntry;
- palEntry.r = getParameter(&paramP) << 2;
- palEntry.g = getParameter(&paramP) << 2;
- palEntry.b = getParameter(&paramP) << 2;
- _vm->_palette->setPalette(&palEntry, 5 + index, 1);
-
- } else if (!strncmp(commandStr, "SPARE", 5)) {
- // Sets a secondary background number that can be later switched in with a PAGE command
- paramP = commandStr + 6;
- int spareIndex = commandStr[5] - '0';
- if ((spareIndex >= 0) && (spareIndex <= 9)) {
- int screenId = getParameter(&paramP);
-
- _spareScreens[spareIndex] = screenId;
- }
-
- } else if (!strncmp(commandStr, "PAGE", 4)) {
- // Signals to change to a previous specified secondary background
- paramP = commandStr + 4;
- int spareIndex = getParameter(&paramP);
-
- // Only allow background switches if one isn't currently in progress
- if (!_spareScreen && (_spareScreens[spareIndex] != 0)) {
- _spareScreen = new M4Surface(width(), MADS_SURFACE_HEIGHT);
- _spareScreen->loadBackground(_spareScreens[spareIndex], &_bgSpare);
- _vm->_palette->addRange(_bgSpare);
- _spareScreen->translate(_bgSpare);
-
- _translationX = 0;
- }
-
- } else {
- error("Unknown response command: '%s'", commandStr);
- }
-}
-
-int TextviewView::getParameter(char **paramP) {
- if ((**paramP != '=') && (**paramP != ','))
- return 0;
-
- int result = 0;
- ++*paramP;
- while ((**paramP >= '0') && (**paramP <= '9')) {
- result = result * 10 + (**paramP - '0');
- ++*paramP;
- }
-
- return result;
-}
-
-void TextviewView::processText() {
- int lineWidth, xStart;
-
- if (!strcmp(_currentLine, "***")) {
- // Special signifier for end of script
- _scrollCount = _vm->_font->current()->getHeight() * 13;
- _lineY = -1;
- return;
- }
-
- _lineY = 0;
-
- // Lines are always centered, except if line contains a '@', in which case the
- // '@' marks the position that must be horizontally centered
- char *centerP = strchr(_currentLine, '@');
- if (centerP) {
- *centerP = '\0';
- xStart = (width() / 2) - _vm->_font->current()->getWidth(_currentLine);
-
- // Delete the @ character and shift back the remainder of the string
- char *p = centerP + 1;
- if (*p == ' ') ++p;
- strcpy(centerP, p);
-
- } else {
- lineWidth = _vm->_font->current()->getWidth(_currentLine);
- xStart = (width() - lineWidth) / 2;
- }
-
- // Copy the text line onto the bottom of the textSurface surface, which will allow it
- // to gradually scroll onto the screen
- int yp = _textSurface.height() - _vm->_font->current()->getHeight() - TEXTVIEW_LINE_SPACING;
- _textSurface.fillRect(Common::Rect(0, yp, _textSurface.width(), _textSurface.height()),
- _vm->_palette->BLACK);
- _vm->_font->current()->writeString(&_textSurface, _currentLine, xStart, yp);
-}
-
-
-//--------------------------------------------------------------------------
-
-AnimviewView::AnimviewView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())),
- MadsView(this), _backgroundSurface(MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT),
- _codeSurface(MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT) {
-
- MadsView::_bgSurface = &_backgroundSurface;
- MadsView::_depthSurface = &_codeSurface;
- MadsView::setViewport(Common::Rect(0, MADS_Y_OFFSET, MADS_SURFACE_WIDTH, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT));
-
- _screenType = VIEWID_ANIMVIEW;
- _screenFlags.layer = LAYER_BACKGROUND;
- _screenFlags.visible = true;
- _screenFlags.get = SCREVENT_ALL;
- _callback = NULL;
- _script = NULL;
- _palData = NULL;
- _previousUpdate = 0;
- _transition = kTransitionNone;
- _activeAnimation = NULL;
- _bgLoadFlag = true;
- _startFrame = -1;
- _scriptDone = false;
-
- reset();
-
- // Set up system palette colors
- _vm->_palette->setMadsSystemPalette();
-
- // Block reserved palette ranges
- _vm->_palette->blockRange(16, 2);
- _vm->_palette->blockRange(250, 4);
-
- clear();
- _backgroundSurface.clear();
-
- setColor(2);
- hLine(0, width() - 1, MADS_Y_OFFSET - 2);
- hLine(0, width() - 1, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT + 2);
-}
-
-AnimviewView::~AnimviewView() {
- if (_script)
- _vm->res()->toss(_resourceName);
- delete _activeAnimation;
-}
-
-void AnimviewView::reset() {
- _backgroundSurface.clear();
- _soundDriverLoaded = false;
-}
-
-void AnimviewView::setScript(const char *resourceName, AnimviewCallback callback) {
- _callback = callback;
- if (_script)
- _vm->res()->toss(_resourceName);
-
- reset();
-
- strncpy(_resourceName, resourceName, 15);
- _resourceName[15] = '\0';
- if (!strchr(_resourceName, '.'))
- strcat(_resourceName, ".res");
-
- _script = _vm->res()->get(_resourceName);
-}
-
-bool AnimviewView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- // Wait for the Escape key or a mouse press
- if (((eventType == KEVENT_KEY) && (param == Common::KEYCODE_ESCAPE)) ||
- (eventType == MEVENT_LEFT_RELEASE) || (eventType == MEVENT_RIGHT_RELEASE)) {
- scriptDone();
- captureEvents = false;
- return true;
- }
-
- return false;
-}
-
-void AnimviewView::updateState() {
- MadsView::update();
-
- if (!_script || _scriptDone)
- return;
-
- if (!_activeAnimation) {
- readNextCommand();
- assert(_activeAnimation);
- }
-
- // Update the current animation
- _activeAnimation->update();
- if (_activeAnimation->freeFlag()) {
- delete _activeAnimation;
- _activeAnimation = NULL;
-
- // Clear up current background and sprites
- _backgroundSurface.reset();
- clearLists();
-
- // Reset flags
- _startFrame = -1;
-
- readNextCommand();
-
- // Check if script is finished
- if (_scriptDone) {
- scriptDone();
- return;
- }
- }
-
- refresh();
-}
-
-void AnimviewView::readNextCommand() {
-static bool tempFlag = true;//****DEBUG - Temporarily allow me to skip several intro scenes ****
-
- while (!_script->eos() && !_script->err()) {
- if (!tempFlag) {
- tempFlag = true;
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- strncpy(_currentLine, _script->readLine().c_str(), 79);
- }
-
- strncpy(_currentLine, _script->readLine().c_str(), 79);
-
- // Process any switches on the line
- char *cStart = strchr(_currentLine, '-');
- while (cStart) {
- // Loop for possible multiple commands on one line
- char *cEnd = strchr(_currentLine, ' ');
- if (!cEnd)
- error("Unterminated command '%s' in response file", _currentLine);
-
- *cEnd = '\0';
- processCommand();
-
- // Copy rest of line (if any) to start of buffer
- // Don't use strcpy() here, because if the
- // rest of the line is the longer of the two
- // strings, the memory areas will overlap.
- memmove(_currentLine, cEnd + 1, strlen(cEnd + 1) + 1);
-
- cStart = strchr(_currentLine, '-');
- }
-
- // If there's something left, presume it's a resource name to process
- if (_currentLine[0])
- break;
- }
-
- if (!_currentLine[0]) {
- // A blank line at this point means that the end of the animation has been reached
- _scriptDone = true;
- return;
- }
-
- if (strchr(_currentLine, '.') == NULL)
- strcat(_currentLine, ".aa");
-
- uint16 flags = 0;
- if (_bgLoadFlag)
- flags |= 0x100;
-
- _activeAnimation = new MadsAnimation(_vm, this);
- _activeAnimation->initialize(_currentLine, flags, &_backgroundSurface, &_codeSurface);
-
- if (_startFrame != -1)
- _activeAnimation->setCurrentFrame(_startFrame);
-
- _spriteSlots.fullRefresh();
-/*
- // Handle scene transition
- switch (_transition) {
- case kTransitionNone:
- // nothing to do
- break;
- case kTransitionFadeIn:
- case kTransitionFadeIn2:
- _vm->_palette->fadeIn(TV_NUM_FADE_STEPS, TV_FADE_DELAY_MILLI, destPalette, 256);
- break;
- case kTransitionBoxInBottomLeft:
- case kTransitionBoxInBottomRight:
- case kTransitionBoxInTopLeft:
- case kTransitionBoxInTopRight:
- // unused
- warning("Unsupported box in scene effect");
- break;
- case kTransitionPanLeftToRight:
- // TODO
- break;
- case kTransitionPanRightToLeft:
- // TODO
- break;
- case kTransitionCircleIn:
- // TODO
- break;
- default:
- // nothing to do
- break;
- }
-*/
-
- _vm->_resourceManager->toss(_currentLine);
-}
-
-
-void AnimviewView::scriptDone() {
-return;
- AnimviewCallback fn = _callback;
- MadsM4Engine *vm = _vm;
-
- // Remove this view from manager and destroy it
- _vm->_viewManager->deleteView(this);
-
- if (fn)
- fn(vm);
-}
-
-/*
-Switches are: (taken from the help of the original executable)
- -b Toggle background load status off/on.
- -c:char Specify sound card id letter.
- -f:num Specify a specific starting frame number
- -g Stay in graphics mode on exit.
- -h[:ex] Disable EMS/XMS high memory support.
- -i Switch sound interrupts mode off/on.
- -j Wait for music to finish at end.
- -k Keystroke jumps to end instead of abort.
- -m Operate in non-MADS mode.
- -o:xxx Specify opening special effect.
- -p Switch MADS path mode to CONCAT.
- -r[:abn] Resynch timer (always, beginning, never).
- -s:file Specify sound file.
- -u[:...] Use DMA speech [optional: addr,type,irq,drq].
- -w Toggle white bars off/on.
- -x Exit immediately after last frame.
- -y Do not clear screen initially
- -z Display statistics after run.
-
- Opening special effects are:
- 0: no effect
- 1: fade in
- 2: fade in (looks to be the same as 1)
- 3: box in from bottom left (unused)
- 4: box in from bottom right (unused)
- 5: box in from top left (unused)
- 6: box in from top right (unused)
- 7: pan in from left to right
- 8: pan in from right to left
- 9: circle in (new scene appears in a circle that expands)
-
- Animview is ran like this from the original games:
- animview.exe @resfilename -c:P,220,20 -u:220,20,07,01 -p -a:mainmenu -p
-
- Note that the first -p is necessary to watch the animation, otherwise
- the program just exits
-
- To watch an animation within the *.res file, just run animview like this:
- animview.exe -x -r:b -o:2 animfilename -p
-*/
-void AnimviewView::processCommand() {
- char commandStr[80];
- strcpy(commandStr, _currentLine + 1);
- str_upper(commandStr);
- char *param = commandStr;
-
- switch (commandStr[0]) {
- case 'B':
- // Toggle background load flag
- _bgLoadFlag = !_bgLoadFlag;
- break;
-
- case 'F':
- // Start animation at a specific frame
- ++param;
- assert(*param == ':');
- _startFrame = atoi(++param);
- break;
-
- case 'O':
- param = param + 2;
- //warning(kDebugGraphics, "O:%i ", atoi(param));
- _transition = atoi(param);
- break;
-
- case 'R':
- param = param + 2;
- //warning(kDebugGraphics, "R:%s ", param);
- break;
-
- case 'W':
- //warning(kDebugGraphics, "W ");
- break;
-
- case 'X':
- //warning(kDebugGraphics, "X ");
- break;
-
- default:
- error("Unknown response command: '%s'", commandStr);
- }
-}
-
-}
diff --git a/engines/m4/mads_anim.h b/engines/m4/mads_anim.h
deleted file mode 100644
index 411d575d59..0000000000
--- a/engines/m4/mads_anim.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_MADS_ANIM_H
-#define M4_MADS_ANIM_H
-
-#include "m4/viewmgr.h"
-#include "m4/compression.h"
-#include "m4/animation.h"
-
-#include "common/str-array.h"
-
-namespace M4 {
-
-typedef void (*TextviewCallback)(MadsM4Engine *vm);
-
-class TextviewView : public View {
-private:
- bool _animating;
-
- char _resourceName[80];
- Common::SeekableReadStream *_script;
- uint16 _spareScreens[10];
- M4Surface *_spareScreen;
- RGBList *_bgCurrent, *_bgSpare;
- int _translationX;
- int _panX, _panY, _panSpeed;
- int _panCountdown;
- char _currentLine[80];
- uint32 _scrollTimeout;
- int _scrollCount;
- int _lineY;
- M4Surface _bgSurface;
- M4Surface _textSurface;
- TextviewCallback _callback;
- bool _soundDriverLoaded;
- bool _processEvents;
-
- void reset();
- void processLines();
- void processCommand();
- void processText();
- int getParameter(char **paramP);
-public:
- TextviewView(MadsM4Engine *vm);
- ~TextviewView();
-
- void setScript(const char *resourceName, TextviewCallback callback);
- bool isAnimating() { return _animating; }
- void scriptDone();
-
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-typedef void (*AnimviewCallback)(MadsM4Engine *vm);
-
-class AnimviewView : public View, MadsView {
-private:
- char _resourceName[80];
- Common::SeekableReadStream *_script;
- bool _scriptDone;
- uint32 _previousUpdate;
- char _currentLine[80];
- M4Surface _backgroundSurface;
- M4Surface _codeSurface;
- AnimviewCallback _callback;
- bool _soundDriverLoaded;
- RGBList *_palData;
- int _transition;
- MadsAnimation *_activeAnimation;
- bool _bgLoadFlag;
- int _startFrame;
-
- void reset();
- void readNextCommand();
- void processCommand();
-public:
- AnimviewView(MadsM4Engine *vm);
- ~AnimviewView();
-
- void setScript(const char *resourceName, AnimviewCallback callback);
- void scriptDone();
-
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp
deleted file mode 100644
index a7838d0e26..0000000000
--- a/engines/m4/mads_logic.cpp
+++ /dev/null
@@ -1,1038 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/dialogs.h"
-#include "m4/mads_logic.h"
-#include "m4/scene.h"
-
-#define MAX_CALL_PARAMS 10
-
-namespace M4 {
-
-void MadsGameLogic::initializeGlobals() {
- // Clear the entire globals list
- Common::fill(&_madsVm->globals()->_globals[0], &_madsVm->globals()->_globals[TOTAL_NUM_VARIABLES], 0);
-
- SET_GLOBAL(4, 8);
- SET_GLOBAL(33, 1);
- SET_GLOBAL(10, 0xFFFF);
- SET_GLOBAL(13, 0xFFFF);
- SET_GLOBAL(15, 0xFFFF);
- SET_GLOBAL(19, 0xFFFF);
- SET_GLOBAL(20, 0xFFFF);
- SET_GLOBAL(21, 0xFFFF);
- SET_GLOBAL(95, 0xFFFF);
-
- // TODO: unknown sub call
-
- // Put the values 0 through 3 in a random ordering in global slots 83 - 86
- for (int idx = 0; idx < 4; ) {
- int randVal = _madsVm->_random->getRandomNumber(4);
- SET_GLOBAL(83 + idx, randVal);
-
- // Check whether the given value has already been used
- bool flag = false;
- for (int idx2 = 0; idx2 < idx; ++idx2) {
- if (randVal == GET_GLOBAL(83 + idx2))
- flag = true;
- }
-
- if (!flag)
- ++idx;
- }
-
- // Put the values 0 through 3 in a random ordering in global slots 87 - 90
- for (int idx = 0; idx < 4; ) {
- int randVal = _madsVm->_random->getRandomNumber(3);
- SET_GLOBAL(87 + idx, randVal);
-
- // Check whether the given value has already been used
- bool flag = false;
- for (int idx2 = 0; idx2 < idx; ++idx2) {
- if (randVal == GET_GLOBAL(87 + idx2))
- flag = true;
- }
-
- if (!flag)
- ++idx;
- }
-
- // Miscellaneous global settings
- SET_GLOBAL(120, 501);
- SET_GLOBAL(121, 0xFFFF);
- SET_GLOBAL(110, 0xFFFF);
- SET_GLOBAL(119, 1);
- SET_GLOBAL(134, 4);
- SET_GLOBAL(190, 201);
- SET_GLOBAL(191, 301);
- SET_GLOBAL(192, 413);
- SET_GLOBAL(193, 706);
- SET_GLOBAL(194, 801);
- SET_GLOBAL(195, 551);
- SET_GLOBAL(196, 752);
-
- // Fill out the globals 200 - 209 with unique random number values less than 10000
- for (int idx = 0; idx < 10; ) {
- int randVal = _madsVm->_random->getRandomNumber(9999);
- SET_GLOBAL(200 + idx, randVal);
-
- // Check whether the given value has already been used
- bool flag = false;
- for (int idx2 = 0; idx2 < idx; ++idx2) {
- if (randVal == GET_GLOBAL(87 + idx2))
- flag = true;
- }
-
- if (!flag)
- ++idx;
- }
-
- switch (_madsVm->globals()->_difficultyLevel) {
- case 1:
- // Very hard
- SET_GLOBAL(35, 0);
- // TODO: object set room
- SET_GLOBAL(137, 5);
- SET_GLOBAL(136, 0);
- break;
-
- case 2:
- // Hard
- SET_GLOBAL(35, 0);
- // TODO: object set room
- SET_GLOBAL(136, 0xFFFF);
- SET_GLOBAL(137, 6);
- break;
-
- case 3:
- // Easy
- SET_GLOBAL(35, 2);
- // TODO: object set room
- break;
- }
-
- _madsVm->_player._direction = 8;
- _madsVm->_player._newDirection = 8;
-
- // TODO: unknown processing routine getting called for 'RXM' and 'ROX'
-}
-
-/*--------------------------------------------------------------------------*/
-
-const char *MadsSceneLogic::subFormatList[] = {"scene%d_enter", "scene%d_step", "scene%d_preaction", "scene%d_actions"};
-
-#define OPSIZE8 0x40 ///< when this bit is set - the operand size is 8 bits
-#define OPSIZE16 0x80 ///< when this bit is set - the operand size is 16 bits
-#define OPMASK 0x3F ///< mask to isolate the opcode
-
-enum Opcodes {
- OP_HALT = 0, OP_IMM = 1, OP_ZERO = 2, OP_ONE = 3, OP_MINUSONE = 4, OP_STR = 5, OP_DLOAD = 6,
- OP_DSTORE = 7, OP_PAL = 8, OP_LOAD = 9, OP_GLOAD = 10, OP_STORE = 11, OP_GSTORE = 12,
- OP_CALL = 13, OP_LIBCALL = 14, OP_RET = 15, OP_ALLOC = 16, OP_JUMP = 17, OP_JMPFALSE = 18,
- OP_JMPTRUE = 19, OP_EQUAL = 20, OP_LESS = 21, OP_LEQUAL = 22, OP_NEQUAL = 23, OP_GEQUAL = 24,
- OP_GREAT = 25, OP_PLUS = 26, OP_MINUS = 27, OP_LOR = 28, OP_MULT = 29, OP_DIV = 30,
- OP_MOD = 31, OP_AND = 32, OP_OR = 33, OP_EOR = 34, OP_LAND = 35, OP_NOT = 36, OP_COMP = 37,
- OP_NEG = 38, OP_DUP = 39,
- TOTAL_OPCODES = 40
-};
-
-const char *MadsSceneLogic::_opcodeStrings[] = {
- "HALT", "IMM", "ZERO", "ONE", "MINUSONE", "STR", "DLOAD", "DSTORE", NULL, "LOAD", "GLOAD",
- "STORE", "GSTORE", "CALL", "LIBCALL", "RET", "ALLOC", "JUMP", "JMPFALSE", "JMPTRUE", "EQUAL",
- "LESS", "LEQUAL", "NEQUAL", "GEQUAL", "GREAT", "PLUS", "MINUS", "LOR", "MULT", "DIV",
- "MOD", "AND", "OR", "EOR", "LAND", "NOT", "COMP", "NEG", "DUP"
-};
-
-/**
- * This method sets up the data map with pointers to all the common game objects. This allows the script engine to
- * convert game specific offsets for various fields in the original game's data segment into a generic data index
- * that will be common across all the MADS games
-
-void MadsSceneLogic::initializeDataMap() {
- // The unique order of these items must be maintained
-}
-*/
-
-uint32 MadsSceneLogic::getDataValue(int dataId) {
- switch (dataId) {
- case 1:
- return _madsVm->scene()->_abortTimersMode2;
- case 2:
- return _madsVm->scene()->_abortTimers;
- case 3:
- return _madsVm->_player._stepEnabled ? 0xffff : 0;
- case 4:
- return _madsVm->scene()->_nextScene;
- case 5:
- return _madsVm->scene()->_previousScene;
- case 6:
- return _madsVm->_player._playerPos.x;
- case 7:
- return _madsVm->_player._playerPos.y;
- case 8:
- return _madsVm->_player._direction;
- case 9:
- return _madsVm->_player._visible ? 0xffff : 0;
- case 10:
- return getActiveAnimationBool();
- case 11:
- return getAnimationCurrentFrame();
- case 12:
- return _madsVm->scene()->_action._inProgress;
- case 13:
- return _madsVm->globals()->_difficultyLevel;
- default:
- // All other data variables get stored in the hash table
- return _madsVm->globals()->_dataMap[dataId];
- break;
- }
-}
-
-void MadsSceneLogic::setDataValue(int dataId, uint16 dataValue) {
- switch (dataId) {
- case 1:
- _madsVm->scene()->_abortTimersMode2 = (AbortTimerMode)dataValue;
- break;
- case 2:
- _madsVm->scene()->_abortTimers = dataValue;
- break;
- case 3:
- _madsVm->_player._stepEnabled = dataValue != 0;
- break;
- case 4:
- _madsVm->scene()->_nextScene = dataValue;
- break;
- case 5:
- _madsVm->scene()->_previousScene = dataValue;
- break;
- case 6:
- _madsVm->_player._playerPos.x = dataValue;
- break;
- case 7:
- _madsVm->_player._playerPos.y = dataValue;
- break;
- case 8:
- _madsVm->_player._direction = dataValue;
- break;
- case 9:
- _madsVm->_player._visible = dataValue != 0;
- break;
- case 10:
- case 11:
- error("Tried to set read only data field %d", dataId);
- break;
- case 12:
- _madsVm->scene()->_action._inProgress = dataValue != 0;
- break;
- case 13:
- _madsVm->globals()->_difficultyLevel = dataValue;
- break;
- default:
- // All other data variables get stored in the hash table
- _madsVm->globals()->_dataMap[dataId] = dataValue;
- break;
- }
-}
-
-const char *MadsSceneLogic::formAnimName(char sepChar, int16 suffixNum) {
- return MADSResourceManager::getResourceName(sepChar, _sceneNumber, EXTTYPE_NONE, NULL, suffixNum);
-}
-
-void MadsSceneLogic::getSceneSpriteSet() {
- char prefix[100];
-
- // Room change sound
- _madsVm->_sound->playSound(5);
-
- // Set up sprite set prefix to use
- if ((_sceneNumber <= 103) || (_sceneNumber == 111)) {
- if (_madsVm->globals()->_globals[0] == SEX_FEMALE)
- strcpy(prefix, "ROX");
- else
- strcpy(prefix, "RXM");
- } else if (_sceneNumber <= 110) {
- strcpy(prefix, "RXSW");
- _madsVm->globals()->_globals[0] = SEX_UNKNOWN;
- } else if (_sceneNumber == 112)
- strcpy(prefix, "");
-
- _madsVm->globals()->playerSpriteChanged = true;
- _madsVm->_player.loadSprites(prefix);
-
-// if ((_sceneNumber == 105) ((_sceneNumber == 109) && (word_84800 != 0)))
-// _madsVm->globals()->playerSpriteChanged = true;
-
- _vm->_palette->setEntry(16, 0x38, 0xFF, 0xFF);
- _vm->_palette->setEntry(17, 0x38, 0xb4, 0xb4);
-}
-
-void MadsSceneLogic::getAnimName() {
- const char *newName = MADSResourceManager::getAAName(
- ((_sceneNumber <= 103) || (_sceneNumber > 111)) ? 0 : 1);
- strcpy(_madsVm->scene()->_aaName, newName);
-}
-
-/*--------------------------------------------------------------------------*/
-
-uint16 MadsSceneLogic::loadSpriteSet(uint16 suffixNum, uint16 sepChar) {
- assert(sepChar < 256);
- const char *resName = formAnimName((char)sepChar, (int16)suffixNum);
- return _madsVm->scene()->loadSceneSpriteSet(resName);
-}
-
-uint16 MadsSceneLogic::startReversibleSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
- M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0);
- uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2),
- spriteFrame->y + (spriteFrame->height() / 2)));
-
- return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
- true, 100, depth - 1, 1, ANIMTYPE_REVERSIBLE, 0, 0);
-}
-
-uint16 MadsSceneLogic::startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
- M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0);
- uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2),
- spriteFrame->y + (spriteFrame->height() / 2)));
-
- return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
- true, 100, depth - 1, 1, ANIMTYPE_CYCLED, 0, 0);
-}
-
-uint16 MadsSceneLogic::startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) {
- M4Sprite *spriteFrame = _madsVm->scene()->_spriteSlots.getSprite(srcSpriteIdx).getFrame(0);
- uint8 depth = _madsVm->_rails->getDepth(Common::Point(spriteFrame->x + (spriteFrame->width() / 2),
- spriteFrame->y + (spriteFrame->height() / 2)));
-
- return _madsVm->scene()->_sequenceList.add(srcSpriteIdx, flipped, 1, triggerCountdown, timeoutTicks, extraTicks, numTicks, 0, 0,
- true, 100, depth - 1, -1, ANIMTYPE_CYCLED, 0, 0);
-}
-
-void MadsSceneLogic::activateHotspot(int idx, bool active) {
- // TODO:
-}
-
-void MadsSceneLogic::getPlayerSpritesPrefix() {
- _madsVm->_sound->playSound(5);
-
- char oldName[80];
- strcpy(oldName, _madsVm->_player._spritesPrefix);
-
- if ((_madsVm->globals()->_nextSceneId <= 103) || (_madsVm->globals()->_nextSceneId == 111))
- strcpy(_madsVm->_player._spritesPrefix, (_madsVm->globals()->_globals[0] == SEX_FEMALE) ? "ROX" : "RXM");
- else if (_madsVm->globals()->_nextSceneId <= 110)
- strcpy(_madsVm->_player._spritesPrefix, "RXSM");
- else if (_madsVm->globals()->_nextSceneId == 112)
- strcpy(_madsVm->_player._spritesPrefix, "");
-
- if (strcmp(oldName, _madsVm->_player._spritesPrefix) != 0)
- _madsVm->_player._spritesChanged = true;
-
- if ((_madsVm->globals()->_nextSceneId == 105) ||
- ((_madsVm->globals()->_nextSceneId == 109) && (_madsVm->globals()->_globals[15] != 0))) {
- // TODO: unknown flag setting
- _madsVm->_player._spritesChanged = true;
- }
-
- _madsVm->_palette->setEntry(16, 40, 255, 255);
- _madsVm->_palette->setEntry(17, 40, 180, 180);
-
-}
-
-void MadsSceneLogic::getPlayerSpritesPrefix2() {
- _madsVm->_sound->playSound(5);
-
- char oldName[80];
- strcpy(oldName, _madsVm->_player._spritesPrefix);
-
- if ((_madsVm->globals()->_nextSceneId == 213) || (_madsVm->globals()->_nextSceneId == 216))
- strcpy(_madsVm->_player._spritesPrefix, "");
- else if (_madsVm->globals()->_globals[0] == SEX_MALE)
- strcpy(_madsVm->_player._spritesPrefix, "RXM");
- else
- strcpy(_madsVm->_player._spritesPrefix, "ROX");
-
- // TODO: unknown flag setting for next scene Id > 212
-
- if (strcmp(oldName, _madsVm->_player._spritesPrefix) != 0)
- _madsVm->_player._spritesChanged = true;
-
-/* if ((_madsVm->globals()->_nextSceneId == 203) && (_madsVm->globals()->_nextSceneId == 204) &&
- (_madsVm->globals()->_globals[0x22] == 0))
- // TODO: unknown flag set
-*/
- _madsVm->_palette->setEntry(16, 40, 255, 255);
- _madsVm->_palette->setEntry(17, 40, 180, 180);
-}
-
-
-/*--------------------------------------------------------------------------*/
-
-/**
- * Loads the MADS.DAT file and loads the script data for the correct game/language
- */
-void MadsSceneLogic::initializeScripts() {
- Common::File f;
- if (!f.open("mads.dat")) {
- warning("Could not locate mads.dat file");
- return;
- }
-
- // Validate that the file being read is a valid mads.dat file
- char header[4];
- f.read(&header[0], 4);
- if (strncmp(header, "MADS", 4) != 0) {
- warning("Invalid mads.dat file");
- return;
- }
-
- // Get a list of the offsets of game blocks
- uint32 v;
- Common::Array<uint32> offsets;
- while ((v = f.readUint32LE()) != 0)
- offsets.push_back(v);
-
- // Check the header of each block in turn
- _scriptsData = NULL;
- _scriptsSize = 0;
-
- for (uint i = 0; i < offsets.size(); ++i) {
- // Get the block header
- f.seek(offsets[i]);
- byte gameId = f.readByte();
- byte language = f.readByte();
- f.readByte(); // Language currently unused
-
- // If this block isn't for the current game, skip it
- if (_madsVm->getGameType() != (gameId + 2))
- continue;
- if ((language != 1) || (_madsVm->getLanguage() != Common::EN_ANY))
- continue;
-
- // Found script block for the given game and language.
- _scriptsSize = (i < (offsets.size() - 1)) ? offsets[i + 1] - offsets[i] : f.size() - offsets[i];
- break;
- }
-
- if (!_scriptsSize) {
- warning("Could not find appropriate scripts block for game in mads.dat file");
- f.close();
- return;
- }
-
- // Load up the list of subroutines into a hash map
- uint32 blockOffset = f.pos() - 3;
- uint32 subsStart = 0;
- for (;;) {
- // Get next entry
- Common::String subName;
- char c;
- while ((c = (char)f.readByte()) != '\0')
- subName += c;
- if (subName.empty())
- // Reached end of subroutine list
- break;
-
- // Read in the offset of the routine
- uint32 offset = f.readUint32LE();
- if (_subroutines.empty()) {
- // The first subroutine offset is used to reduce the amount of data to later load in. In essence,
- // the subroutine index will not be separately loaded, since it's contents will be in the hash map
- subsStart = offset;
- _scriptsSize -= offset;
- }
-
- _subroutines[subName] = offset - subsStart;
- _subroutineOffsets.push_back(offset - subsStart);
- }
-
- // Read in the remaining data
- f.seek(blockOffset + subsStart, SEEK_SET);
- _scriptsData = (byte *)malloc(_scriptsSize);
- f.read(_scriptsData, _scriptsSize);
-
- f.close();
-}
-
-void MadsSceneLogic::selectScene(int sceneNum) {
- assert(sceneNum == 101);
- _sceneNumber = sceneNum;
-
- Common::fill(&_spriteIndexes[0], &_spriteIndexes[50], 0);
-
- // If debugging is turned on, show a debug warning if any of the scene methods aren't present
- if (gDebugLevel > 0) {
- for (int i = 0; i < 4; ++i) {
- char buffer[20];
- sprintf(buffer, subFormatList[i], sceneNum);
- Common::HashMap<Common::String, uint32>::iterator it = _subroutines.find(Common::String(buffer));
- if (it == _subroutines.end())
- debugC(1, kDebugScript, "Scene method %s not found", buffer);
- }
- }
-}
-
-void MadsSceneLogic::setupScene() {
- // FIXME: This is the hardcoded logic for Rex scene 101 only
- const char *animName = formAnimName('A', -1);
- warning("anim - %s", animName);
-
-// sub_1e754(animName, 3);
-
- if ((_sceneNumber >= 101) && (_sceneNumber <= 112))
- getPlayerSpritesPrefix();
- else
- getPlayerSpritesPrefix2();
-
- getAnimName();
-}
-
-/**
- * Handles the logic when a scene is entered
- */
-void MadsSceneLogic::doEnterScene() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_ENTER], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Handles the script execution which is called regularly every frame
- */
-void MadsSceneLogic::doSceneStep() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_STEP], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Handles and preactions before an action is started
- */
-void MadsSceneLogic::doPreactions() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_PREACTIONS], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Handles any action that has been selected
- */
-void MadsSceneLogic::doAction() {
- char buffer[20];
- sprintf(buffer, subFormatList[SUBFORMAT_ACTIONS], _sceneNumber);
- execute(Common::String(buffer));
-}
-
-/**
- * Executes the script with the specified name
- */
-void MadsSceneLogic::execute(const Common::String &scriptName) {
- Common::HashMap<Common::String, uint32>::iterator it = _subroutines.find(scriptName);
- if (it != _subroutines.end())
- execute(it->_value);
-}
-
-#define UNUSED_VAL 0xEAEAEAEA
-/**
- * Executes the script at the specified offset
- */
-void MadsSceneLogic::execute(uint32 subOffset) {
- Common::Array<ScriptVar> locals;
- Common::Stack<ScriptVar> stack;
- char opcodeBuffer[100];
- uint32 scriptOffset = subOffset;
- uint32 param;
-
- debugC(1, kDebugScript, "executing script at %xh", subOffset);
-
- bool done = false;
- while (!done) {
- param = UNUSED_VAL;
- byte opcode = _scriptsData[scriptOffset++];
- sprintf(opcodeBuffer, "%.4x[%.2d] - %s", scriptOffset - 1, stack.size(), _opcodeStrings[opcode & OPMASK]);
-
- switch (opcode & OPMASK) {
- case OP_HALT: // end of program
- case OP_RET:
- done = true;
- break;
-
- case OP_IMM: // Loads immediate value onto stack
- param = getParam(scriptOffset, opcode);
- stack.push(ScriptVar(param));
- break;
-
- case OP_ZERO: // loads zero onto stack
- stack.push(ScriptVar((uint32)0));
- break;
-
- case OP_ONE: // loads one onto stack
- stack.push(ScriptVar(1));
- break;
-
- case OP_MINUSONE: // loads minus one (0xffff) onto stack
- stack.push(ScriptVar(0xffff));
- break;
-
- case OP_DLOAD: { // Gets data variable
- param = getParam(scriptOffset, opcode);
- uint16 v = getDataValue(param);
- stack.push(ScriptVar(v));
- break;
- }
-
- case OP_DSTORE: { // Stores data variable
- param = getParam(scriptOffset, opcode);
- ScriptVar v = stack.pop();
- setDataValue(param, v.isInt() ? v.get() : 0);
- break;
- }
-
- case OP_LOAD: // loads local variable onto stack
- param = getParam(scriptOffset, opcode);
- stack.push(locals[param]);
- break;
-
- case OP_STORE: // Pops a value and stores it in a local
- // Get the local index and expand the locals store if necessary
- param = getParam(scriptOffset, opcode);
- while (param >= locals.size())
- locals.push_back(ScriptVar());
-
- locals[param] = stack.pop();
- break;
-
- case OP_GLOAD: // loads global variable onto stack
- param = getParam(scriptOffset, opcode);
- assert(param < TOTAL_NUM_VARIABLES);
- stack.push(_madsVm->globals()->_globals[param]);
- break;
-
- case OP_GSTORE: // pops stack and stores in global variable
- param = getParam(scriptOffset, opcode);
- assert(param < TOTAL_NUM_VARIABLES);
- _madsVm->globals()->_globals[param] = stack.pop().get();
- break;
-
- case OP_CALL: // procedure call
- param = getParam(scriptOffset, opcode);
- assert(param < _subroutineOffsets.size());
- execute(_subroutineOffsets[param]);
- break;
-
- case OP_LIBCALL: // library procedure or function call
- param = getParam(scriptOffset, opcode);
- callSubroutine(param, stack);
- break;
-
- case OP_JUMP: // unconditional jump
- param = subOffset + getParam(scriptOffset, opcode);
- scriptOffset = param;
- break;
-
- case OP_JMPFALSE: // conditional jump
- param = subOffset + getParam(scriptOffset, opcode);
- if (stack.pop().get() == 0)
- // Condition satisfied - do the jump
- scriptOffset = param;
- break;
-
- case OP_JMPTRUE: // conditional jump
- param = subOffset + getParam(scriptOffset, opcode);
- if (stack.pop().get() != 0)
- // Condition satisfied - do the jump
- scriptOffset = param;
- break;
-
- case OP_EQUAL: // tests top two items on stack for equality
- case OP_LESS: // tests top two items on stack
- case OP_LEQUAL: // tests top two items on stack
- case OP_NEQUAL: // tests top two items on stack
- case OP_GEQUAL: // tests top two items on stack
- case OP_GREAT: // tests top two items on stack
- case OP_LOR: // logical or of top two items on stack and replaces with result
- case OP_LAND: // logical ands top two items on stack and replaces with result
- {
- uint32 param2 = stack.pop().get();
- uint32 param1 = stack.pop().get();
-
- // Do the comparison
- uint32 tmp = 0;
- switch (opcode) {
- case OP_EQUAL: tmp = (param1 == param2); break;
- case OP_LESS: tmp = (param1 < param2); break;
- case OP_LEQUAL: tmp = (param1 <= param2); break;
- case OP_NEQUAL: tmp = (param1 != param2); break;
- case OP_GEQUAL: tmp = (param1 >= param2); break;
- case OP_GREAT: tmp = (param1 > param2); break;
-
- case OP_LOR: tmp = (param1 || param2); break;
- case OP_LAND: tmp = (param1 && param2); break;
- }
-
- stack.push(ScriptVar(tmp));
- }
- break;
-
- case OP_PLUS: // adds top two items on stack and replaces with result
- case OP_MINUS: // subs top two items on stack and replaces with result
- case OP_MULT: // multiplies top two items on stack and replaces with result
- case OP_DIV: // divides top two items on stack and replaces with result
- case OP_MOD: // divides top two items on stack and replaces with modulus
- case OP_AND: // bitwise ands top two items on stack and replaces with result
- case OP_OR: // bitwise ors top two items on stack and replaces with result
- case OP_EOR: // bitwise exclusive ors top two items on stack and replaces with result
- {
- uint32 param2 = stack.pop().get();
- uint32 param1 = stack.pop().get();
-
- // replace other operand with result of operation
- switch (opcode) {
- case OP_PLUS: param1 += param2; break;
- case OP_MINUS: param1 -= param2; break;
- case OP_MULT: param1 *= param2; break;
- case OP_DIV: param1 /= param2; break;
- case OP_MOD: param1 %= param2; break;
- case OP_AND: param1 &= param2; break;
- case OP_OR: param1 |= param2; break;
- case OP_EOR: param1 ^= param2; break;
- }
-
- stack.push(ScriptVar(param1));
- }
- break;
-
- case OP_NOT: // logical nots top item on stack
- param = stack.pop().get();
- stack.push(ScriptVar((uint32)(!param) & 0xffff));
- break;
-
- case OP_COMP: // complements top item on stack
- param = stack.pop().get();
- stack.push(ScriptVar((~param) & 0xffff));
- break;
-
- case OP_NEG: // negates top item on stack
- param = stack.pop().get();
- stack.push(ScriptVar(((uint32)-(int32)param) & 0xffff));
- break;
-
- case OP_DUP: // duplicates top item on stack
- stack.push(stack.top());
- break;
-
- default:
- error("execute() - Unknown opcode");
- }
-
- // check for stack size
- assert(stack.size() < 100);
-
- if (gDebugLevel > 0) {
- if (param != UNUSED_VAL)
- sprintf(opcodeBuffer + strlen(opcodeBuffer), "\t%u", param);
- debugC(2, kDebugScript, "%s", opcodeBuffer);
- }
- }
-
- debugC(1, kDebugScript, "finished executing script");
-
- // make sure stack is unwound
- assert(stack.size() == 0);
-}
-
-uint32 MadsSceneLogic::getParam(uint32 &scriptOffset, int opcode) {
- switch (opcode & (~OPMASK)) {
- case OPSIZE8:
- return _scriptsData[scriptOffset++];
- case OPSIZE16: {
- uint16 v = READ_LE_UINT16(&_scriptsData[scriptOffset]);
- scriptOffset += sizeof(uint16);
- return v;
- }
- default: {
- uint32 v = READ_LE_UINT32(&_scriptsData[scriptOffset]);
- scriptOffset += sizeof(uint32);
- return v;
- }
- }
-}
-
-/**
- * Support method for extracting the required number of parameters needed for a library routine call
- */
-void MadsSceneLogic::getCallParameters(int numParams, Common::Stack<ScriptVar> &stack, ScriptVar *callParams) {
- assert(numParams <= MAX_CALL_PARAMS);
- for (int i = 0; i < numParams; ++i, ++callParams)
- *callParams = stack.pop();
-}
-
-#define EXTRACT_PARAMS(n) getCallParameters(n, stack, p)
-
-void MadsSceneLogic::callSubroutine(int subIndex, Common::Stack<ScriptVar> &stack) {
- ScriptVar p[MAX_CALL_PARAMS];
-
- switch (subIndex) {
- case 1: {
- // dialog_show
- EXTRACT_PARAMS(1);
- Dialog *dlg = new Dialog(_vm, p[0].getStr(), "TODO: Proper Title");
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
- break;
- }
-
- case 2:
- // SequenceList_remove
- EXTRACT_PARAMS(1);
- _madsVm->scene()->_sequenceList.remove(p[0]);
- break;
-
- case 3:
- case 6:
- case 20: {
- // 3: start_reversible_sprite_sequence
- // 6: start_cycled_sprite_sequence
- // 20: start_sprite_sequence3
- EXTRACT_PARAMS(6);
- int idx;
- if (subIndex == 3)
- idx = startReversibleSpriteSequence(p[0], p[1] != 0, p[2], p[3], p[4], p[5]);
- else if (subIndex == 6)
- idx = startCycledSpriteSequence(p[0], p[1], p[2], p[3], p[4], p[5]);
- else
- idx = startSpriteSequence3(p[0], p[1] != 0, p[2], p[3], p[4], p[5]);
- stack.push(ScriptVar(idx));
- break;
- }
-
- case 4:
- // SequenceList_setAnimRange
- EXTRACT_PARAMS(3);
- _madsVm->scene()->_sequenceList.setAnimRange(p[0], p[1], p[2]);
- break;
-
- case 5:
- // SequenceList_addSubEntry
- EXTRACT_PARAMS(4);
- stack.push(ScriptVar(_madsVm->scene()->_sequenceList.addSubEntry(p[0], (SequenceSubEntryMode)p[1].get(), p[2], p[3])));
- break;
-
- case 7: {
- // quotes_get_pointer
- EXTRACT_PARAMS(1);
- const char *quoteStr = _madsVm->globals()->getQuote(p[0]);
- stack.push(ScriptVar(quoteStr));
- break;
- }
-
- case 8: {
- // KernelMessageList_add
- EXTRACT_PARAMS(8);
- int msgIndex = _madsVm->scene()->_kernelMessages.add(Common::Point(p[0], p[1]), p[2],
- p[3], p[4], p[5] | (p[6] << 16), p[7].getStr());
- stack.push(ScriptVar(msgIndex));
- break;
- }
-
- case 9:
- // SequenceList_unk3
- EXTRACT_PARAMS(1);
- // TODO: Implement unk3 method
-// stack.push(ScriptVar(_madsVm->scene()->_sequenceList.unk3(p[0])));
- break;
-
- case 10:
- // start_sound
- EXTRACT_PARAMS(1);
- _madsVm->_sound->playSound(p[0]);
- break;
-
- case 11:
- // SceneLogic_formAnimName
- EXTRACT_PARAMS(2);
- stack.push(ScriptVar(formAnimName((char)p[0], p[1])));
- break;
-
- case 12:
- // SpriteList_addSprites
- EXTRACT_PARAMS(2);
- stack.push(ScriptVar(_madsVm->scene()->_spriteSlots.addSprites(p[0].getStr(), false, p[1])));
- break;
-
- case 13:
- // hotspot_activate
- EXTRACT_PARAMS(2);
- // TODO: Implement setActive version that takes in a hotspot Id
-// _madsVm->scene()->getSceneResources().hotspots->setActive(p[0], p[1] != 0);
- break;
-
- case 14: {
- // DynamicHotspots_add
- EXTRACT_PARAMS(7);
- int idx = _madsVm->scene()->_dynamicHotspots.add(p[0], p[1], p[2],
- Common::Rect(p[6], p[5], p[6] + p[4], p[5] + p[3]));
- stack.push(ScriptVar(idx));
- break;
- }
-
- case 15:
- // SequenceList_setDepth
- EXTRACT_PARAMS(2);
- _madsVm->scene()->_sequenceList.setDepth(p[0], p[1]);
- break;
-
- case 16: {
- // quotes_load
- // Quotes loading can take an arbitrary number of quote Ids, terminated by a 0
- int firstId = -1;
- int quoteId;
- while ((quoteId = stack.pop()) != 0) {
- if (firstId == -1)
- firstId = quoteId;
- _madsVm->globals()->loadQuote(quoteId);
- }
-
- if (firstId != -1)
- stack.push(ScriptVar(_madsVm->globals()->getQuote(firstId)));
- break;
- }
-
- case 17: {
- // form_resource_name
- EXTRACT_PARAMS(4);
- const char *suffix = NULL;
- if (p[4].isInt()) {
- // If integer provided for suffix, it must be a value of 0 (NULL)
- uint32 vTemp = p[4] | stack.pop();
- assert(!vTemp);
- } else
- suffix = p[4].getStr();
-
- stack.push(ScriptVar(MADSResourceManager::getResourceName((char)p[1], p[0], (ExtensionType)p[3].get(),
- suffix, (int16)p[2])));
- break;
- }
-
- case 18:
- // MadsScene_loadAnimation
- EXTRACT_PARAMS(3);
- _madsVm->scene()->loadAnimation(p[1].getStr(), p[0]);
- break;
-
- case 19: {
- // Action_isAction
- int verbId = stack.pop();
- int objectNameId = (verbId == 0) ? 0 : stack.pop().get();
- int indirectObjectId = (objectNameId == 0) ? 0 : stack.pop().get();
-
- stack.push(ScriptVar(_madsVm->scene()->_action.isAction(verbId, objectNameId, indirectObjectId)));
- break;
- }
-
- case 21:
- // DynamicHotspots_remove
- EXTRACT_PARAMS(1);
- _madsVm->scene()->_dynamicHotspots.remove(p[0]);
- break;
-
- case 22: {
- // object_is_present
- EXTRACT_PARAMS(1);
- const MadsObject *obj = _madsVm->globals()->getObject(p[0]);
- stack.push(ScriptVar((obj->_roomNumber == _madsVm->scene()->_currentScene)));
- break;
- }
-
- case 23:
- // inventory_add
- EXTRACT_PARAMS(1);
- _madsVm->scene()->getInterface()->addObjectToInventory(p[0]);
- break;
-
- case 24: {
- // dialog_picture_show
- EXTRACT_PARAMS(3);
- int messageId = p[0] | (p[1] << 16);
- int objectNum = p[2];
- warning("TODO: Implement dialog with picture. MessageId=%d, objectNum=%d", messageId, objectNum);
- break;
- }
-
- case 25: {
- // object_is_in_inventory
- EXTRACT_PARAMS(1);
- const MadsObject *obj = _madsVm->globals()->getObject(p[0]);
- stack.push(ScriptVar(obj->isInInventory()));
- break;
- }
-
- case 26: {
- // object_set_room
- EXTRACT_PARAMS(2);
- MadsObject *obj = _madsVm->globals()->getObject(p[0]);
- obj->setRoom(p[1]);
- break;
- }
-
- case 27: {
- // object_get_id_from_desc
- EXTRACT_PARAMS(1);
- stack.push(_madsVm->globals()->getObjectIndex(p[0]));
- break;
- }
-
- case 28: {
- // object_get_folder
- EXTRACT_PARAMS(1);
- stack.push(_madsVm->globals()->getObjectFolder(p[0]));
- break;
- }
-
- case 29:
- // inventory_remove
- EXTRACT_PARAMS(1);
- _madsVm->scene()->getInterface()->addObjectToInventory(p[0]);
- break;
-
- case 30:
- // image_inter_list_call
- EXTRACT_PARAMS(1);
- warning("TODO: image_inter_list_call");
- break;
-
- case 31:
- // dialog_flags_show
- warning("todo: dialog_flags_show");
- break;
-
- default:
- error("Unknown subroutine %d called", subIndex);
- break;
- }
-}
-
-#undef EXTRACT_PARAMS
-
-}
diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h
deleted file mode 100644
index 4f0b0d5ba2..0000000000
--- a/engines/m4/mads_logic.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The MADS game logic is all hard-coded into the games, although for Rex at least
- * it seems to use only a fairly basic set of instructions and function calls, so it should be
- * possible
- */
-
-#ifndef M4_MADS_LOGIC_H
-#define M4_MADS_LOGIC_H
-
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-#include "common/stack.h"
-#include "m4/mads_views.h"
-
-namespace M4 {
-
-union ScriptVarValue {
- const char *strValue;
- uint32 intValue;
-};
-
-/**
- * Specifies a script variable that either be a 32-bit unsigned integer or a string pointer
- */
-class ScriptVar {
-private:
- ScriptVarValue _value;
- bool _isInt;
-public:
- ScriptVar(uint32 v = 0) { _value.intValue = v; _isInt = true; }
- ScriptVar(const char *s) { _value.strValue = s; _isInt = false; }
-
- void set(uint32 v) { _value.intValue = v; _isInt = true; }
- void set(const char *s) { _value.strValue = s; _isInt = false; }
- const char *getStr() const { assert(!_isInt); return _value.strValue; }
- uint32 get() const { assert(_isInt); return _value.intValue; }
- bool isInt() const { return _isInt; }
-
- operator int() { return get(); }
-};
-
-class MadsSceneLogic {
-private:
- // Library interface methods
- uint16 loadSpriteSet(uint16 suffixNum, uint16 sepChar);
- uint16 startReversibleSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
- uint16 startCycledSpriteSequence(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
- uint16 startSpriteSequence3(uint16 srcSpriteIdx, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks);
- void activateHotspot(int idx, bool active);
- void getPlayerSpritesPrefix();
- void getPlayerSpritesPrefix2();
-private:
- int _sceneNumber;
- int16 _spriteIndexes[50];
- byte *_scriptsData;
- int _scriptsSize;
- Common::HashMap<Common::String, uint32> _subroutines;
- Common::Array<uint32> _subroutineOffsets;
-
- enum SubFormatIndex {SUBFORMAT_ENTER, SUBFORMAT_STEP, SUBFORMAT_PREACTIONS, SUBFORMAT_ACTIONS};
- static const char *subFormatList[];
- static const char *_opcodeStrings[];
-
- // Support functions
- const char *formAnimName(char sepChar, int16 suffixNum);
- void getSceneSpriteSet();
- void getAnimName();
-
- uint32 getDataValue(int dataId);
- void setDataValue(int dataId, uint16 dataValue);
- void getCallParameters(int numParams, Common::Stack<ScriptVar> &stack, ScriptVar *callParams);
-public:
- MadsSceneLogic() { _scriptsData = NULL; }
- ~MadsSceneLogic() { delete _scriptsData; }
-
- void initializeScripts();
- void selectScene(int sceneNum);
-
- void setupScene();
- void doEnterScene();
- void doPreactions();
- void doAction();
- void doSceneStep();
-
- void execute(const Common::String &scriptName);
- void execute(uint32 scriptOffset);
- uint32 getParam(uint32 &scriptOffset, int opcode);
- void callSubroutine(int subIndex, Common::Stack<ScriptVar> &stack);
-};
-
-class MadsGameLogic {
-public:
- static void initializeGlobals();
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp
deleted file mode 100644
index ae16b00616..0000000000
--- a/engines/m4/mads_menus.cpp
+++ /dev/null
@@ -1,1173 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/textconsole.h"
-
-#include "m4/mads_menus.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-#define REX_MENUSCREEN 990
-#define PHANTOM_MENUSCREEN 920
-#define DRAGON_MENUSCREEN 922
-
-#define DRAGON_MENU_BUTTON_W = 45
-#define DRAGON_MENU_BUTTON_H = 11
-
-RexMainMenuView::RexMainMenuView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
-
- _screenType = VIEWID_MAINMENU;
- _screenFlags.get = SCREVENT_ALL;
-
- _delayTimeout = 0;
- _menuItem = NULL;
- _menuItemIndex = 0;
- _frameIndex = 0;
- _highlightedIndex = -1;
- _skipFlag = false;
-
- // Load the background for the Rex Nebular game
- _bgSurface = new M4Surface();
- _bgSurface->loadBackground(REX_MENUSCREEN, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- _bgSurface->translate(_bgPalData);
-
- int row = (height() - MADS_SURFACE_HEIGHT) / 2;
- _bgSurface->copyTo(this, 0, row);
-
- // Add in the bounding lines for the background
- setColor(2);
- hLine(0, width() - 1, row - 1);
- hLine(0, width() - 1, height() - row + 1);
-
- // Set up the menu item pos list
- _menuItemPosList[0] = Common::Point(12, 68);
- _menuItemPosList[1] = Common::Point(12, 87);
- _menuItemPosList[2] = Common::Point(12, 107);
- _menuItemPosList[3] = Common::Point(184, 75);
- _menuItemPosList[4] = Common::Point(245, 75);
- _menuItemPosList[5] = Common::Point(184, 99);
-}
-
-RexMainMenuView::~RexMainMenuView() {
- delete _menuItem;
-
- _vm->_palette->deleteRange(_bgPalData);
-
- delete _bgPalData;
- delete _bgSurface;
-
- for (uint i = 0; i < _itemPalData.size(); ++i) {
- _vm->_palette->deleteRange(_itemPalData[i]);
- delete _itemPalData[i];
- }
-}
-
-bool RexMainMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- // Handle keypresses - these can be done at any time, even when the menu items are being drawn
- if (eventType == KEVENT_KEY) {
- switch (param) {
- case Common::KEYCODE_ESCAPE:
- case Common::KEYCODE_F6:
- handleAction(EXIT);
- break;
-
- case Common::KEYCODE_F1:
- handleAction(START_GAME);
- break;
-
- case Common::KEYCODE_F2:
- handleAction(RESUME_GAME);
- break;
-
- case Common::KEYCODE_F3:
- handleAction(SHOW_INTRO);
- break;
-
- case Common::KEYCODE_F4:
- handleAction(CREDITS);
- break;
-
- case Common::KEYCODE_F5:
- handleAction(QUOTES);
- break;
-
- case Common::KEYCODE_s:
- // Goodness knows why, but Rex has a key to restart the menuitem animations
-
- // Delete the current menu items
- delete _menuItem;
-
- _vm->_palette->deleteRange(_bgPalData);
- delete _bgPalData;
- for (uint i = 0; i < _itemPalData.size(); ++i) {
- _vm->_palette->deleteRange(_itemPalData[i]);
- delete _itemPalData[i];
- }
- _itemPalData.clear();
-
- // Reload the background surface, and restart the animation
- _bgSurface->loadBackground(REX_MENUSCREEN, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- _bgSurface->translate(_bgPalData);
-
- _menuItemIndex = 0;
- _skipFlag = false;
- _menuItem = NULL;
- _vm->_mouse->cursorOff();
- break;
-
- default:
- // Any other key skips the menu animation
- _skipFlag = true;
- return false;
- }
-
- return true;
- }
-
- int row = (height() - MADS_SURFACE_HEIGHT) / 2;
- int menuIndex;
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_LEFT_DRAG:
- if (_vm->_mouse->getCursorOn()) {
- menuIndex = getHighlightedItem(x, y);
- if (menuIndex != _highlightedIndex) {
- _bgSurface->copyTo(this, 0, row);
-
- _highlightedIndex = menuIndex;
- if (_highlightedIndex != -1) {
- M4Sprite *spr = _menuItem->getFrame(_highlightedIndex);
- const Common::Point &pt = _menuItemPosList[_highlightedIndex];
- spr->copyTo(this, pt.x, row + pt.y, spr->getTransparencyIndex());
- }
- }
- } else {
- // Skip the menu animation
- _skipFlag = true;
- }
- return true;
-
- case MEVENT_LEFT_RELEASE:
- if (_highlightedIndex != -1)
- handleAction((MadsGameAction) _highlightedIndex);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-void RexMainMenuView::updateState() {
- char resName[20];
- Common::SeekableReadStream *data;
- int row = (height() - MADS_SURFACE_HEIGHT) / 2;
- int itemSize;
-
- uint32 currTime = g_system->getMillis();
- if (currTime < _delayTimeout)
- return;
- _delayTimeout = currTime + MADS_MENU_ANIM_DELAY;
-
- // Rex Nebular handling to cycle through the animated display of the menu items
- if (_menuItemIndex == 7)
- return;
-
- // If the user has chosen to skip the menu animation, show the menu immediately
- if (_skipFlag && !_vm->_mouse->getCursorOn()) {
- // Clear any pending animation
- _bgSurface->copyTo(this, 0, row);
- // Quickly loop through all the menuitems to display each's final frame
- while (_menuItemIndex < 7) {
-
- if (_menuItem) {
- // Draw the final frame of the menuitem
- M4Sprite *spr = _menuItem->getFrame(0);
- itemSize = _menuItem->getFrame(0)->height();
- spr->copyTo(this, _menuItemPosList[_menuItemIndex - 1].x,
- _menuItemPosList[_menuItemIndex - 1].y + row + (itemSize / 2) - (spr->height() / 2),
- spr->getTransparencyIndex());
-
- delete _menuItem;
- copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SURFACE_HEIGHT), 0, 0,
- spr->getTransparencyIndex());
- }
-
- // Get the next sprite set
- sprintf(resName, "RM%dA%d.SS", REX_MENUSCREEN, ++_menuItemIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- RGBList *palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
- }
-
- _vm->_mouse->cursorOn();
- return;
- }
-
- if ((_menuItemIndex == 0) || (_frameIndex == 0)) {
- // Get the next menu item
- if (_menuItem) {
- delete _menuItem;
-
- // Copy over the current display surface area to the background, so the final frame
- // of the previous menuitem should be kept on the screen
- copyTo(_bgSurface, Common::Rect(0, row, width(), row + MADS_SURFACE_HEIGHT), 0, 0);
- }
-
- // Get the next menuitem resource
- sprintf(resName, "RM%dA%d.SS", REX_MENUSCREEN, ++_menuItemIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- RGBList *palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- _frameIndex = _menuItem->getCount() - 1;
-
- // If the final resource is now loaded, which contains the highlighted versions of
- // each menuitem, then the startup animation is complete
- if (_menuItemIndex == 7) {
- _vm->_mouse->cursorOn();
- return;
- }
- } else {
- --_frameIndex;
- }
-
- // Move to the next menuitem frame
-
- itemSize = _menuItem->getFrame(0)->height();
-
- _bgSurface->copyTo(this, 0, row);
- M4Sprite *spr = _menuItem->getFrame(_frameIndex);
- spr->copyTo(this, _menuItemPosList[_menuItemIndex - 1].x, _menuItemPosList[_menuItemIndex - 1].y +
- row + (itemSize / 2) - (spr->height() / 2), spr->getTransparencyIndex());
-}
-
-int RexMainMenuView::getHighlightedItem(int x, int y) {
- y -= (height() - MADS_SURFACE_HEIGHT) / 2;
-
- for (int index = 0; index < 6; ++index) {
- const Common::Point &pt = _menuItemPosList[index];
- M4Sprite *spr = _menuItem->getFrame(index);
-
- if ((x >= pt.x) && (y >= pt.y) && (x < (pt.x + spr->width())) && (y < (pt.y + spr->height())))
- return index;
- }
-
- return -1;
-}
-
-void RexMainMenuView::handleAction(MadsGameAction action) {
- MadsEngine *vm = (MadsEngine *)_vm;
- vm->_mouse->cursorOff();
- vm->_viewManager->deleteView(this);
-
- switch (action) {
- case START_GAME:
- case RESUME_GAME:
- // Load a sample starting scene - note that, currently, calling loadScene automatically
- // removes this menu screen from being displayed
- vm->_mouse->cursorOn();
- vm->startScene(101);
- return;
-
- case SHOW_INTRO:
- vm->_viewManager->showAnimView("@rexopen");
- break;
-
- case CREDITS:
- vm->_viewManager->showTextView("credits");
- return;
-
- case QUOTES:
- vm->_viewManager->showTextView("quotes");
- return;
-
- case EXIT:
- {
- // When the Exit action is done from the menu, show one of two possible advertisements
-
- // Activate the scene display with the specified scene
- bool altAdvert = vm->_random->getRandomNumber(1000) >= 500;
- vm->startScene(altAdvert ? 995 : 996);
- vm->_viewManager->addView(vm->_scene);
-
- vm->_viewManager->refreshAll();
- vm->delay(10000);
-
- vm->_events->quitFlag = true;
- return;
- }
- break;
- default:
- break;
- }
-}
-
-//--------------------------------------------------------------------------
-
-MadsMainMenuView::MadsMainMenuView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
-
-}
-
-bool MadsMainMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- return false;
-}
-
-void MadsMainMenuView::updateState() {
- // TODO: Implement me
-}
-
-//--------------------------------------------------------------------------
-
-DragonMainMenuView::DragonMainMenuView(MadsM4Engine *vm):
- View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
-
- _screenType = VIEWID_MAINMENU;
- _screenFlags.get = SCREVENT_ALL;
-
- _delayTimeout = 0;
- _menuItem = NULL;
- _menuItemIndex = 0;
- _frameIndex = 0;
- _highlightedIndex = -1;
- _skipFlag = false;
-
- // Load the background for the Dragonsphere game
- this->loadBackground(942, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- this->translate(_bgPalData);
-
- // Set up the menu item pos list
- _menuItemPosList[0] = Common::Point(46, 187);
- _menuItemPosList[1] = Common::Point(92, 187);
- _menuItemPosList[2] = Common::Point(138, 187);
- _menuItemPosList[3] = Common::Point(184, 187);
- _menuItemPosList[4] = Common::Point(230, 187);
- _menuItemPosList[5] = Common::Point(276, 187);
-}
-
-DragonMainMenuView::~DragonMainMenuView() {
- //if (_menuItem)
- // delete _menuItem;
-
- _vm->_palette->deleteRange(_bgPalData);
-
- delete _bgPalData;
-
- for (uint i = 0; i < _itemPalData.size(); ++i) {
- _vm->_palette->deleteRange(_itemPalData[i]);
- delete _itemPalData[i];
- }
-}
-
-bool DragonMainMenuView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) {
- char resName[20];
- Common::SeekableReadStream *data;
-
- // Handle keypresses - these can be done at any time, even when the menu items are being drawn
- if (eventType == KEVENT_KEY) {
- switch (param) {
- case Common::KEYCODE_ESCAPE:
- case Common::KEYCODE_F6:
- handleAction(EXIT);
- break;
-
- case Common::KEYCODE_F1:
- handleAction(START_GAME);
- break;
-
- case Common::KEYCODE_F2:
- handleAction(RESUME_GAME);
- break;
-
- case Common::KEYCODE_F3:
- handleAction(SHOW_INTRO);
- break;
-
- case Common::KEYCODE_F4:
- handleAction(CREDITS);
- break;
-
- default:
- // Any other key skips the menu animation
- _skipFlag = true;
- return false;
- }
-
- return true;
- }
-
- int menuIndex;
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- case MEVENT_LEFT_DRAG:
- if (_vm->_mouse->getCursorOn()) {
- menuIndex = getHighlightedItem(x, y);
- if (menuIndex != _highlightedIndex) {
-
- _highlightedIndex = menuIndex;
- if (_highlightedIndex != -1) {
- sprintf(resName, "MAIN%d.SS", menuIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- M4Sprite *spr = _menuItem->getFrame(1);
- spr->copyTo(this, spr->xOffset - 25, spr->yOffset - spr->height());
- }
- }
- } else {
- // Skip the menu animation
- _skipFlag = true;
- }
- return true;
-
- case MEVENT_LEFT_RELEASE:
- if (_highlightedIndex != -1)
- handleAction((MadsGameAction) _highlightedIndex);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-void DragonMainMenuView::updateState() {
- char resName[20];
- Common::SeekableReadStream *data;
- RGBList *palData;
- M4Sprite *spr;
-
- if (_menuItemIndex == 6)
- return;
-
- while (_menuItemIndex < 6) {
- sprintf(resName, "MAIN%d.SS", _menuItemIndex);
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- spr = _menuItem->getFrame(0);
- spr->copyTo(this, spr->xOffset - 25, spr->yOffset - spr->height());
-
- if (_menuItemIndex != 5)
- delete _menuItem;
- _menuItemIndex++;
- }
-
- // Sphere
- sprintf(resName, "RM920X0.SS");
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- spr = _menuItem->getFrame(0); // empty sphere
- spr->copyTo(this, spr->xOffset - 75, spr->yOffset - spr->height());
- spr = _menuItem->getFrame(1); // dragon inside sphere
- spr->copyTo(this, spr->xOffset - 75, spr->yOffset - spr->height());
-
- // Dragonsphere letters
- sprintf(resName, "RM920X3.SS");
- data = _vm->res()->get(resName);
- _menuItem = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- palData = _menuItem->getRgbList();
- _vm->_palette->addRange(palData);
- _menuItem->translate(palData, true);
- _itemPalData.push_back(palData);
-
- spr = _menuItem->getFrame(1);
- spr->copyTo(this, spr->xOffset - 140, spr->yOffset - spr->height(), spr->getTransparencyIndex());
-
- _vm->_mouse->cursorOn();
-}
-
-int DragonMainMenuView::getHighlightedItem(int x, int y) {
- y -= (height() - MADS_SURFACE_HEIGHT) / 2;
-
- for (int index = 0; index < 6; ++index) {
- const Common::Point &pt = _menuItemPosList[index];
- M4Sprite *spr = _menuItem->getFrame(0);
-
- if ((x >= pt.x - 25) && (y >= pt.y - spr->height()) && (x < (pt.x - 25 + spr->width())) && (y < (pt.y))) {
- debugCN(kDebugGraphics, "x = %d, y = %d, index = %d\n", x, y, index);
- return index;
- }
- }
-
- return -1;
-}
-
-void DragonMainMenuView::handleAction(MadsGameAction action) {
- MadsM4Engine *vm = _vm;
- vm->_mouse->cursorOff();
- vm->_viewManager->deleteView(this);
-
- switch (action) {
- case START_GAME:
- case RESUME_GAME:
- // Load a sample starting scene - note that, currently, calling loadScene automatically
- // removes this menu screen from being displayed
- vm->_mouse->cursorOn();
- vm->_viewManager->addView(vm->_scene);
- vm->_scene->loadScene(101);
- return;
-
- case SHOW_INTRO:
- vm->_viewManager->showAnimView("@dragon");
- break;
-
- case CREDITS:
- vm->_viewManager->showTextView("credits");
- return;
-
- case EXIT:
- vm->_events->quitFlag = true;
- return;
-
- default:
- break;
- }
-}
-
-
-/*--------------------------------------------------------------------------
- * RexDialogView is the base class for the different full-screen dialogs
- * in at least Rex Nebular
- *--------------------------------------------------------------------------
- */
-
-RexDialogView::RexDialogView(): View(_madsVm, Common::Rect(0, 0, _madsVm->_screen->width(), _madsVm->_screen->height())),
- MadsView(this) {
- _screenType = VIEWID_MENU;
-
- // Initialize class variables
- _priorSceneId = _madsVm->_scene->getCurrentScene();
- _dialogType = DIALOG_NONE;
-
- // Load necessary quotes
- _madsVm->globals()->loadQuoteRange(1, 48);
-
- initializeLines();
- initializeGraphics();
-}
-
-void RexDialogView::initializeLines() {
- // Set up a list of blank entries for use in the various dialogs
- for (int i = 0; i < DIALOG_LINES_SIZE; ++i) {
- DialogTextEntry rec;
- rec.in_use = false;
- _dialogText.push_back(rec);
- }
- _totalTextEntries = 0;
-
- // Set up a default sprite slot entry for a full screen refresh
- _spriteSlots.startIndex = 1;
- _spriteSlots[0].spriteType = FULL_SCREEN_REFRESH;
- _spriteSlots[0].seqIndex = -1;
-}
-
-void RexDialogView::initializeGraphics() {
- // Set needed palette entries
- _madsVm->_palette->blockRange(0, 16);
- _madsVm->_palette->setEntry(10, 0, 255, 0);
- _madsVm->_palette->setEntry(11, 0, 180, 0);
- _madsVm->_palette->setEntry(12, 255, 255, 0);
- _madsVm->_palette->setEntry(13, 180, 180, 0);
- _madsVm->_palette->setEntry(14, 255, 255, 180);
- _madsVm->_palette->setEntry(15, 180, 180, 180);
-
- // Load an appropriate background and menu sprites
- loadBackground();
- loadMenuSprites();
-
- // Set the current cursor
- _madsVm->_mouse->setCursorNum(CURSOR_ARROW);
-}
-
-
-RexDialogView::~RexDialogView() {
- _madsVm->_palette->deleteRange(_bgPalData);
- delete _bgPalData;
- delete _backgroundSurface;
-}
-
-void RexDialogView::loadBackground() {
- int bgIndex = _madsVm->globals()->sceneNumber / 100;
- int screenId = 0;
-
- switch (bgIndex) {
- case 1:
- case 2:
- screenId = 921;
- break;
- case 3:
- case 4:
- screenId = 922;
- break;
- case 5:
- case 6:
- case 7:
- screenId = 923;
- break;
- case 8:
- screenId = 924;
- break;
- case 9:
- screenId = 920;
- break;
- default:
- error("Unknown scene number");
- }
-
- _backgroundSurface = new M4Surface(width(), MADS_SURFACE_HEIGHT);
- _backgroundSurface->loadBackground(screenId, &_bgPalData);
- _vm->_palette->addRange(_bgPalData);
- _backgroundSurface->translate(_bgPalData);
-}
-
-void RexDialogView::loadMenuSprites() {
- const char *SPRITES_NAME = "*MENU.SS";
-
- _spriteSlots.addSprites(SPRITES_NAME);
-}
-
-
-void RexDialogView::updateState() {
-}
-
-void RexDialogView::onRefresh(RectList *rects, M4Surface *destSurface) {
- // Draw the framed base area
- fillRect(this->bounds(), _madsVm->_palette->BLACK);
- setColor(2);
- hLine(0, width(), MADS_Y_OFFSET - 2);
- hLine(0, width(), MADS_Y_OFFSET + MADS_SURFACE_HEIGHT + 2);
-
- // Add in the loaded background vertically centered
- _backgroundSurface->copyTo(this, 0, (height() - MADS_SURFACE_HEIGHT) / 2);
-
- // Check whether any of the dialog text entries need to be refreshed
- refreshText();
-
- // Handle the drawing of the various Mads elements
- refresh();
-
- View::onRefresh(rects, destSurface);
-}
-
-/**
- * Handles item selection within dialogs
- */
-bool RexDialogView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- static bool word_7F28C = false;
- int word_7FED2 = 0;
- //int word_8502A = 0;
-
- // If it's a keypress, handle it immediately
- if (eventType == KEVENT_KEY) {
- switch (param1) {
- case Common::KEYCODE_q | (Common::KBD_CTRL << 24):
- case Common::KEYCODE_q | (Common::KBD_ALT << 24):
- _madsVm->quitGame();
- return true;
- case Common::KEYCODE_RETURN:
- _enterFlag = true;
- _selectedLine = 0;
- break;
- case Common::KEYCODE_ESCAPE:
- _selectedLine = 0;
- break;
- default:
- return false;
- }
- }
-
- // Mark all the dialog text entries as not being seelcted
- for (uint i = 0; i < _dialogText.size(); ++i)
- _dialogText[i].state = STATE_DESELECTED;
-
- // Check if the mouse is over a registered screen object
- int idx = _screenObjects.scan(x, y, LAYER_GUI);
-
- if (word_7F28C) {
- if (y < _screenObjects[2].bounds.top) {
- if (eventType != MEVENT_LEFT_RELEASE)
- _dialogText[1].state = STATE_SELECTED;
- idx = 19;
- }
-
- if (y > _screenObjects[8].bounds.bottom) {
- if (eventType != MEVENT_LEFT_RELEASE)
- _dialogText[7].state = STATE_SELECTED;
- idx = 20;
- }
- }
-
- int objIndex = -1;
- if ((idx > 0) && ((eventType == MEVENT_LEFT_HOLD) || (eventType == MEVENT_LEFT_DRAG) ||
- (eventType == MEVENT_LEFT_RELEASE))) {
- objIndex = _screenObjects[idx].index;
-
- if ((_dialogType == DIALOG_SAVE) || (_dialogType == DIALOG_RESTORE)) {
- if ((objIndex > 7) && (objIndex <= 14))
- _dialogText[objIndex].state = STATE_SELECTED;
- }
-
- if (word_7FED2)
- word_7F28C = (objIndex > 0) && (objIndex <= 7);
-
- if (_screenObjects[idx].category == 1)
- _dialogText[objIndex].state = STATE_SELECTED;
- } else {
- idx = -1;
- }
-
- if (idx == 0)
- idx = -1;
-
- if (_dialogType == DIALOG_ERROR) {
- if (idx == 1)
- idx = -1;
- }
-
- if (eventType == MEVENT_LEFT_RELEASE) {
- if (!word_7F28C || (objIndex <= 18))
- _selectedLine = objIndex;
-
- //word_8502A = -1;
- }
-
- return true;
-}
-
-void RexDialogView::setFrame(int frameNumber, int depth) {
- int slotIndex = _spriteSlots.getIndex();
- _spriteSlots[slotIndex].spriteType = FOREGROUND_SPRITE;
- _spriteSlots[slotIndex].seqIndex = 1;
- _spriteSlots[slotIndex].spriteListIndex = 0; //_menuSpritesIndex;
- _spriteSlots[slotIndex].frameNumber = frameNumber;
-
- M4Sprite *spr = _spriteSlots.getSprite(0).getFrame(frameNumber - 1);
- _spriteSlots[slotIndex].xp = spr->x;
- _spriteSlots[slotIndex].yp = spr->y;
- _spriteSlots[slotIndex].depth = depth;
- _spriteSlots[slotIndex].scale = 100;
-}
-
-void RexDialogView::initVars() {
- _v8502C = -1;
- _selectedLine = -1;
- _lineIndex = 0;
- _enterFlag = false;
- _textLines.clear();
-}
-
-void RexDialogView::addLine(const char *msg_p, Font *font, MadsTextAlignment alignment, int left, int top) {
- DialogTextEntry *rec = NULL;
-
- if (_lineIndex < _totalTextEntries) {
- if (strcmp(msg_p, _dialogText[_lineIndex].text) == 0) {
- rec = &_dialogText[_lineIndex];
- if (rec->textDisplay_index != 0) {
- MadsTextDisplayEntry &tdEntry = _textDisplay[rec->textDisplay_index];
- if (tdEntry.active) {
- if (_textLines.size() < 20) {
- // Add entry to line list
- _textLines.push_back(tdEntry.msg);
- tdEntry.msg = _textLines[_textLines.size() - 1].c_str();
- }
- }
- }
- }
- } else {
- if (_lineIndex < DIALOG_LINES_SIZE) {
- rec = &_dialogText[_lineIndex];
- _totalTextEntries = _lineIndex + 1;
- }
- }
-
- // Handling for if a line needs to be added
- if (rec) {
- strcpy(rec->text, msg_p);
- rec->font = font;
- rec->state = STATE_DESELECTED;
- rec->pos.y = top;
- rec->widthAdjust = -1;
- rec->in_use = true;
- rec->textDisplay_index = -1;
-
- switch (alignment) {
- case ALIGN_CENTER:
- // Center text
- rec->pos.x = (width() - font->getWidth(rec->text)) / 2 + left;
- break;
-
- case ALIGN_CHAR_CENTER: {
- // Text is center aligned on the '@' character within the string
- char *p = strchr(rec->text, '@');
-
- if (p) {
- // '@' string handling
- // Get length of string up to the '@' character
- *p = '\0';
- int strWidth = font->getWidth(rec->text, rec->widthAdjust);
- // Remove the character from the string. strcpy isn't used here because it's unsafe for
- // copying within the same string
- while ((*p = *(p + 1)) != '\0') ++p;
-
- rec->pos.x = (width() / 2) - strWidth;
- } else {
- rec->pos.x = left;
- }
- break;
- }
-
- case RIGHT_ALIGN:
- // Right align (moving left from given passed left)
- rec->pos.x = left - font->getWidth(rec->text);
- break;
-
- default:
- break;
- }
- }
-
- ++_lineIndex;
-}
-
-/**
- * Adds a line consisting of either a single quote, or the combination of two quote Ids
- */
-void RexDialogView::addQuote(Font *font, MadsTextAlignment alignment, int left, int top, int id1, int id2) {
- char buffer[80];
-
- // Copy the first quote string into the buffer
- const char *quoteStr = _madsVm->globals()->getQuote(id1);
- strcpy(buffer, quoteStr);
-
- // Handle the optional second quote Id
- if (id2 != 0) {
- quoteStr = _madsVm->globals()->getQuote(id2);
- strcat(buffer, " ");
- strcat(buffer, quoteStr);
- }
-
- // Add in the generated line
- addLine(buffer, font, alignment, left, top);
-}
-
-/**
- * Sets any previously created dialog text entries as clickable items
- */
-void RexDialogView::setClickableLines() {
- _screenObjects.clear();
-
- for (int i = 0; i < DIALOG_LINES_SIZE; ++i) {
- if (_dialogText[i].in_use) {
- // Add an entry for the line
- _screenObjects.add(Common::Rect(_dialogText[i].pos.x, _dialogText[i].pos.y,
- _dialogText[i].pos.x + _dialogText[i].font->getWidth(_dialogText[i].text, _dialogText[i].widthAdjust),
- _dialogText[i].pos.y + _dialogText[i].font->getHeight()), 19, i, 1);
- }
- }
-
- if ((_madsVm->globals()->dialogType == DIALOG_SAVE) || (_madsVm->globals()->dialogType == DIALOG_RESTORE)) {
- // Extra entries for the scroller areas of the Save and Restor dialogs
- _screenObjects.add(Common::Rect(293, 26, 312, 75), LAYER_GUI, 50, 2);
- _screenObjects.add(Common::Rect(293, 78, 312, 127), LAYER_GUI, 51, 2);
- }
-}
-
-/**
- * Handles creating text display objects for each dialog line initially, and when the selected state
- * of any entry changes
- */
-void RexDialogView::refreshText() {
- for (uint i = 0; i < _dialogText.size(); ++i) {
- if (!_dialogText[i].in_use)
- continue;
-
- // Get the item's colors
- uint color;
- if (_dialogText[i].state == STATE_DESELECTED)
- color = 0xB0A;
- else if (_dialogText[i].state == STATE_SELECTED)
- color = 0xD0C;
- else
- color = 0xF0E;
-
- // If there's an associated text display entry, check to see if it's color needs to change
- if (_dialogText[i].textDisplay_index >= 0) {
- MadsTextDisplayEntry &tdEntry = _textDisplay[_dialogText[i].textDisplay_index];
-
- if ((tdEntry.color1 == (color & 0xff)) && (tdEntry.color2 == (color >> 8)))
- // It's still the same, so no further action needed
- continue;
-
- // Flag the currently assigned text display to be expired, so it can be re-created
- _textDisplay.expire(_dialogText[i].textDisplay_index);
- _dialogText[i].textDisplay_index = -1;
- }
-
- // Create a new text display entry for the dialog text line
- _dialogText[i].textDisplay_index = _textDisplay.add(_dialogText[i].pos.x, _dialogText[i].pos.y,
- color, _dialogText[i].widthAdjust, _dialogText[i].text, _dialogText[i].font);
- }
-}
-
-/*--------------------------------------------------------------------------
- * RexGameMenuDialog is the main game dialog for the game
- *--------------------------------------------------------------------------
- */
-
-RexGameMenuDialog::RexGameMenuDialog(): RexDialogView() {
- _dialogType = DIALOG_GAME_MENU;
- setFrame(1, 2);
- initVars();
-
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- addLines();
- setClickableLines();
-}
-
-void RexGameMenuDialog::addLines() {
- // Add the title
- int top = MADS_Y_OFFSET - 2 - ((((_vm->_font->current()->getHeight() + 2) * 6) >> 1) - 78);
-
- addQuote(_vm->_font->current(), ALIGN_CENTER, 0, top, 10);
-
- // Loop for adding the option lines of the dialog
- top += 6;
- for (int idx = 0; idx < 5; ++idx) {
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CENTER, 0, top, 11 + idx);
- }
-}
-
-bool RexGameMenuDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- // Call the parent event handler to handle line selection
- bool handled = RexDialogView::onEvent(eventType, param1, x, y, captureEvents);
-
- if (_selectedLine > 0) {
- switch (_selectedLine) {
- case 1:
- // Save Game
- _madsVm->globals()->dialogType = DIALOG_SAVE;
- break;
- case 2:
- // Restore Game
- _madsVm->globals()->dialogType = DIALOG_RESTORE;
- break;
- case 3:
- // Game Play Options
- _madsVm->globals()->dialogType = DIALOG_OPTIONS;
- break;
- case 4:
- // Resume Current Game
- _madsVm->globals()->dialogType = DIALOG_NONE;
- break;
- case 5:
- // Exit From Game
- _madsVm->quitGame();
- break;
- default:
- // TODO: Extra logic for such as resuming scene if necessary
- _madsVm->globals()->dialogType = DIALOG_NONE;
- break;
- }
-
- // Close this dialog
- _madsVm->_viewManager->deleteView(this);
- }
-
- return handled;
-}
-
-/*--------------------------------------------------------------------------
- * RexOptionsDialog is the game options dialog for Rex Nebular
- *--------------------------------------------------------------------------
- */
-
-RexOptionsDialog::RexOptionsDialog(): RexDialogView() {
- _dialogType = DIALOG_OPTIONS;
- _tempConfig = _madsVm->globals()->_config;
-
- setFrame(2, 2);
- initVars();
-
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- addLines();
- setClickableLines();
-}
-
-void RexOptionsDialog::reload() {
- for (int i = 0; i < DIALOG_LINES_SIZE; ++i)
- _dialogText[i].in_use = false;
- _totalTextEntries = 0;
- _textDisplay.clear();
- _screenObjects.clear();
-
- initVars();
-
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- addLines();
- setClickableLines();
-}
-
-void RexOptionsDialog::addLines() {
- // Add the title
- int top = MADS_Y_OFFSET - 2 - ((((_vm->_font->current()->getHeight() + 1) * 9 + 12) >> 1) - 78);
-
- addQuote(_vm->_font->current(), ALIGN_CENTER, 0, top, 16);
-
- // Music state line
- top += _vm->_font->current()->getHeight() + 1 + 6;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 17, _tempConfig.musicFlag ? 24 : 25);
-
- // Sound state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 18, _tempConfig.soundFlag ? 26 : 27);
-
- // Interface easy state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 19, _tempConfig.easyMouse ? 29 : 28);
-
- // Inventory sppinng state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 20, _tempConfig.invObjectsStill ? 31 : 30);
-
- // Text window state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 21, _tempConfig.textWindowStill ? 33 : 32);
-
- // Screen fade state line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 22, _tempConfig.screenFades + 34);
-
- // Storyline mode line
- top += _vm->_font->current()->getHeight() + 1;
- addQuote(_vm->_font->current(), ALIGN_CHAR_CENTER, 0, top, 23, (_tempConfig.storyMode == 1) ? 37 : 38);
-
- // Add Done and Cancel button texts
- top += _vm->_font->current()->getHeight() + 1 + 6;
- addQuote(_vm->_font->current(), ALIGN_CENTER, -54, top, 1, 0);
- addQuote(_vm->_font->current(), ALIGN_CENTER, 54, top, 2, 0);
-}
-
-bool RexOptionsDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- // Call the parent event handler to handle line selection
- bool handled = RexDialogView::onEvent(eventType, param1, x, y, captureEvents);
-
- if (_selectedLine > 0) {
- switch (_selectedLine) {
- case 0:
- // Enter or Escape
- _selectedLine = _enterFlag ? 8 : 9;
- return true;
- case 1:
- // Music line
- _tempConfig.musicFlag = !_tempConfig.musicFlag;
- break;
- case 2:
- // Sound line
- _tempConfig.soundFlag = !_tempConfig.soundFlag;
- break;
- case 3:
- // Interface line
- _tempConfig.easyMouse = !_tempConfig.easyMouse;
- break;
- case 4:
- // Inventory line
- _tempConfig.invObjectsStill = !_tempConfig.invObjectsStill;
- break;
- case 5:
- // Text window line
- _tempConfig.textWindowStill = !_tempConfig.textWindowStill;
- break;
- case 6:
- // Screen fades line
- if (++_tempConfig.screenFades > 2)
- _tempConfig.screenFades = 0;
- break;
- case 7:
- // Story mode line
- if (_tempConfig.storyMode == 2)
- _tempConfig.storyMode = 1;
- else if (_tempConfig.storyMode == 1)
- _tempConfig.storyMode = 2;
- break;
- case 8:
- case 9:
- // Done and Cancel buttons
- // TODO: Proper re-loading of settings if Cancel button clicked
- _madsVm->globals()->_config = _tempConfig;
-
- // Closing the dialog, so return to the game menu
- _madsVm->globals()->dialogType = DIALOG_GAME_MENU;
- _madsVm->_viewManager->deleteView(this);
- return true;
- }
-
- // Update the option selections
- reload();
- }
-
- return handled;
-}
-
-}
diff --git a/engines/m4/mads_menus.h b/engines/m4/mads_menus.h
deleted file mode 100644
index 4d3ea5da39..0000000000
--- a/engines/m4/mads_menus.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_MADS_MENUS_H
-#define M4_MADS_MENUS_H
-
-#include "common/str-array.h"
-#include "m4/viewmgr.h"
-#include "m4/mads_views.h"
-#include "m4/font.h"
-
-namespace M4 {
-
-#define MADS_MENU_ANIM_DELAY 70
-
-enum MadsGameAction {START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT};
-
-enum MadsLayers {LAYER_GUI = 19};
-
-class RexMainMenuView : public View {
-private:
- Common::Point _menuItemPosList[6];
-private:
- M4Surface *_bgSurface;
- RGBList *_bgPalData;
- int _menuItemIndex;
- int _frameIndex;
- bool _skipFlag;
- SpriteAsset *_menuItem;
- Common::Array<RGBList *> _itemPalData;
- uint32 _delayTimeout;
- int _highlightedIndex;
-
- int getHighlightedItem(int x, int y);
- void handleAction(MadsGameAction action);
-public:
- RexMainMenuView(MadsM4Engine *vm);
- ~RexMainMenuView();
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-class DragonMainMenuView : public View {
-private:
- Common::Point _menuItemPosList[6];
-private:
- //M4Surface *_bgSurface;
- RGBList *_bgPalData;
- int _menuItemIndex;
- int _frameIndex;
- bool _skipFlag;
- SpriteAsset *_menuItem;
- Common::Array<RGBList *> _itemPalData;
- uint32 _delayTimeout;
- int _highlightedIndex;
-
- int getHighlightedItem(int x, int y);
- void handleAction(MadsGameAction action);
-public:
- DragonMainMenuView(MadsM4Engine *vm);
- ~DragonMainMenuView();
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-class MadsMainMenuView : public View {
-public:
- MadsMainMenuView(MadsM4Engine *vm);
-
- bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
- void updateState();
-};
-
-enum DialogTextState {STATE_DESELECTED = 0, STATE_SELECTED = 1, STATE_UNKNOWN = 2};
-
-class DialogTextEntry {
-public:
- bool in_use;
- DialogTextState state;
- Common::Point pos;
- char text[80];
- Font *font;
- int widthAdjust;
-
- int textDisplay_index;
-
- DialogTextEntry() { in_use = false; }
-};
-
-#define DIALOG_LINES_SIZE 20
-
-enum MadsTextAlignment { ALIGN_CENTER = -1, ALIGN_CHAR_CENTER = -2, RIGHT_ALIGN = -3 };
-
-
-class RexDialogView : public View, public MadsView {
-private:
- int _priorSceneId;
-
- void initializeLines();
- void initializeGraphics();
- void loadBackground();
- void loadMenuSprites();
-protected:
- MadsDialogType _dialogType;
- M4Surface *_backgroundSurface;
- RGBList *_bgPalData;
- SpriteAsset *_menuSprites;
-
- Common::Array<DialogTextEntry> _dialogText;
- Common::StringArray _textLines;
- int _totalTextEntries;
- int _dialogSelectedLine;
- Common::StringArray _saveList;
-
- int _v8502C;
- int _selectedLine;
- int _lineIndex;
- bool _enterFlag;
-
- void setFrame(int frameNumber, int depth);
- void initVars();
- void addLine(const char *msg_p, Font *font, MadsTextAlignment alignment, int left, int top);
- void addQuote(Font *font, MadsTextAlignment alignment, int left, int top, int id1, int id2 = 0);
- void setClickableLines();
- void refreshText();
-public:
- RexDialogView();
- ~RexDialogView();
-
- virtual void updateState();
- virtual void onRefresh(RectList *rects, M4Surface *destSurface);
- virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-class RexGameMenuDialog : public RexDialogView {
-private:
- void addLines();
-public:
- RexGameMenuDialog();
-
- virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-class RexOptionsDialog : public RexDialogView {
-private:
- MadsConfigData _tempConfig;
-
- void reload();
- void addLines();
-public:
- RexOptionsDialog();
-
- virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-}
-
-#endif
diff --git a/engines/m4/mads_player.cpp b/engines/m4/mads_player.cpp
deleted file mode 100644
index 73480088ee..0000000000
--- a/engines/m4/mads_player.cpp
+++ /dev/null
@@ -1,789 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/m4.h"
-#include "m4/mads_player.h"
-#include "m4/mads_scene.h"
-
-namespace M4 {
-
-const int MadsPlayer::_directionListIndexes[32] = {
- 0, 7, 4, 3, 6, 0, 2, 5, 0, 1, 9, 4, 1, 2, 7, 9, 3, 8, 9, 6, 7, 2, 3, 6, 1, 7, 9, 4, 7, 8, 0, 0
-};
-
-MadsPlayer::MadsPlayer() {
- _playerPos = Common::Point(160, 78);
- _ticksAmount = 3;
- _forceRefresh = true;
- _stepEnabled = true;
- _visible = true;
- _yScale = 0;
- _moving = false;
-
- _spriteListStart = 0;
- //TODO:unknown vars
- _special = 0;
- _next = 0;
- _unk4 = false;
-
- _spritesChanged = true;
-
- _direction = 0;
- _newDirection = 0;
- _priorTimer = 0;
- _priorVisible = false;
- _visible3 = false;
- _spriteListIdx = 0;
- _currentScale = 0;
- strcpy(_spritesPrefix, "");
- for (int idx = 0; idx < 8; ++idx)
- _spriteSetsPresent[idx] = false;
- _frameNum = 0;
- _frameOffset = 0;
- _unk1 = 0;
- _frameCount = 0;
- _frameListIndex = 0;
- _actionIndex = 0;
- _routeCount = 0;
-
- resetActionList();
-}
-
-/**
- * Loads the sprite set for the player
- */
-bool MadsPlayer::loadSprites(const char *prefix) {
- const char suffixList[8] = { '8', '9', '6', '3', '2', '7', '4', '1' };
- char setName[80];
- bool result = true;
-
- if (prefix)
- strcpy(_spritesPrefix, prefix);
-
- _spriteSetCount = 0;
- int prefixLen = strlen(_spritesPrefix);
-
- if (prefixLen == 0) {
- // No player sprites at at all
- for (int idx = 0; idx < 8; ++idx)
- _spriteSetsPresent[idx] = false;
- } else {
- strcpy(setName, "*");
- strcat(setName, _spritesPrefix);
- strcat(setName, "_0.SS");
-
- char *digitP = strchr(setName, '_') + 1;
-
- for (int idx = 0; idx < 8; ++idx) {
- *digitP = suffixList[idx];
- _spriteSetsPresent[idx] = true;
-
- int setIndex = _madsVm->scene()->_spriteSlots.addSprites(setName, true, SPRITE_SET_CHAR_INFO);
- if (setIndex < 0) {
- if (idx < 5)
- break;
- _spriteSetsPresent[idx] = false;
- } else {
- ++_spriteSetCount;
- }
-
- if (idx == 0)
- _spriteListStart = setIndex;
- }
-
- result = 0;
- // TODO: Unknown flag
- _spritesChanged = false;
- }
-
- return result;
-}
-
-/**
- * Called each frame to update the display of the player
- */
-void MadsPlayer::update() {
- if (_forceRefresh || (_visible != _priorVisible)) {
- // If there's an existing player sprite visible, flag it for expiry
- int slotIndex = getSpriteSlot();
- if (slotIndex >= 0)
- _madsVm->scene()->_spriteSlots[slotIndex].spriteType = EXPIRED_SPRITE;
-
- // Figure out the depth for the sprite
- int newDepth = 1;
- int yp = MIN(_playerPos.y, (int16)155);
-
- for (int idx = 1; idx < 15; ++idx) {
- if (_madsVm->scene()->getSceneResources()._depthBands[newDepth] >= yp)
- newDepth = idx + 1;
- }
- _currentDepth = newDepth;
-
- // Get the scale
- int newScale = getScale(_playerPos.y);
- _currentScale = MIN(newScale, 100);
-
- if (_visible) {
- // Player sprite needs to be rendered
- MadsSpriteSlot slot;
- slot.spriteType = FOREGROUND_SPRITE;
- slot.seqIndex = PLAYER_SEQ_INDEX;
- slot.spriteListIndex = _spriteListStart + _spriteListIdx;
- slot.frameNumber = _frameOffset + _frameNum;
- slot.xp = _playerPos.x;
- slot.yp = _playerPos.y + (_yScale * newScale) / 100;
- slot.depth = newDepth;
- slot.scale = newScale;
-
- if (slotIndex >= 0) {
- // Check if the existing player slot has the same details, and can be re-used
- MadsSpriteSlot &s2 = _madsVm->scene()->_spriteSlots[slotIndex];
- bool equal = (s2.seqIndex == slot.seqIndex) && (s2.spriteListIndex == slot.spriteListIndex)
- && (s2.frameNumber == slot.frameNumber) && (s2.xp == slot.xp) && (s2.yp == slot.yp)
- && (s2.depth == slot.depth) && (s2.scale == slot.scale);
-
- if (equal)
- // Undo the prior expiry of the player sprite
- s2.spriteType = SPRITE_ZERO;
- else
- slotIndex = -1;
- }
-
- if (slotIndex < 0) {
- // New slot needed, so allocate one and copy the slot data
- slotIndex = _madsVm->scene()->_spriteSlots.getIndex();
- _madsVm->scene()->_spriteSlots[slotIndex] = slot;
- }
-
- // TODO: Meaning of _v844c0 block
-
- }
- }
-
- _visible3 = _priorVisible = _visible;
- _forceRefresh = false;
-}
-
-/**
- * Updates the animation frame for the player
- */
-void MadsPlayer::updateFrame() {
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
-
- if (!spriteSet._charInfo->_numEntries) {
- _frameNum = 1;
- } else {
- _frameListIndex = _actionList[_actionIndex];
-
- if (!_visible) {
- _unk2 = 0;
- } else {
- _unk2 = _actionList2[_actionIndex];
-
- if (_actionIndex > 0)
- --_actionIndex;
- }
-
- // Set the player frame number
- int frameIndex = ABS(_frameListIndex);
- _frameNum = (_frameListIndex <= 0) ? spriteSet._charInfo->_frameList[frameIndex] :
- spriteSet._charInfo->_frameList2[frameIndex];
-
- // Set next waiting period in ticks
- if (frameIndex == 0)
- setTicksAmount();
- else
- _madsVm->_player._ticksAmount = spriteSet._charInfo->_ticksList[frameIndex];
- }
-}
-
-void MadsPlayer::setupFrame() {
- resetActionList();
- _frameOffset = 0;
- _spriteListIdx = _directionListIndexes[_direction];
- if (!_spriteSetsPresent[_spriteListIdx]) {
- // Direction isn't present, so use alternate direction, with entries flipped
- _spriteListIdx -= 4;
- _frameOffset = 0x8000;
- }
-
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
- _unk1 = MAX(spriteSet._charInfo->_unk1, 100);
- setTicksAmount();
-
- _frameCount = spriteSet._charInfo->_totalFrames;
- if (_frameCount == 0)
- _frameCount = spriteSet.getCount();
-
- _yScale = spriteSet._charInfo->_yScale;
-
- if ((_frameNum <= 0) || (_frameNum > _frameCount))
- _frameNum = 1;
- _forceRefresh = true;
-}
-
-void MadsPlayer::step() {
- if (_visible && _stepEnabled && !_moving && (_direction == _newDirection) && (_madsVm->_currentTimer >= GET_GLOBAL32(2))) {
- if (_actionIndex == 0) {
- int randVal = _vm->_random->getRandomNumber(29999);
-
- if (GET_GLOBAL(0) == SEX_MALE) {
- switch (_direction) {
- case 1:
- case 3:
- case 7:
- case 9:
- if (randVal < 200) {
- queueAction(-1, 0);
- queueAction(1, 0);
- }
- break;
-
- case 2:
- if (randVal < 500) {
- for (int i = 0; i < 10; ++i)
- queueAction((randVal < 250) ? 1 : 2, 0);
- } else if (randVal < 750) {
- for (int i = 0; i < 5; ++i)
- queueAction(1, 0);
- queueAction(0, 0);
- for (int i = 0; i < 5; ++i)
- queueAction(2, 0);
- }
- break;
-
- case 4:
- case 6:
- if (randVal < 500) {
- for (int i = 0; i < 10; ++i)
- queueAction(1, 0);
- }
- break;
-
- case 5:
- case 8:
- if (randVal < 200) {
- queueAction(-1, 0);
- queueAction(1, 0);
- }
- break;
- }
- }
- }
-
- SET_GLOBAL32(2, GET_GLOBAL32(2) + 6);
- }
-
- if (GET_GLOBAL(138) == 1) {
- uint32 diff = _madsVm->_currentTimer - GET_GLOBAL32(142);
- if (diff > 60) {
- SET_GLOBAL32(144, GET_GLOBAL32(144) + 1);
- } else {
- SET_GLOBAL32(144, GET_GLOBAL32(144) + diff);
- }
-
- SET_GLOBAL32(142, _madsVm->_currentTimer);
- }
-}
-
-void MadsPlayer::nextFrame() {
- if (_madsVm->_currentTimer >= (_priorTimer + _ticksAmount)) {
- _priorTimer = _madsVm->_currentTimer;
-
- if (_moving)
- move();
- else
- idle();
-
- // Post update logic
- if (_moving) {
- ++_frameNum;
- if (_frameNum > _frameCount)
- _frameNum = 1;
- _forceRefresh = true;
- } else if (!_forceRefresh) {
- idle();
- }
-
- // Final update
- update();
- }
-}
-
-void MadsPlayer::setDest(int destX, int destY, int facing) {
- resetActionList();
- setTicksAmount();
- _moving = true;
- _destFacing = facing;
-
- _madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 2,
- _playerPos, _madsVm->scene()->_depthSurface);
- _madsVm->scene()->getSceneResources().setRouteNode(_madsVm->scene()->getSceneResources()._nodes.size() - 1,
- Common::Point(destX, destY), _madsVm->scene()->_depthSurface);
-
- bool v = _madsVm->scene()->getDepthHighBit(Common::Point(destX, destY));
- setupRoute(v);
- _next = 0;
-
- if (_routeCount > 0) {
- Common::Point srcPos = _playerPos;
- for (int routeCtr = _routeCount - 1; (routeCtr >= 0) && (_next == 0); --routeCtr) {
- int idx = _routeIndexes[routeCtr];
- const Common::Point &pt = _madsVm->scene()->getSceneResources()._nodes[idx].pt;
-
- _next = scanPath(_madsVm->scene()->_depthSurface, srcPos, pt);
- srcPos = pt;
- }
- }
-}
-
-
-int MadsPlayer::getScale(int yp) {
- MadsSceneResources &r = _madsVm->scene()->getSceneResources();
-
- int scale = (r.bandsRange() == 0) ? r._maxScale : (yp - r._yBandsStart) * r.scaleRange() / r.bandsRange()
- + r._minScale;
-
- return MIN(scale, 100);
-}
-
-/**
- * Scans through the scene's sprite slot list to find any sprite displaying the player
- */
-int MadsPlayer::getSpriteSlot() {
- MadsSpriteSlots &slots = _madsVm->scene()->_spriteSlots;
- for (int i = 0; i < slots.startIndex; ++i) {
- if ((slots[i].seqIndex == PLAYER_SEQ_INDEX) && (slots[i].spriteType >= SPRITE_ZERO))
- return i;
- }
- return -1;
-}
-
-void MadsPlayer::setTicksAmount() {
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
- _madsVm->_player._ticksAmount = spriteSet._charInfo->_ticksAmount;
- if (_madsVm->_player._ticksAmount == 0)
- _madsVm->_player._ticksAmount = 6;
-}
-
-void MadsPlayer::resetActionList() {
- _actionList[0] = 0;
- _actionList2[0] = 0;
- _actionIndex = 0;
- _unk2 = 0;
- _unk3 = 0;
-}
-
-int MadsPlayer::queueAction(int action1, int action2) {
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
-
- if ((action1 < spriteSet._charInfo->_numEntries) && (_actionIndex < 11)) {
- ++_actionIndex;
- _actionList[_actionIndex] = action1;
- _actionList2[_actionIndex] = action2;
- return false;
- }
-
- return true;
-}
-
-void MadsPlayer::idle() {
- if (_direction != _newDirection) {
- // The direction has changed, so reset for new direction
- dirChanged();
- return;
- }
-
- SpriteAsset &spriteSet = _madsVm->scene()->_spriteSlots.getSprite(_spriteListStart + _spriteListIdx);
- assert(spriteSet._charInfo);
- if (spriteSet._charInfo->_numEntries == 0)
- // No entries, so exit immediately
- return;
-
- int frameIndex = ABS(_frameListIndex);
- int direction = (_frameListIndex < 0) ? -1 : 1;
-
- if (frameIndex >= spriteSet._charInfo->_numEntries)
- // Reset back to the start of the list
- _frameListIndex = 0;
- else {
- _frameNum += direction;
- _forceRefresh = true;
-
- if (spriteSet._charInfo->_frameList2[frameIndex] < _frameNum) {
- _unk3 = _unk2;
- updateFrame();
- }
- if (spriteSet._charInfo->_frameList[frameIndex] < _frameNum) {
- _unk3 = _unk2;
- updateFrame();
- }
- }
-}
-
-void MadsPlayer::move() {
- bool routeFlag = false;
-
- if (_moving) {
- int idx = _routeCount;
- while (!_v844C0 && (_destPos.x == _playerPos.x) && (_destPos.y == _playerPos.y)) {
- if (idx != 0) {
- --idx;
- SceneNode &node = _madsVm->scene()->getSceneResources()._nodes[_routeIndexes[idx]];
- _destPos = node.pt;
- routeFlag = true;
- } else if (_v844BE == idx) {
- // End of walking path
- _routeCount = 0;
- _moving = false;
- turnToDestFacing();
- routeFlag = true;
- idx = _routeCount;
- } else {
- _v844C0 = _v844BE;
- _v844BC = true;
- _v844BE = 0;
- _stepEnabled = true;
- routeFlag = false;
- }
-
- if (!_moving)
- break;
- }
- _routeCount = idx;
- }
-
- if (routeFlag && _moving)
- startMovement();
-
- if (_newDirection != _direction)
- dirChanged();
- else if (!_moving)
- updateFrame();
-
- int var1 = _unk1;
- if (_unk4 && (_hypotenuse > 0)) {
- int v1 = -(_currentScale - 100) * (_posDiff.x - 1) / _hypotenuse + _currentScale;
- var1 = MAX(1, 10000 / (v1 * _currentScale * var1));
- }
-
- if (!_moving || (_direction != _newDirection))
- return;
-
- Common::Point newPos = _playerPos;
-
- if (_v8452E < var1) {
- do {
- if (_v8452C < _posDiff.x)
- _v8452C += _posDiff.y;
- if (_v8452C >= _posDiff.x) {
- if ((_posChange.y > 0) || (_v844C0 != 0))
- newPos.y += _yDirection;
- --_posChange.y;
- _v8452C -= _posDiff.x;
- }
-
- if (_v8452C < _posDiff.x) {
- if ((_posChange.x > 0) || (_v844C0 != 0))
- newPos.x += _xDirection;
- --_posChange.x;
- }
-
- if ((_v844BC == 0) && (_v844C0 == 0) && (_v844BE == 0)) {
- routeFlag = _madsVm->scene()->getDepthHighBit(newPos);
-
- if (_special == 0)
- _special = _madsVm->scene()->getDepthHighBits(newPos);
- }
-
- _v8452E += _v84530;
-
- } while ((_v8452E < var1) && !routeFlag && ((_posChange.x > 0) || (_posChange.y > 0) || (_v844C0 != 0)));
- }
-
- _v8452E -= var1;
-
- if (routeFlag)
- moveComplete();
- else {
- if (!_v844C0) {
- // If the move is complete, make sure the position is exactly on the given destination
- if (_posChange.x == 0)
- newPos.x = _destPos.x;
- if (_posChange.y == 0)
- newPos.y = _destPos.y;
- }
-
- _playerPos = newPos;
- }
-}
-
-void MadsPlayer::dirChanged() {
- int dirIndex = 0, dirIndex2 = 0;
- int newDir = 0, newDir2 = 0;
-
- if (_direction != _newDirection) {
- // Find the index for the given direction in the player direction list
- int tempDir = _direction;
- do {
- ++dirIndex;
- newDir += tempDir;
- tempDir = _directionListIndexes[tempDir + 10];
- } while (tempDir != _newDirection);
- }
-
-
- if (_direction != _newDirection) {
- // Find the index for the given direction in the player direction list
- int tempDir = _direction;
- do {
- ++dirIndex2;
- newDir2 += tempDir;
- tempDir = _directionListIndexes[tempDir + 20];
- } while (tempDir != _newDirection);
- }
-
- int diff = dirIndex - dirIndex2;
- if (diff == 0)
- diff = newDir - newDir2;
-
- _direction = (diff >= 0) ? _directionListIndexes[_direction + 20] : _directionListIndexes[_direction + 10];
- setupFrame();
- if ((_direction == _newDirection) && !_moving)
- updateFrame();
-
- _priorTimer += 1;
-}
-
-void MadsPlayer::moveComplete() {
- reset();
- //todo: Unknown flag
-}
-
-void MadsPlayer::reset() {
- _destPos = _playerPos;
- _destFacing = 5;
- _newDirection = _direction;
-
- _madsVm->scene()->_action._startWalkFlag = false;
- _madsVm->scene()->_action._walkFlag = false;
- _moving = false;
- _v844BC = false;
- _v844C0 = false;
- _v844BE = 0;
- _next = 0;
- _routeCount = 0;
-}
-
-/**
- * Scans along an edge connecting two points within the depths/walk surface, and returns the information of the first
- * pixel high nibble encountered with a non-zero value
- */
-int MadsPlayer::scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos) {
- // For compressed depth surfaces, always return 0
- if (_madsVm->scene()->getSceneResources()._depthStyle != 2)
- return 0;
-
- int yDiff = destPos.y - srcPos.y;
- int yAmount = MADS_SURFACE_WIDTH;
-
- if (yDiff < 0) {
- yDiff = -yDiff;
- yAmount = -yAmount;
- }
-
- int xDiff = destPos.x - srcPos.y;
- int xDirection = 1;
- int xAmount = 0;
- if (xDiff < 0) {
- xDiff = -xDiff;
- xDirection = -xDirection;
- xAmount = MIN(yDiff, xDiff);
- }
-
- ++xDiff;
- ++yDiff;
-
- const byte *srcP = depthSurface->getBasePtr(srcPos.x, srcPos.y);
- int index = xAmount;
-
- // Outer horizontal movement loop
- for (int yIndex = 0; yIndex < yDiff; ++yIndex) {
- index += yDiff;
- int v = (*srcP & 0x7F) >> 4;
- if (v)
- return v;
-
- // Inner loop for handling vertical movement
- while (index >= xDiff) {
- index -= xDiff;
-
- v = (*srcP & 0x7F) >> 4;
- if (v)
- return v;
-
- srcP += yAmount;
- }
-
- srcP += xDirection;
- }
-
- return 0;
-}
-
-/**
- * Starts a player moving to a given destination
- */
-void MadsPlayer::startMovement() {
- int xDiff = _destPos.x - _playerPos.x;
- int yDiff = _destPos.y - _playerPos.y;
- int srcScale = getScale(_playerPos.y);
- int destScale = getScale(_destPos.y);
-
- // Sets the X direction
- if (xDiff > 0)
- _xDirection = 1;
- else if (xDiff < 0)
- _xDirection = -1;
- else
- _xDirection = 0;
-
- // Sets the Y direction
- if (yDiff > 0)
- _yDirection = 1;
- else if (yDiff < 0)
- _yDirection = -1;
- else
- _yDirection = 0;
-
- xDiff = ABS(xDiff);
- yDiff = ABS(yDiff);
- int scaleDiff = ABS(srcScale - destScale);
-
- int xAmt100 = xDiff * 100;
- int yAmt100 = yDiff * 100;
- int xAmt33 = xDiff * 33;
-
- int scaleAmount = (_unk4 ? scaleDiff * 3 : 0) + 100 * yDiff / 100;
- int scaleAmount100 = scaleAmount * 100;
-
- // Figure out direction that will need to be moved in
- int majorDir;
- if (xDiff == 0)
- majorDir = 1;
- else if (yDiff == 0)
- majorDir = 3;
- else {
- if ((scaleAmount < xDiff) && ((xAmt33 / scaleAmount) >= 141))
- majorDir = 3;
- else if (yDiff <= xDiff)
- majorDir = 2;
- else if ((scaleAmount100 / xDiff) >= 141)
- majorDir = 1;
- else
- majorDir = 2;
- }
-
- switch (majorDir) {
- case 1:
- _newDirection = (_yDirection <= 0) ? 8 : 2;
- break;
- case 2: {
- _newDirection = ((_yDirection <= 0) ? 9 : 3) - ((_xDirection <= 0) ? 2 : 0);
- break;
- }
- case 3:
- _newDirection = (_xDirection <= 0) ? 4 : 6;
- break;
- default:
- break;
- }
-
- _hypotenuse = SqrtF16(xAmt100 * xAmt100 + yAmt100 * yAmt100);
- _posDiff.x = xDiff + 1;
- _posDiff.y = yDiff + 1;
- _posChange.x = xDiff;
- _posChange.y = yDiff;
-
- int majorChange = MAX(xDiff, yDiff);
- _v84530 = (majorChange == 0) ? 0 : _hypotenuse / majorChange;
-
- if (_playerPos.x > _destPos.x)
- _v8452C = MAX(_posChange.x, _posChange.y);
- else
- _v8452C = 0;
-
- _hypotenuse /= 100;
- _v8452E = -_v84530;
-}
-
-void MadsPlayer::turnToDestFacing() {
- if (_destFacing != 5)
- _newDirection = _destFacing;
-}
-
-void MadsPlayer::setupRoute(bool bitFlag) {
- // Reset the flag set of nodes in use
- SceneNodeList &nodes = _madsVm->scene()->getSceneResources()._nodes;
- for (uint i = 0; i < nodes.size(); ++i)
- nodes[i].active = false;
-
- // Start constructing route node list
- _routeLength = 0x3FFF;
- _routeCount = 0;
-
- setupRouteNode(_tempRoute, nodes.size() - 1, bitFlag ? 0xC000 : 0x8000, 0);
-}
-
-void MadsPlayer::setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength) {
- SceneNodeList &nodes = _madsVm->scene()->getSceneResources()._nodes;
- SceneNode &currentNode = nodes[nodeIndex];
- currentNode.active = true;
-
- *routeIndexP++ = nodeIndex;
-
- int subIndex = nodes.size() - 2;
- int indexVal = nodes[nodeIndex].indexes[subIndex];
- if (indexVal & flags) {
- routeLength += indexVal & 0x3FFF;
- if (routeLength < _routeLength) {
- // Found a new shorter route to destination, so set up the route with the found one
- Common::copy(_tempRoute, routeIndexP, _routeIndexes);
- _routeCount = routeIndexP - _tempRoute;
- _routeLength = indexVal & 0x3FFF;
- }
- } else {
- for (int idx = nodes.size() - 2; idx > 0; --idx) {
- int nodePos = idx - 1;
- if (!nodes[nodePos].active && ((currentNode.indexes[nodePos] & flags) != 0))
- setupRouteNode(routeIndexP, nodePos, 0x8000, indexVal & 0x3fff);
- }
- }
-
- currentNode.active = false;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/mads_player.h b/engines/m4/mads_player.h
deleted file mode 100644
index bbeefaf3d5..0000000000
--- a/engines/m4/mads_player.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_MADS_PLAYER_H
-#define M4_MADS_PLAYER_H
-
-#include "common/scummsys.h"
-#include "m4/mads_scene.h"
-
-namespace M4 {
-
-#define PLAYER_SEQ_INDEX -2
-
-class MadsPlayer {
-private:
- int getScale(int yp);
- int getSpriteSlot();
- void setTicksAmount();
- void resetActionList();
- int queueAction(int v0, int v1);
- void idle();
- void move();
- void dirChanged();
- void reset();
- int scanPath(M4Surface *depthSurface, const Common::Point &srcPos, const Common::Point &destPos);
- void startMovement();
- void setupRouteNode(int *routeIndexP, int nodeIndex, int flags, int routeLength);
-public:
- char _spritesPrefix[16];
- int _spriteSetCount;
- bool _spriteSetsPresent[8];
- Common::Point _playerPos;
- Common::Point _destPos;
- Common::Point _posChange;
- Common::Point _posDiff;
- int _hypotenuse;
- uint32 _priorTimer;
- uint _ticksAmount;
- int16 _direction, _newDirection;
- bool _stepEnabled;
- bool _visible, _priorVisible;
- bool _visible3;
- bool _forceRefresh;
- int16 _currentScale;
- int16 _yScale;
- int16 _currentDepth;
- int16 _spriteListStart, _spriteListIdx;
- bool _spritesChanged;
- uint16 _frameOffset, _frameNum;
- bool _moving;
- int _unk1;
- int _frameCount;
- int _frameListIndex;
- int _actionIndex;
- int _actionList[12];
- int _actionList2[12];
- int _unk2;
- int _unk3;
- int _xDirection, _yDirection;
- int _destFacing;
- int _special;
- int _next;
- int _routeCount;
- int _routeOffset;
- int _tempRoute[MAX_ROUTE_NODES];
- int _routeIndexes[MAX_ROUTE_NODES];
- bool _unk4;
- bool _v844BC;
- int _v844BE;
- bool _v844C0;
- int _v8452E;
- int _v8452C;
- int _v84530;
- int _routeLength;
-
- static const int _directionListIndexes[32];
-public:
- MadsPlayer();
-
- bool loadSprites(const char *prefix);
- void update();
- void updateFrame();
- void setupFrame();
- void step();
- void nextFrame();
- void setDest(int destX, int destY, int facing);
- void turnToDestFacing();
- void setupRoute(bool bitFlag);
- void moveComplete();
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp
deleted file mode 100644
index e2d034f6d1..0000000000
--- a/engines/m4/mads_scene.cpp
+++ /dev/null
@@ -1,1272 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/textconsole.h"
-
-#include "m4/mads_scene.h"
-#include "m4/dialogs.h"
-#include "m4/globals.h"
-#include "m4/scene.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/rails.h"
-#include "m4/font.h"
-#include "m4/m4_views.h"
-#include "m4/mads_views.h"
-#include "m4/compression.h"
-#include "m4/staticres.h"
-#include "m4/animation.h"
-
-namespace M4 {
-
-static const int INV_ANIM_FRAME_SPEED = 2;
-static const int INVENTORY_X = 160;
-static const int INVENTORY_Y = 159;
-static const int SCROLLER_DELAY = 200;
-
-//--------------------------------------------------------------------------
-
-void SceneNode::load(Common::SeekableReadStream *stream) {
- // Get the next data block
- pt.x = stream->readUint16LE();
- pt.y = stream->readUint16LE();
-
- for (int i = 0; i < MAX_ROUTE_NODES; ++i)
- indexes[i] = stream->readUint16LE();
-}
-
-//--------------------------------------------------------------------------
-
-MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResources), MadsView(this) {
- _vm = vm;
- _activeAnimation = NULL;
-
- MadsView::_bgSurface = Scene::_backgroundSurface;
- MadsView::_depthSurface = Scene::_walkSurface;
- _interfaceSurface = new MadsInterfaceView(vm);
- _showMousePos = false;
- _mouseMsgIndex = -1;
- _previousScene = -1;
-}
-
-MadsScene::~MadsScene() {
- delete _activeAnimation;
- _activeAnimation = NULL;
- leaveScene();
- _vm->_viewManager->deleteView(_interfaceSurface);
-}
-
-/**
- * Secondary scene loading code
- */
-void MadsScene::loadScene2(const char *aaName, int sceneNumber) {
- // TODO: Completely finish
- _madsVm->globals()->previousScene = _madsVm->globals()->sceneNumber;
- _madsVm->globals()->sceneNumber = sceneNumber;
-
- _spriteSlots.clear();
- _sequenceList.clear();
- _kernelMessages.clear();
-
- // Load up the properties for the scene
- _sceneResources.load(_currentScene, NULL, 0/*word_83546*/, _walkSurface, _backgroundSurface);
-
- // Load scene walk paths
- loadSceneCodes(_currentScene);
-
- // Initialize the scene animation
- uint16 flags = 0x4100;
- if (_madsVm->globals()->_config.textWindowStill)
- flags |= 0x200;
-
- _sceneAnimation->initialize(aaName, flags, _interfaceSurface, NULL);
-}
-
-/**
- * Existing ScummVM code that needs to be eventually replaced with MADS code
- */
-void MadsScene::loadSceneTemporary() {
- /* Existing code that eventually needs to be replaced with the proper MADS code */
- // Set system palette entries
- _vm->_palette->blockRange(0, 18);
- RGB8 sysColors[3] = { {0x1f<<2, 0x2d<<2, 0x31<<2}, {0x24<<2, 0x37<<2, 0x3a<<2},
- {0x00<<2, 0x10<<2, 0x16<<2}};
- _vm->_palette->setPalette(&sysColors[0], 4, 3);
-
- _interfaceSurface->initialize();
-
- loadSceneHotspots(_currentScene);
-
- _action.clear();
-}
-
-void MadsScene::loadScene(int sceneNumber) {
- // Close the menu if it's active
- View *mainMenu = _vm->_viewManager->getView(VIEWID_MAINMENU);
- if (mainMenu != NULL) {
- _vm->_viewManager->deleteView(mainMenu);
- }
-
- // Handle common scene setting
- Scene::loadScene(sceneNumber);
- _madsVm->globals()->_nextSceneId = sceneNumber;
-
- // Existing ScummVM code that needs to be eventually replaced with MADS code
- loadSceneTemporary();
-
- _madsVm->_player._spritesChanged = true;
- _madsVm->globals()->clearQuotes();
- _dynamicHotspots.reset();
-
- // Signal the script engine what scene is to be active
- _sceneLogic.selectScene(sceneNumber);
-
- // Add the scene if necessary to the list of scenes that have been visited
- _vm->globals()->addVisitedScene(sceneNumber);
-
- if (_vm->getGameType() == GType_RexNebular)
- _sceneLogic.setupScene();
-
- // TODO: Unknown code
-
- // Secondary scene load routine
- if (_vm->getGameType() == GType_RexNebular)
- // Secondary scene load routine
- loadScene2("*I0.AA", sceneNumber);
-
- _madsVm->_player.loadSprites(NULL);
-
- switch (_madsVm->globals()->_config.screenFades) {
- case 0:
- _abortTimers2 = 2;
- break;
- case 2:
- _abortTimers2 = 21;
- break;
- default:
- _abortTimers2 = 20;
- break;
- }
- _abortTimers = 0;
- _abortTimersMode2 = ABORTMODE_1;
-
-
- // Do any scene specific setup
- if (_vm->getGameType() == GType_RexNebular)
- _sceneLogic.doEnterScene();
-
- // Miscellaneous player setup
- //_madsVm->_player._destPos = _madsVm->_player._destPos;
- _madsVm->_player._newDirection = _madsVm->_player._direction;
- _madsVm->_player.setupFrame();
- _madsVm->_player.updateFrame();
-
- // Purge resources
- _vm->res()->purge();
-}
-
-void MadsScene::loadSceneHotspots(int sceneNumber) {
- char filename[kM4MaxFilenameSize];
- sprintf(filename, "rm%i.hh", sceneNumber);
- MadsPack hotSpotData(filename, _vm);
- Common::SeekableReadStream *hotspotStream = hotSpotData.getItemStream(0);
-
- int hotspotCount = hotspotStream->readUint16LE();
- delete hotspotStream;
-
- hotspotStream = hotSpotData.getItemStream(1);
-
- // Clear current hotspot lists
- _sceneResources.hotspots->clear();
- _sceneResources.hotspots->loadHotSpots(hotspotStream, hotspotCount);
-
- delete hotspotStream;
-}
-
-void MadsScene::leaveScene() {
- _sceneResources.hotspots->clear();
- _sceneResources.dynamicHotspots->clear();
-
- delete _sceneResources.hotspots;
- delete _sceneResources.dynamicHotspots;
- delete _walkSurface;
-
- if (_activeAnimation) {
- delete _activeAnimation;
- _activeAnimation = NULL;
- }
-
- Scene::leaveScene();
-}
-
-void MadsScene::show() {
- Scene::show();
- _vm->_viewManager->addView(_interfaceSurface);
-}
-
-void MadsScene::loadSceneCodes(int sceneNumber, int index) {
- char filename[kM4MaxFilenameSize];
- Common::SeekableReadStream *sceneS;
-
- if (_vm->getGameType() == GType_Phantom || _vm->getGameType() == GType_DragonSphere) {
- sprintf(filename, "rm%i.ww%i", sceneNumber, index);
- MadsPack walkData(filename, _vm);
- sceneS = walkData.getItemStream(0);
- _walkSurface->loadCodesMads(sceneS);
- _vm->res()->toss(filename);
- }
-}
-
-void MadsScene::mouseMove(int x, int y) {
- HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
- if (currentHotSpot != NULL) {
- _vm->_mouse->setCursorNum(currentHotSpot->getCursor());
-
- _action._selectedRow = -1;
- _action._actionMode = ACTMODE_NONE;
- _action._actionMode2 = ACTMODE2_4;
- _action._hotspotId = currentHotSpot->getIndex();
-
- } else {
- _vm->_mouse->setCursorNum(0);
- }
-}
-
-void MadsScene::leftClick(int x, int y) {
- // TODO: figure out the rest of Scene_leftClick, and implements relevant parts in the interface class
- _action._v86F4C = -1;
- _action._v86F4E = 0;
- _customDest = _madsVm->_mouse->currentPos();
- _action._selectedAction = -1;
- _action._v86F4A = true;
-}
-
-void MadsScene::rightClick(int x, int y) {
- if (_vm->getGameType() == GType_RexNebular) {
- // ***DEBUG*** - sample dialog display
- int idx = 3; //_madsVm->_globals->messageIndexOf(0x277a);
- const char *msg = _madsVm->globals()->loadMessage(idx);
- Dialog *dlg = new Dialog(_vm, msg, "TEST DIALOG");
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
- }
-}
-
-void MadsScene::setAction(int action, int objectId) {
- VALIDATE_MADS;
-
- error("todo");
- // TODO: Actually executing actions directly for objects. Also, some object actions are special in that
- // a second object can be selected, as in 'use gun to shoot person', with requires a target
-/*
- // Set up the new action
- strcpy(statusText, _madsVm->globals()->getVocab(action));
- statusText[0] = toupper(statusText[0]); // capitalize first letter
-
- if (objectId != -1) {
- MadsObject *obj = _madsVm->globals()->getObject(objectId);
- sprintf(statusText + strlen(statusText), " %s", _madsVm->globals()->getVocab(obj->descId));
- } else {
- _currentAction = action;
- }
-*/
-// setStatusText(statusText);
-}
-
-/**
- * Draws all the elements of the scene
- */
-void MadsScene::drawElements() {
- refresh();
-
- // Copy the user interface surface onto the surface
- _interfaceSurface->copyTo(this, 0, this->height() - _interfaceSurface->height());
-}
-
-
-void MadsScene::update() {
- // Draw all the various elements
- drawElements();
-
- _action.set();
-}
-
-void MadsScene::updateState() {
- if (!_abortTimers && !_madsVm->_player._unk3) {
- if (_dynamicHotspots._changed)
- _dynamicHotspots.refresh();
-
-// int v = (_madsVm->_player._stepEnabled && !_action._startWalkFlag && !_abortTimers2) ? 1 : 0;
-// _screenObjects.check(v, false);
- }
-
- // Handle starting off any selected action
- bool doPreAction = false;
- if ((_action._selectedAction != 0) && _madsVm->_player._stepEnabled &&
- !_action._startWalkFlag && !_abortTimers && !_madsVm->_player._unk3) {
- // Start the action
- _action.startAction();
-
- if (_action._action.verbId == kVerbLookAt) {
- _action._action.verbId = kVerbLook;
- _action._savedFields.selectedRow = 0;
- }
- doPreAction = true;
- }
- if (doPreAction || ((_abortTimers != 0) && (_abortTimersMode == ABORTMODE_2)))
- doPreactions();
-
- checkStartWalk();
-
- if (_action._inProgress && !_madsVm->_player._moving && !_action._startWalkFlag &&
- (_madsVm->_player._newDirection == _madsVm->_player._direction)) {
- // Reached the end of action movement, so ready to actually do action
- doAction();
- } else if ((_abortTimers != 0) && (_abortTimersMode == ABORTMODE_0))
- // Do an action designated by scripts
- doAction();
-
- bool freeFlag = false;
- if (_currentScene != _nextScene)
- freeFlag = true;
- else {
- doSceneStep();
-
- if (_currentScene != _nextScene)
- freeFlag = true;
- else {
- // Update the player
- _madsVm->_player.nextFrame();
-
- // Handle updating the animation
- if (!_abortTimers && (_activeAnimation))
- _activeAnimation->update();
-
- // Handle refreshing the mouse position display
- if (_mouseMsgIndex != -1)
- _madsVm->scene()->_kernelMessages.remove(_mouseMsgIndex);
- if (_showMousePos) {
- char buffer[20];
- sprintf(buffer, "(%d,%d)", _madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y);
-
- _mouseMsgIndex = _madsVm->scene()->_kernelMessages.add(Common::Point(5, 5), 0x203, 0, 0, 1, buffer);
- }
- }
- }
-
- if (_madsVm->globals()->_config.easyMouse)
- _action.refresh();
-
- if ((_activeAnimation) && !_abortTimers) {
- _activeAnimation->update();
- if (((MadsAnimation *) _activeAnimation)->freeFlag() || freeFlag) {
- delete _activeAnimation;
- _activeAnimation = NULL;
- }
- }
-
- MadsView::update();
-
- // Remove the animation if it's been completed
- if ((_activeAnimation) && ((MadsAnimation *)_activeAnimation)->freeFlag())
- freeAnimation();
-
- if ((_action._selectedAction != 0) || !_madsVm->_player._stepEnabled) {
- _action.clear();
- _action._selectedAction = 0;
- }
-}
-
-void MadsScene::checkStartWalk() {
- if (_action._startWalkFlag && _action._walkFlag) {
- _madsVm->_player.setDest(_destPos.x, _destPos.y, _destFacing);
- _action._startWalkFlag = false;
- }
-}
-
-void MadsScene::doPreactions() {
- if ((_screenObjects._v832EC == 0) || (_screenObjects._v832EC == 2)) {
- _abortTimersMode2 = ABORTMODE_2;
- _action.checkAction();
-
- _sceneLogic.doPreactions();
-
- if (_abortTimersMode == ABORTMODE_2)
- _abortTimers = 0;
- }
-}
-
-void MadsScene::doSceneStep() {
- // Step through the scene
- _sceneLogic.doSceneStep();
-
- _madsVm->_player.step();
- _madsVm->_player._unk3 = 0;
-
- if (_abortTimersMode == ABORTMODE_1)
- _abortTimers = 0;
-}
-
-void MadsScene::doAction() {
- AbortTimerMode mode = ABORTMODE_0;
- _abortTimersMode2 = mode;
-
- if ((_action._inProgress || (_abortTimers != 0)) && !_action._v8453A) {
- _sceneLogic.doAction();
- mode = _action._inProgress ? ABORTMODE_0 : ABORTMODE_1;
- }
-
- if (_screenObjects._v832EC)
- _action._inProgress = false;
- else {
- if ((_action._inProgress || (_abortTimers != 0)) && (mode == ABORTMODE_0) && (_action._v8453A == mode)) {
- // TODO: sound_fn_p();
- mode = _action._inProgress ? ABORTMODE_0 : ABORTMODE_1;
-
- }
-
- if ((_action._inProgress || (_abortTimers != 0)) && (mode == ABORTMODE_0) && (_action._v8453A == mode)) {
- // Perform a core scene-indepedant action on an object
- // object_do_action
- }
- }
-
-}
-
-
-/**
- * Does extra work at cleaning up the animation, and then deletes it
- */
-void MadsScene::freeAnimation() {
- if (!_activeAnimation)
- return;
-
- MadsAnimation *anim = (MadsAnimation *)_activeAnimation;
- if (anim->freeFlag()) {
- _madsVm->scene()->_spriteSlots.clear();
- _madsVm->scene()->_spriteSlots.fullRefresh();
- _madsVm->scene()->_sequenceList.scan();
- }
-
- if (_madsVm->_player._visible) {
- _madsVm->_player._forceRefresh = true;
- _madsVm->_player.update();
- }
-
- delete _activeAnimation;
- _activeAnimation = NULL;
-}
-
-
-int MadsScene::loadSceneSpriteSet(const char *setName) {
- char resName[100];
- strcpy(resName, setName);
-
- // Append a '.SS' if it doesn't alreayd have an extension
- if (!strchr(resName, '.'))
- strcat(resName, ".SS");
-
- return _spriteSlots.addSprites(resName);
-}
-
-enum boxSprites {
- topLeft = 0,
- topRight = 1,
- bottomLeft = 2,
- bottomRight = 3,
- left = 4,
- right = 5,
- top = 6,
- bottom = 7,
- topMiddle = 8,
- filler1 = 9,
- filler2 = 10
- // TODO: finish this
-};
-
-// TODO: calculate width and height, show text, show face if it exists
-// TODO: this has been tested with Dragonsphere only, there are some differences
-// in the sprites used in Phantom
-void MadsScene::showMADSV2TextBox(char *text, int x, int y, char *faceName) {
- int repeatX = 40; // FIXME: this is hardcoded
- int repeatY = 30; // FIXME: this is hardcoded
- int curX = x, curY = y;
- int topRightX = x; // TODO: this is probably not needed
- Common::SeekableReadStream *data = _vm->res()->get("box.ss");
- SpriteAsset *boxSprites = new SpriteAsset(_vm, data, data->size(), "box.ss");
- _vm->res()->toss("box.ss");
-
- RGBList *palData = new RGBList(boxSprites->getColorCount(), boxSprites->getPalette(), true);
- _vm->_palette->addRange(palData);
-
- for (int i = 0; i < boxSprites->getCount(); i++)
- boxSprites->getFrame(i)->translate(palData); // sprite pixel translation
-
- // Top left corner
- boxSprites->getFrame(topLeft)->copyTo(_backgroundSurface, x, curY);
- curX += boxSprites->getFrame(topLeft)->width();
-
- // Top line
- for (int i = 0; i < repeatX; i++) {
- boxSprites->getFrame(top)->copyTo(_backgroundSurface, curX, curY + 3);
- curX += boxSprites->getFrame(top)->width();
- }
-
- // Top right corner
- boxSprites->getFrame(topRight)->copyTo(_backgroundSurface, curX, curY);
- topRightX = curX;
-
- // Top middle
- // FIXME: the transparent color for this is also the black border color
- boxSprites->getFrame(topMiddle)->copyTo(_backgroundSurface,
- x + (curX - x) / 2 - boxSprites->getFrame(topMiddle)->width() / 2,
- curY - 5, 167);
- curX = x;
- curY += boxSprites->getFrame(topLeft)->height();
-
- // -----------------------------------------------------------------------------------------------
-
- // Draw contents
- for (int i = 0; i < repeatY; i++) {
- for (int j = 0; j < repeatX; j++) {
- if (j == 0) {
- boxSprites->getFrame(left)->copyTo(_backgroundSurface, curX + 3, curY);
- curX += boxSprites->getFrame(left)->width();
- } else if (j == repeatX - 1) {
- curX = topRightX - 2;
- boxSprites->getFrame(right)->copyTo(_backgroundSurface, curX + 3, curY + 1);
- } else {
- // TODO: the background of the contents follows a pattern which is not understood yet
- if (j % 2 == 0) {
- boxSprites->getFrame(filler1)->copyTo(_backgroundSurface, curX + 3, curY);
- curX += boxSprites->getFrame(filler1)->width();
- } else {
- boxSprites->getFrame(filler2)->copyTo(_backgroundSurface, curX + 3, curY);
- curX += boxSprites->getFrame(filler2)->width();
- }
- }
- } // for j
- curX = x;
- curY += boxSprites->getFrame(left)->height();
- } // for i
-
- // -----------------------------------------------------------------------------------------------
- curX = x;
-
- // Bottom left corner
- boxSprites->getFrame(bottomLeft)->copyTo(_backgroundSurface, curX, curY);
- curX += boxSprites->getFrame(bottomLeft)->width();
-
- // Bottom line
- for (int i = 0; i < repeatX; i++) {
- boxSprites->getFrame(bottom)->copyTo(_backgroundSurface, curX, curY + 1);
- curX += boxSprites->getFrame(bottom)->width();
- }
-
- // Bottom right corner
- boxSprites->getFrame(bottomRight)->copyTo(_backgroundSurface, curX, curY + 1);
-}
-
-void MadsScene::loadAnimation(const Common::String &animName, int abortTimers) {
- if (_activeAnimation)
- error("Multiple active animations are not allowed");
-
- MadsAnimation *anim = new MadsAnimation(_vm, this);
- anim->load(animName.c_str(), abortTimers);
- _activeAnimation = anim;
-}
-
-bool MadsScene::getDepthHighBit(const Common::Point &pt) {
- const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
- if (_sceneResources._depthStyle == 2)
- return ((*p << 4) & 0x80) != 0;
-
- return (*p & 0x80) != 0;
-}
-
-bool MadsScene::getDepthHighBits(const Common::Point &pt) {
- if (_sceneResources._depthStyle == 2)
- return 0;
-
- const byte *p = _depthSurface->getBasePtr(pt.x, pt.y);
- return (*p & 0x70) >> 4;
-}
-
-/*--------------------------------------------------------------------------*/
-
-void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface) {
- char buffer1[80];
- const char *sceneName;
-
- // TODO: Initialize spriteSet / xp_list
-
- if (sceneNumber > 0) {
- sceneName = MADSResourceManager::getResourceName(RESPREFIX_RM, sceneNumber, ".DAT");
- } else {
- strcpy(buffer1, "*");
- strcat(buffer1, resName);
- sceneName = buffer1; // TODO: Check whether this needs to be converted to 'HAG form'
- }
-
- Common::SeekableReadStream *rawStream = _vm->_resourceManager->get(sceneName);
- MadsPack sceneInfo(rawStream);
-
- // Chunk 0:
- // Basic scene info
- Common::SeekableReadStream *stream = sceneInfo.getItemStream(0);
-
- if (_vm->getGameType() == GType_RexNebular) {
- int resSceneId = stream->readUint16LE();
- assert(resSceneId == sceneNumber);
- } else {
- char roomFilename[10];
- char roomFilenameExpected[10];
- sprintf(roomFilenameExpected, "*RM%d", sceneNumber);
-
- stream->read(roomFilename, 6);
- roomFilename[6] = 0;
- assert(!strcmp(roomFilename, roomFilenameExpected));
- }
-
- // TODO: The following is wrong for Phantom/Dragon
- _artFileNum = stream->readUint16LE();
- _depthStyle = stream->readUint16LE();
- _width = stream->readUint16LE();
- _height = stream->readUint16LE();
-
- stream->skip(24);
-
- int nodeCount = stream->readUint16LE();
- _yBandsEnd = stream->readUint16LE();
- _yBandsStart = stream->readUint16LE();
- _maxScale = stream->readSint16LE();
- _minScale = stream->readSint16LE();
- for (int i = 0; i < DEPTH_BANDS_SIZE; ++i)
- _depthBands[i] = stream->readUint16LE();
- stream->skip(2);
-
- // Load in any scene objects
- for (int i = 0; i < nodeCount; ++i) {
- SceneNode rec;
- rec.load(stream);
- _nodes.push_back(rec);
- }
- for (int i = 0; i < 20 - nodeCount; ++i)
- stream->skip(48);
-
- // Add two extra nodes in that will be used for player movement
- for (int i = 0; i < 2; ++i) {
- SceneNode rec;
- _nodes.push_back(rec);
- }
-
- int setCount = stream->readUint16LE();
- stream->readUint16LE();
- for (int i = 0; i < setCount; ++i) {
- char buffer2[64];
- Common::String s(buffer2, 64);
- _setNames.push_back(s);
- }
-
- delete stream;
-
- // Initialize a copy of the surfaces if they weren't provided
- bool dsFlag = false, ssFlag = false;
- if (!surface) {
- surface = new M4Surface(_width, _height);
- ssFlag = true;
- } else if ((_width != surface->width()) || (_height != surface->height()))
- surface->setSize(_width, _height);
-
- if (!depthSurface) {
- depthSurface = new M4Surface(_width, _height);
- dsFlag = true;
- } else if ((_width != depthSurface->width()) || (_height != depthSurface->height()))
- depthSurface->setSize(_width, _height);
-
-
- // For Rex Nebular, read in the scene's compressed walk surface information
- if (_vm->getGameType() == GType_RexNebular) {
- assert(depthSurface);
- stream = sceneInfo.getItemStream(1);
- byte *walkData = (byte *)malloc(stream->size());
- stream->read(walkData, stream->size());
-
- // For Rex Nebular, the walk areas are part of the scene info
- byte *destP = depthSurface->getBasePtr(0, 0);
- const byte *srcP = walkData;
- byte runLength;
-
- // Run length encoded depth data
- while ((runLength = *srcP++) != 0) {
- if (_depthStyle == 2) {
- // 2-bit depth pixels
- byte byteVal = *srcP++;
- for (int byteCtr = 0; byteCtr < runLength; ++byteCtr) {
- byte v = byteVal;
- for (int bitCtr = 0; bitCtr < 4; ++bitCtr, v >>= 2)
- *destP++ = (((v & 1) + 1) << 3) - 1;
- }
- } else {
- // 8-bit depth pixels
- Common::fill(destP, destP + runLength, *srcP++);
- destP += runLength;
- }
- }
-
- free(walkData);
- delete stream;
- }
-
- _vm->_resourceManager->toss(sceneName);
-
- // Load the surface artwork
- surface->loadBackground(_artFileNum);
-
- // Final cleanup
- if (ssFlag)
- delete surface;
- if (dsFlag)
- delete depthSurface;
-}
-
-void MadsSceneResources::setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface) {
- int flags, hypotenuse;
-
- _nodes[nodeIndex].pt = pt;
-
- // Recalculate inter-node lengths
- for (uint idx = 0; idx < _nodes.size(); ++idx) {
- int entry;
- if (idx == (uint)nodeIndex) {
- entry = 0x3FFF;
- } else {
- // Process the node
- flags = getRouteFlags(pt, _nodes[idx].pt, depthSurface);
-
- int xDiff = ABS(_nodes[idx].pt.x - pt.x);
- int yDiff = ABS(_nodes[idx].pt.y - pt.y);
- hypotenuse = SqrtF16(xDiff * xDiff + yDiff * yDiff);
-
- if (hypotenuse >= 0x3FFF)
- // Shouldn't ever be this large
- hypotenuse = 0x3FFF;
-
- entry = hypotenuse | flags;
- _nodes[idx].indexes[nodeIndex] = entry;
- _nodes[nodeIndex].indexes[idx] = entry;
- }
- }
-}
-
-int MadsSceneResources::getRouteFlags(const Common::Point &src, const Common::Point &dest, M4Surface *depthSurface) {
- int result = 0x8000;
- bool flag = false;
-
- int xDiff = ABS(dest.x - src.x);
- int yDiff = ABS(dest.y - src.y);
- int xDirection = dest.x >= src.x ? 1 : -1;
- int yDirection = dest.y >= src.y ? depthSurface->width() : -depthSurface->width();
- int majorDiff = 0;
- if (dest.x < src.x)
- majorDiff = MAX(xDiff, yDiff);
- ++xDiff;
- ++yDiff;
-
- byte *srcP = depthSurface->getBasePtr(src.x, src.y);
-
- int totalCtr = majorDiff;
- for (int xCtr = 0; xCtr < xDiff; ++xCtr, srcP += xDirection) {
- totalCtr += yDiff;
-
- if ((*srcP & 0x80) == 0)
- flag = false;
- else if (!flag) {
- flag = true;
- result -= 0x4000;
- if (result == 0)
- break;
- }
-
- while (totalCtr >= xDiff) {
- totalCtr -= xDiff;
-
- if ((*srcP & 0x80) == 0)
- flag = false;
- else if (!flag) {
- flag = true;
- result -= 0x4000;
- if (result == 0)
- break;
- }
-
- srcP += yDirection;
- }
- if (result == 0)
- break;
- }
-
- return result;
-}
-
-/*--------------------------------------------------------------------------*/
-
-/*--------------------------------------------------------------------------
- * MadsInterfaceView handles the user interface section at the bottom of
- * game screens in MADS games
- *--------------------------------------------------------------------------
- */
-
-MadsInterfaceView::MadsInterfaceView(MadsM4Engine *vm): GameInterfaceView(vm,
- Common::Rect(0, MADS_SURFACE_HEIGHT, vm->_screen->width(), vm->_screen->height())) {
- _screenType = VIEWID_INTERFACE;
- _highlightedElement = -1;
- _topIndex = 0;
- _selectedObject = -1;
- _cheatKeyCtr = 0;
-
- _objectSprites = NULL;
- _objectPalData = NULL;
-
- /* Set up the rect list for screen elements */
- // Actions
- for (int i = 0; i < 10; ++i)
- _screenObjects.addRect((i / 5) * 32 + 1, (i % 5) * 8 + MADS_SURFACE_HEIGHT + 2,
- ((i / 5) + 1) * 32 + 3, ((i % 5) + 1) * 8 + MADS_SURFACE_HEIGHT + 2);
-
- // Scroller elements (up arrow, scroller, down arrow)
- _screenObjects.addRect(73, 160, 82, 167);
- _screenObjects.addRect(73, 168, 82, 190);
- _screenObjects.addRect(73, 191, 82, 198);
-
- // Inventory object names
- for (int i = 0; i < 5; ++i)
- _screenObjects.addRect(89, 158 + i * 8, 160, 166 + i * 8);
-
- // Full rectangle area for all vocab actions
- for (int i = 0; i < 5; ++i)
- _screenObjects.addRect(239, 158 + i * 8, 320, 166 + i * 8);
-}
-
-MadsInterfaceView::~MadsInterfaceView() {
- delete _objectSprites;
-}
-
-void MadsInterfaceView::setFontMode(InterfaceFontMode newMode) {
- switch (newMode) {
- case ITEM_NORMAL:
- _vm->_font->current()->setColors(4, 4, 0xff);
- break;
- case ITEM_HIGHLIGHTED:
- _vm->_font->current()->setColors(5, 5, 0xff);
- break;
- case ITEM_SELECTED:
- _vm->_font->current()->setColors(6, 6, 0xff);
- break;
- }
-}
-
-void MadsInterfaceView::initialize() {
- // Build up the inventory list
- _inventoryList.clear();
-
- for (uint i = 0; i < _madsVm->globals()->getObjectsSize(); ++i) {
- MadsObject *obj = _madsVm->globals()->getObject(i);
- if (obj->_roomNumber == PLAYER_INVENTORY)
- _inventoryList.push_back(i);
- }
-
- // If the inventory has at least one object, select it
- if (_inventoryList.size() > 0)
- setSelectedObject(_inventoryList[0]);
-}
-
-void MadsInterfaceView::setSelectedObject(int objectNumber) {
- char resName[80];
-
- // Load inventory resource
- if (_objectSprites) {
- _vm->_palette->deleteRange(_objectPalData);
- delete _objectSprites;
- }
-
- // Check to make sure the object is in the inventory, and also visible on-screen
- int idx = _inventoryList.indexOf(objectNumber);
- if (idx == -1) {
- // Object wasn't found, so return
- _selectedObject = -1;
- return;
- }
-
- // Found the object
- if (idx < _topIndex)
- _topIndex = idx;
- else if (idx >= (_topIndex + 5))
- _topIndex = MAX(0, idx - 4);
-
- _selectedObject = objectNumber;
- sprintf(resName, "*OB%.3dI.SS", objectNumber);
-
- Common::SeekableReadStream *data = _vm->res()->get(resName);
- _objectSprites = new SpriteAsset(_vm, data, data->size(), resName);
- _vm->res()->toss(resName);
-
- // Slot it into available palette space
- _objectPalData = _objectSprites->getRgbList();
- _vm->_palette->addRange(_objectPalData);
- _objectSprites->translate(_objectPalData, true);
-
- _objectFrameNumber = 0;
-}
-
-void MadsInterfaceView::addObjectToInventory(int objectNumber) {
- if (_inventoryList.indexOf(objectNumber) == -1) {
- _madsVm->globals()->getObject(objectNumber)->_roomNumber = PLAYER_INVENTORY;
- _inventoryList.push_back(objectNumber);
- }
-
- setSelectedObject(objectNumber);
-}
-
-void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
- _vm->_font->setFont(FONT_INTERFACE_MADS);
- char buffer[100];
-
- // Check to see if any dialog is currently active
- bool dialogVisible = _vm->_viewManager->getView(LAYER_DIALOG) != NULL;
-
- // Highlighting logic for action list
- int actionIndex = 0;
- for (int x = 0; x < 2; ++x) {
- for (int y = 0; y < 5; ++y, ++actionIndex) {
- // Determine the font color depending on whether an item is selected. Note that the first action,
- // 'Look', is always 'selected', even when another action is clicked on
- setFontMode((_highlightedElement == actionIndex) ? ITEM_HIGHLIGHTED :
- ((actionIndex == 0) ? ITEM_SELECTED : ITEM_NORMAL));
-
- // Get the verb action and capitalise it
- const char *verbStr = _madsVm->globals()->getVocab(kVerbLook + actionIndex);
- strcpy(buffer, verbStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- // Display the verb
- const Common::Rect r(_screenObjects[actionIndex]);
- _vm->_font->current()->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
- }
-
- // Check for highlighting of the scrollbar controls
- if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_SCROLLER) || (_highlightedElement == SCROLL_DOWN)) {
- // Highlight the control's borders
- const Common::Rect r(_screenObjects[_highlightedElement]);
- destSurface->frameRect(r, 5);
- }
-
- // Draw the horizontal line in the scroller representing the current top selected
- const Common::Rect scroller(_screenObjects[SCROLL_SCROLLER]);
- int yP = (_inventoryList.size() < 2) ? 0 : (scroller.height() - 5) * _topIndex / (_inventoryList.size() - 1);
- destSurface->setColor(4);
- destSurface->hLine(scroller.left + 2, scroller.right - 3, scroller.top + 2 + yP);
-
- // List inventory items
- for (uint i = 0; i < 5; ++i) {
- if ((_topIndex + i) >= _inventoryList.size())
- break;
-
- const char *descStr = _madsVm->globals()->getVocab(_madsVm->globals()->getObject(
- _inventoryList[_topIndex + i])->_descId);
- strcpy(buffer, descStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- const Common::Rect r(_screenObjects[INVLIST_START + i]);
-
- // Set the highlighting of the inventory item
- if (_highlightedElement == (int)(INVLIST_START + i)) setFontMode(ITEM_HIGHLIGHTED);
- else if (_selectedObject == _inventoryList[_topIndex + i]) setFontMode(ITEM_SELECTED);
- else setFontMode(ITEM_NORMAL);
-
- // Write out it's description
- _vm->_font->current()->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
-
- // Handle the display of any currently selected object
- if (_objectSprites) {
- // Display object sprite. Note that the frame number isn't used directly, because it would result
- // in too fast an animation
- M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED);
- spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, TRANSPARENT_COLOR_INDEX);
-
- if (!_madsVm->globals()->_config.invObjectsStill && !dialogVisible) {
- // If objects need to be animated, move to the next frame
- if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED))
- _objectFrameNumber = 0;
- }
-
- // List the vocab actions for the currently selected object
- MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
- int yIndex = MIN(_highlightedElement - VOCAB_START, obj->_vocabCount - 1);
-
- for (int i = 0; i < obj->_vocabCount; ++i) {
- const Common::Rect r(_screenObjects[VOCAB_START + i]);
-
- // Get the vocab description and capitalise it
- const char *descStr = _madsVm->globals()->getVocab(obj->_vocabList[i].vocabId);
- strcpy(buffer, descStr);
- if ((buffer[0] >= 'a') && (buffer[0] <= 'z')) buffer[0] -= 'a' - 'A';
-
- // Set the highlighting and display the entry
- setFontMode((i == yIndex) ? ITEM_HIGHLIGHTED : ITEM_NORMAL);
- _vm->_font->current()->writeString(destSurface, buffer, r.left, r.top, r.width(), 0);
- }
- }
-}
-
-bool MadsInterfaceView::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- MadsAction &act = _madsVm->scene()->_action;
-
- // If the mouse isn't being held down, then reset the repeated scroll timer
- if (eventType != MEVENT_LEFT_HOLD)
- _nextScrollerTicks = 0;
-
- // Handle various event types
- switch (eventType) {
- case MEVENT_MOVE:
- // If the cursor isn't in "wait mode", don't do any processing
- if (_vm->_mouse->getCursorNum() == CURSOR_WAIT)
- return true;
-
- // Ensure the cursor is the standard arrow
- _vm->_mouse->setCursorNum(CURSOR_ARROW);
-
- // Check if any interface element is currently highlighted
- _highlightedElement = _screenObjects.find(Common::Point(x, y));
-
- return true;
-
- case MEVENT_LEFT_CLICK:
- // Left mouse click
- {
- // Check if an inventory object was selected
- if ((_highlightedElement >= INVLIST_START) && (_highlightedElement < (INVLIST_START + 5))) {
- // Ensure there is an inventory item listed in that cell
- uint idx = _highlightedElement - INVLIST_START;
- if ((_topIndex + idx) < _inventoryList.size()) {
- // Set the selected object
- setSelectedObject(_inventoryList[_topIndex + idx]);
- }
- } else if ((_highlightedElement >= ACTIONS_START) && (_highlightedElement < (ACTIONS_START + 10))) {
- // A standard action was selected
- int verbId = kVerbLook + (_highlightedElement - ACTIONS_START);
- warning("Selected action #%d", verbId);
-
- } else if ((_highlightedElement >= VOCAB_START) && (_highlightedElement < (VOCAB_START + 5))) {
- // A vocab action was selected
- MadsObject *obj = _madsVm->globals()->getObject(_selectedObject);
- int vocabIndex = MIN(_highlightedElement - VOCAB_START, obj->_vocabCount - 1);
- if (vocabIndex >= 0) {
- act._actionMode = ACTMODE_OBJECT;
- act._actionMode2 = ACTMODE2_2;
- act._flags1 = obj->_vocabList[1].flags1;
- act._flags2 = obj->_vocabList[1].flags2;
-
- act._action.verbId = _selectedObject;
- act._articleNumber = act._flags2;
- }
- }
- }
- return true;
-
- case MEVENT_LEFT_HOLD:
- // Left mouse hold
- // Handle the scroller - the up/down buttons allow for multiple actions whilst the mouse is held down
- if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_DOWN)) {
- if ((_nextScrollerTicks == 0) || (g_system->getMillis() >= _nextScrollerTicks)) {
- // Handle scroll up/down action
- _nextScrollerTicks = g_system->getMillis() + SCROLLER_DELAY;
-
- if ((_highlightedElement == SCROLL_UP) && (_topIndex > 0))
- --_topIndex;
- if ((_highlightedElement == SCROLL_DOWN) && (_topIndex < (int)(_inventoryList.size() - 1)))
- ++_topIndex;
- }
- }
- return true;
-
- case MEVENT_LEFT_DRAG:
- // Left mouse drag
- // Handle the the the scroller area that can be dragged to adjust the top displayed index
- if (_highlightedElement == SCROLL_SCROLLER) {
- // Calculate the new top index based on the Y position
- const Common::Rect r(_screenObjects[SCROLL_SCROLLER]);
- _topIndex = CLIP((int)(_inventoryList.size() - 1) * (y - r.top - 2) / (r.height() - 5),
- 0, (int)_inventoryList.size() - 1);
- }
- return true;
-
- case KEVENT_KEY:
- if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
- handleCheatKey(param1);
- handleKeypress(param1);
- return true;
-
- default:
- break;
- }
-
- return false;
-}
-
-bool MadsInterfaceView::handleCheatKey(int32 keycode) {
- switch (keycode) {
- case Common::KEYCODE_SPACE:
- // TODO: Move player to current destination
- return true;
-
- case Common::KEYCODE_c | (Common::KBD_CTRL << 24):
- // Toggle display of mouse position
- _madsVm->scene()->_showMousePos = !_madsVm->scene()->_showMousePos;
- break;
-
- case Common::KEYCODE_t | (Common::KBD_ALT << 24): {
- // Teleport to room
- //Scene *sceneView = (Scene *)vm->_viewManager->getView(VIEWID_SCENE);
- // TODO: Implement teleport code
-
- return true;
- }
-
- default:
- break;
- }
-
- return false;
-}
-
-const char *CHEAT_SEQUENCE = "widepipe";
-
-bool MadsInterfaceView::handleKeypress(int32 keycode) {
- int flags = keycode >> 24;
- int kc = keycode & 0xffff;
-
- // Capitalise the letter if necessary
- if (_cheatKeyCtr < CHEAT_SEQUENCE_MAX) {
- if ((flags & Common::KBD_CTRL) && (kc == CHEAT_SEQUENCE[_cheatKeyCtr])) {
- ++_cheatKeyCtr;
- if (_cheatKeyCtr == CHEAT_SEQUENCE_MAX)
- Dialog::display(_vm, 22, cheatingEnabledDesc);
- return true;
- } else {
- _cheatKeyCtr = 0;
- }
- }
-
- // Handle the various keys
- if ((keycode == Common::KEYCODE_ESCAPE) || (keycode == Common::KEYCODE_F1)) {
- // Game menu
- _madsVm->globals()->dialogType = DIALOG_GAME_MENU;
- leaveScene();
- return false;
- } else if (flags & Common::KBD_CTRL) {
- // Handling of the different control key combinations
- switch (kc) {
- case Common::KEYCODE_i:
- // Mouse to inventory
- warning("TODO: Mouse to inventory");
- break;
-
- case Common::KEYCODE_k:
- // Toggle hotspots
- warning("TODO: Toggle hotspots");
- break;
-
- case Common::KEYCODE_p:
- // Player stats
- warning("TODO: Player stats");
- break;
-
- case Common::KEYCODE_q:
- // Quit game
- break;
-
- case Common::KEYCODE_s:
- // Activate sound
- warning("TODO: Activate sound");
- break;
-
- case Common::KEYCODE_t:
- // Rotate player - This was Ctrl-U in the original, but in ScummVM Ctrl-U is a global mute key
- _madsVm->_player._newDirection = _madsVm->_player._directionListIndexes[_madsVm->_player._newDirection + 10];
- break;
-
- case Common::KEYCODE_v: {
- // Release version
- Dialog *dlg = new Dialog(_vm, GameReleaseInfoStr, GameReleaseTitleStr);
- _vm->_viewManager->addView(dlg);
- _vm->_viewManager->moveToFront(dlg);
- return false;
- }
-
- default:
- break;
- }
- } else if ((flags & Common::KBD_ALT) && (kc == Common::KEYCODE_q)) {
- // Quit Game
-
- } else {
- // Standard keypresses
- switch (kc) {
- case Common::KEYCODE_F2:
- // Save game
- _madsVm->globals()->dialogType = DIALOG_SAVE;
- leaveScene();
- break;
- case Common::KEYCODE_F3:
- // Restore game
- _madsVm->globals()->dialogType = DIALOG_RESTORE;
- leaveScene();
- break;
- }
- }
-//DIALOG_OPTIONS
- return false;
-}
-
-void MadsInterfaceView::leaveScene() {
- // Close the scene
- View *view = _madsVm->_viewManager->getView(VIEWID_SCENE);
- _madsVm->_viewManager->deleteView(view);
-}
-
-//--------------------------------------------------------------------------
-
-int getActiveAnimationBool() {
- return (_madsVm->scene()->activeAnimation()) ? 1 : 0;
-}
-
-int getAnimationCurrentFrame() {
- Animation *anim = _madsVm->scene()->activeAnimation();
- return anim ? anim->getCurrentFrame() : 0;
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h
deleted file mode 100644
index 9835de4daf..0000000000
--- a/engines/m4/mads_scene.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_MADS_SCENE_H
-#define M4_MADS_SCENE_H
-
-#include "m4/scene.h"
-#include "m4/mads_logic.h"
-#include "m4/mads_views.h"
-
-namespace M4 {
-
-#define INTERFACE_HEIGHT 106
-class MadsInterfaceView;
-
-#define DEPTH_BANDS_SIZE 15
-#define MAX_ROUTE_NODES 22
-
-enum ScreenCategory {CAT_NONE = 0, CAT_ACTION = 1, CAT_INV_LIST = 2, CAT_INV_VOCAB, CAT_HOTSPOT = 4,
- CAT_INV_ANIM = 6, CAT_6, CAT_INV_SCROLLER = 7, CAT_12 = 12};
-
-class SceneNode {
-public:
- Common::Point pt;
- int indexes[MAX_ROUTE_NODES];
-
- bool active;
-
- SceneNode() {
- active = false;
- }
-
- void load(Common::SeekableReadStream *stream);
-};
-
-typedef Common::Array<SceneNode> SceneNodeList;
-
-class MadsSceneResources: public SceneResources {
-private:
- int getRouteFlags(const Common::Point &src, const Common::Point &dest, M4Surface *depthSurface);
-public:
- int _sceneId;
- int _artFileNum;
- int _depthStyle;
- int _width;
- int _height;
- SceneNodeList _nodes;
- Common::Array<Common::String> _setNames;
- int _yBandsStart, _yBandsEnd;
- int _maxScale, _minScale;
- int _depthBands[DEPTH_BANDS_SIZE];
-
- MadsSceneResources() {}
- ~MadsSceneResources() {}
- void load(int sceneId, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface);
- int bandsRange() const { return _yBandsEnd - _yBandsStart; }
- int scaleRange() const { return _maxScale - _minScale; }
- void setRouteNode(int nodeIndex, const Common::Point &pt, M4Surface *depthSurface);
-};
-
-class MadsScene : public Scene, public MadsView {
-private:
- MadsEngine *_vm;
- MadsSceneResources _sceneResources;
- Animation *_activeAnimation;
-
- MadsSceneLogic _sceneLogic;
- SpriteAsset *_playerSprites;
- int _mouseMsgIndex;
- int _highlightedHotspot;
-
- void drawElements();
- void loadScene2(const char *aaName, int sceneNumber);
- void loadSceneTemporary();
- void loadSceneHotspots(int sceneNumber);
- void clearAction();
- void appendActionVocab(int vocabId, bool capitalise);
- void setAction();
- void checkStartWalk();
- void doPreactions();
- void doSceneStep();
- void doAction();
-public:
- char _aaName[100];
- bool _showMousePos;
- Common::Point _destPos;
- int _destFacing;
- Common::Point _customDest;
-public:
- MadsScene(MadsEngine *vm);
- virtual ~MadsScene();
- void initialize() {
- _sceneLogic.initializeScripts();
- }
-
- // Methods that differ between engines
- virtual void loadScene(int sceneNumber);
- virtual void leaveScene();
- virtual void loadSceneCodes(int sceneNumber, int index = 0);
- virtual void show();
- virtual void mouseMove(int x, int y);
- virtual void leftClick(int x, int y);
- virtual void rightClick(int x, int y);
- virtual void setAction(int action, int objectId = -1);
- virtual void update();
-
- virtual void updateState();
-
- int loadSceneSpriteSet(const char *setName);
- void showMADSV2TextBox(char *text, int x, int y, char *faceName);
- void loadAnimation(const Common::String &animName, int abortTimers);
- Animation *activeAnimation() const { return _activeAnimation; }
- void freeAnimation();
-
- MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; }
- MadsSceneResources &getSceneResources() { return _sceneResources; }
- bool getDepthHighBit(const Common::Point &pt);
- bool getDepthHighBits(const Common::Point &pt);
-};
-
-#define CHEAT_SEQUENCE_MAX 8
-
-class IntegerList : public Common::Array<int> {
-public:
- int indexOf(int v) {
- for (uint i = 0; i < size(); ++i)
- if (operator [](i) == v)
- return i;
- return -1;
- }
-};
-
-enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED};
-
-enum InterfaceObjects {ACTIONS_START = 0, SCROLL_UP = 10, SCROLL_SCROLLER = 11, SCROLL_DOWN = 12,
- INVLIST_START = 13, VOCAB_START = 18};
-
-class MadsInterfaceView : public GameInterfaceView {
-private:
- IntegerList _inventoryList;
- RectList _screenObjects;
- int _highlightedElement;
- int _topIndex;
- uint32 _nextScrollerTicks;
- int _cheatKeyCtr;
-
- // Object display fields
- int _selectedObject;
- SpriteAsset *_objectSprites;
- RGBList *_objectPalData;
- int _objectFrameNumber;
-
- void setFontMode(InterfaceFontMode newMode);
- bool handleCheatKey(int32 keycode);
- bool handleKeypress(int32 keycode);
- void leaveScene();
-public:
- MadsInterfaceView(MadsM4Engine *vm);
- ~MadsInterfaceView();
-
- virtual void initialize();
- virtual void setSelectedObject(int objectNumber);
- virtual void addObjectToInventory(int objectNumber);
- int getSelectedObject() { return _selectedObject; }
- int getInventoryObject(int objectIndex) { return _inventoryList[objectIndex]; }
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-extern int getActiveAnimationBool();
-extern int getAnimationCurrentFrame();
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp
deleted file mode 100644
index c1d88d5741..0000000000
--- a/engines/m4/mads_views.cpp
+++ /dev/null
@@ -1,1632 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/m4_views.h"
-#include "m4/animation.h"
-#include "m4/dialogs.h"
-#include "m4/events.h"
-#include "m4/font.h"
-#include "m4/globals.h"
-#include "m4/mads_menus.h"
-#include "m4/m4.h"
-#include "m4/staticres.h"
-
-#include "common/algorithm.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-MadsAction::MadsAction(MadsView &owner): _owner(owner) {
- clear();
- _currentAction = kVerbNone;
- _startWalkFlag = false;
- _statusTextIndex = -1;
- _selectedAction = 0;
- _inProgress = false;
-}
-
-void MadsAction::clear() {
- _v83338 = 1;
- _actionMode = ACTMODE_NONE;
- _actionMode2 = ACTMODE2_0;
- _v86F42 = 0;
- _v86F4E = 0;
- _articleNumber = 0;
- _lookFlag = false;
- _v86F4A = 0;
- _statusText[0] = '\0';
- _selectedRow = -1;
- _hotspotId = -1;
- _v86F3A = -1;
- _v86F4C = -1;
- _action.verbId = -1;
- _action.objectNameId = -1;
- _action.indirectObjectId = -1;
- _textChanged = true;
- _walkFlag = false;
-}
-
-void MadsAction::appendVocab(int vocabId, bool capitalise) {
- char *s = _statusText + strlen(_statusText);
- const char *vocabStr = _madsVm->globals()->getVocab(vocabId);
- strcpy(s, vocabStr);
- if (capitalise)
- *s = toupper(*s);
-
- strcat(s, " ");
-}
-
-void MadsAction::set() {
- int hotspotCount = _madsVm->scene()->getSceneResources().hotspots->size();
- bool flag = false; // FIXME: unused
- strcpy(_statusText, "");
-
- _currentAction = -1;
- _action.objectNameId = -1;
- _action.indirectObjectId = -1;
-
- if (_actionMode == ACTMODE_TALK) {
- // Handle showing the conversation selection. Rex at least doesn't actually seem to use this
- if (_selectedRow >= 0) {
- const char *desc = _madsVm->_converse[_selectedRow].desc;
- if (desc)
- strcpy(_statusText, desc);
- }
- } else if (_lookFlag && (_selectedRow == 0)) {
- // Two 'look' actions in succession, so the action becomes 'Look around'
- strcpy(_statusText, lookAroundStr);
- } else {
- if ((_actionMode == ACTMODE_OBJECT) && (_selectedRow >= 0) && (_flags1 == 2) && (_flags2 == 0)) {
- // Use/to action
- int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject();
- MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject);
-
- _action.objectNameId = objEntry->_descId;
- _currentAction = objEntry->_vocabList[_selectedRow].vocabId;
-
- // Set up the status text stirng
- strcpy(_statusText, useStr);
- appendVocab(_action.objectNameId);
- strcpy(_statusText, toStr);
- appendVocab(_currentAction);
- } else {
- // Handling for if an action has been selected
- if (_selectedRow >= 0) {
- if (_actionMode == ACTMODE_VERB) {
- // Standard verb action
- _currentAction = verbList[_selectedRow].verb;
- } else {
- // Selected action on an inventory object
- int selectedObject = _madsVm->scene()->getInterface()->getSelectedObject();
- MadsObject *objEntry = _madsVm->globals()->getObject(selectedObject);
-
- _currentAction = objEntry->_vocabList[_selectedRow].vocabId;
- }
-
- appendVocab(_currentAction, true);
-
- if (_currentAction == kVerbLook) {
- // Add in the word 'add'
- strcat(_statusText, atStr);
- strcat(_statusText, " ");
- }
- }
-
- // Handling for if a hotspot has been selected/highlighted
- if ((_hotspotId >= 0) && (_selectedRow >= 0) && (_articleNumber > 0) && (_flags1 == 2)) {
- flag = true;
-
- strcat(_statusText, englishMADSArticleList[_articleNumber]);
- strcat(_statusText, " ");
- }
-
- if (_hotspotId >= 0) {
- if (_selectedRow < 0) {
- int verbId;
-
- if (_hotspotId < hotspotCount) {
- // Get the verb Id from the hotspot
- verbId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVerbID();
- } else {
- // Get the verb Id from the scene object
- verbId = (*_madsVm->scene()->getSceneResources().dynamicHotspots)[_hotspotId - hotspotCount].getVerbID();
- }
-
- if (verbId > 0) {
- // Set the specified action
- _currentAction = verbId;
- appendVocab(_currentAction, true);
- } else {
- // Default to a standard 'walk to'
- _currentAction = kVerbWalkTo;
- strcat(_statusText, walkToStr);
- }
- }
-
- if ((_actionMode2 == ACTMODE2_2) || (_actionMode2 == ACTMODE2_5)) {
- // Get name from given inventory object
- int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId);
- _action.objectNameId = _madsVm->globals()->getObject(objectId)->_descId;
- } else if (_hotspotId < hotspotCount) {
- // Get name from scene hotspot
- _action.objectNameId = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getVocabID();
- } else {
- // Get name from temporary scene hotspot
- _action.objectNameId = (*_madsVm->scene()->getSceneResources().dynamicHotspots)[_hotspotId].getVocabID();
- }
- appendVocab(_action.objectNameId);
- }
- }
-
- if ((_hotspotId >= 0) && (_articleNumber > 0) && !flag) {
- if (_articleNumber == -1) {
- if (_v86F3A >= 0) {
- int articleNum = 0;
-
- if ((_v86F42 == 2) || (_v86F42 == 5)) {
- int objectId = _madsVm->scene()->getInterface()->getInventoryObject(_hotspotId);
- articleNum = _madsVm->globals()->getObject(objectId)->_article;
- } else if (_v86F3A < hotspotCount) {
- articleNum = (*_madsVm->scene()->getSceneResources().hotspots)[_hotspotId].getArticle();
- } else {
-
- }
- }
-
- } else if ((_articleNumber == kVerbLook) || (_vm->getGameType() != GType_RexNebular) ||
- (strcmp(_madsVm->globals()->getVocab(_action.indirectObjectId), fenceStr) != 0)) {
- // Write out the article
- strcat(_statusText, englishMADSArticleList[_articleNumber]);
- } else {
- // Special case for a 'fence' entry in Rex Nebular
- strcat(_statusText, overStr);
- }
-
- strcat(_statusText, " ");
- }
-
- // Append object description if necessary
- if (_v86F3A >= 0)
- appendVocab(_action.indirectObjectId);
-
- // Remove any trailing space character
- int statusLen = strlen(_statusText);
- if ((statusLen > 0) && (_statusText[statusLen - 1] == ' '))
- _statusText[statusLen - 1] = '\0';
- }
-
- _textChanged = true;
-}
-
-void MadsAction::refresh() {
- // Exit immediately if nothing has changed
- if (!_textChanged)
- return;
-
- // Remove any old copy of the status text
- if (_statusTextIndex >= 0) {
- _owner._textDisplay.expire(_statusTextIndex);
- _statusTextIndex = -1;
- }
-
- if (_statusText[0] != '\0') {
- if ((_owner._screenObjects._v832EC == 0) || (_owner._screenObjects._v832EC == 2)) {
- Font *font = _madsVm->_font->getFont(FONT_MAIN_MADS);
- int textSpacing = -1;
-
- int strWidth = font->getWidth(_statusText);
- if (strWidth > 320) {
- // Too large to fit, so fall back on interface font
- font = _madsVm->_font->getFont(FONT_INTERFACE_MADS);
- strWidth = font->getWidth(_statusText, 0);
- textSpacing = 0;
- }
-
- // Add a new text display entry to display the status text at the bottom of the screen area
- uint colors = (_vm->getGameType() == GType_DragonSphere) ? 0x0300 : 0x0003;
-
- _statusTextIndex = _owner._textDisplay.add(160 - (strWidth / 2),
- MADS_SURFACE_HEIGHT + _owner._posAdjust.y - 13, colors, textSpacing, _statusText, font);
- }
- }
-
- _textChanged = false;
-}
-
-void MadsAction::startAction() {
- _madsVm->_player.moveComplete();
-
- _inProgress = true;
- _v8453A = ABORTMODE_0;
- _savedFields.selectedRow = _selectedRow;
- _savedFields.articleNumber = _articleNumber;
- _savedFields.actionMode = _actionMode;
- _savedFields.actionMode2 = _actionMode2;
- _savedFields.lookFlag = _lookFlag;
- int savedHotspotId = _hotspotId;
- int savedV86F3A = _v86F3A;
- int savedV86F42 = _v86F42;
-
- // Copy the action to be active
- _activeAction = _action;
- strcpy(_dialogTitle, _statusText);
-
- if ((_savedFields.actionMode2 == ACTMODE2_4) && (savedV86F42 == 0))
- _v8453A = ABORTMODE_1;
-
- _startWalkFlag = false;
- int hotspotId = -1;
- HotSpotList &dynHotspots = *_madsVm->scene()->getSceneResources().dynamicHotspots;
- HotSpotList &hotspots = *_madsVm->scene()->getSceneResources().hotspots;
-
- if (!_savedFields.lookFlag && (_madsVm->scene()->_screenObjects._v832EC != 1)) {
- if (_savedFields.actionMode2 == ACTMODE2_4)
- hotspotId = savedHotspotId;
- else if (savedV86F42 == 4)
- hotspotId = savedV86F3A;
-
- if (hotspotId >= hotspots.size()) {
- HotSpot &hs = dynHotspots[hotspotId - hotspots.size()];
- if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) {
- if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos = _madsVm->scene()->_customDest;
- }
- } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos.x = hs.getFeetX();
- _madsVm->scene()->_destPos.y = hs.getFeetY();
- }
- _madsVm->scene()->_destFacing = hs.getFacing();
- hotspotId = -1;
- }
- }
-
- if (hotspotId >= 0) {
- HotSpot &hs = hotspots[hotspotId];
- if ((hs.getFeetX() == -1) || (hs.getFeetX() == -3)) {
- if (_v86F4A && ((hs.getFeetX() == -3) || (_savedFields.selectedRow < 0))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos = _madsVm->scene()->_customDest;
- }
- } else if ((hs.getFeetX() >= 0) && ((_savedFields.actionMode == ACTMODE_NONE) || (hs.getCursor() < 2))) {
- _startWalkFlag = true;
- _madsVm->scene()->_destPos.x = hs.getFeetX();
- _madsVm->scene()->_destPos.y = hs.getFeetY();
- }
- _madsVm->scene()->_destFacing = hs.getFacing();
- }
-
- _walkFlag = _startWalkFlag;
-}
-
-void MadsAction::checkAction() {
- if (isAction(kVerbLookAt) || isAction(kVerbThrow))
- _startWalkFlag = 0;
-}
-
-bool MadsAction::isAction(int verbId, int objectNameId, int indirectObjectId) {
- if (_activeAction.verbId != verbId)
- return false;
- if ((objectNameId != 0) && (_activeAction.objectNameId != objectNameId))
- return false;
- if ((indirectObjectId != 0) && (_activeAction.indirectObjectId != indirectObjectId))
- return false;
- return true;
-}
-
-//--------------------------------------------------------------------------
-
-bool MadsSpriteSlot::operator==(const SpriteSlotSubset &other) const {
- return (spriteListIndex == other.spriteListIndex) && (frameNumber == other.frameNumber) &&
- (xp == other.xp) && (yp == other.yp) && (depth == other.depth) && (scale == other.scale);
-}
-
-void MadsSpriteSlot::copy(const SpriteSlotSubset &other) {
- spriteListIndex = other.spriteListIndex;
- frameNumber = other.frameNumber;
- xp = other.xp;
- yp = other.yp;
- depth = other.depth;
- scale = other.scale;
-}
-
-//--------------------------------------------------------------------------
-
-MadsSpriteSlots::MadsSpriteSlots(MadsView &owner): _owner(owner) {
- for (int i = 0; i < SPRITE_SLOTS_SIZE; ++i) {
- MadsSpriteSlot rec;
- _entries.push_back(rec);
- }
-
- startIndex = 0;
-}
-
-MadsSpriteSlots::~MadsSpriteSlots() {
- for (uint i = 0; i < _sprites.size(); ++i)
- delete _sprites[i];
-}
-
-void MadsSpriteSlots::clear() {
- _owner._textDisplay.clear();
- for (uint i = 0; i < _sprites.size(); ++i)
- delete _sprites[i];
- _sprites.clear();
-
- // Reset the sprite slots list back to a single entry for a full screen refresh
- startIndex = 1;
- _entries[0].spriteType = FULL_SCREEN_REFRESH;
- _entries[0].seqIndex = -1;
-}
-
-int MadsSpriteSlots::getIndex() {
- if (startIndex == SPRITE_SLOTS_SIZE)
- error("Run out of sprite slots");
-
- return startIndex++;
-}
-
-int MadsSpriteSlots::addSprites(const char *resName, bool suppressErrors, int flags) {
- // If errors are suppressed, first check if the resource exists
- if (suppressErrors) {
- if (!_vm->res()->resourceExists(resName))
- return -1;
- }
-
- // Append on a '.SS' suffix if the resource doesn't already have an extension
- char buffer[100];
- strncpy(buffer, resName, 95);
- buffer[95] = '\0';
- if (!strchr(buffer, '.'))
- strcat(buffer, ".SS");
-
- // Get the sprite set
- Common::SeekableReadStream *data = _vm->res()->get(buffer);
- SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), buffer, false, flags);
- spriteSet->translate(_madsVm->_palette);
- assert(spriteSet != NULL);
-
- _sprites.push_back(spriteSet);
- _vm->res()->toss(buffer);
-
- return _sprites.size() - 1;
-}
-
-int MadsSpriteSlots::addSprites(SpriteAsset *spriteSet) {
- _sprites.push_back(spriteSet);
-
- return _sprites.size() - 1;
-}
-
-void MadsSpriteSlots::deleteSprites(int listIndex) {
- if (listIndex < 0)
- return;
-
- delete _sprites[listIndex];
- _sprites[listIndex] = NULL;
- if (listIndex == ((int)_sprites.size() - 1))
- _sprites.remove_at(listIndex);
-}
-
-/*
- * Deletes the sprite slot with the given timer entry
- */
-void MadsSpriteSlots::deleteTimer(int seqIndex) {
- for (int idx = 0; idx < startIndex; ++idx) {
- if (_entries[idx].seqIndex == seqIndex)
- _entries[idx].spriteType = EXPIRED_SPRITE;
- }
-}
-
-class DepthEntry {
-public:
- int depth;
- int index;
-
- DepthEntry(int depthAmt, int indexVal) { depth = depthAmt; index = indexVal; }
-};
-
-bool sortHelper(const DepthEntry &entry1, const DepthEntry &entry2) {
- return entry1.depth < entry2.depth;
-}
-
-typedef Common::List<DepthEntry> DepthList;
-
-void MadsSpriteSlots::drawBackground() {
- // Draw all active sprites onto the background surface
- for (int i = 0; i < startIndex; ++i) {
- MadsSpriteSlot &slot = _entries[i];
-
- if (slot.spriteType >= 0) {
- _owner._dirtyAreas[i].active = false;
- } else {
- _owner._dirtyAreas[i].textActive = true;
- _owner._dirtyAreas.setSpriteSlot(i, slot);
-
- if (slot.spriteType == BACKGROUND_SPRITE) {
- SpriteAsset &spriteSet = getSprite(slot.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame((slot.frameNumber & 0x7fff) - 1);
- int xp = slot.xp;
- int yp = slot.yp;
-
- if (_entries[i].scale != -1) {
- // Adjust position based on frame size
- xp -= frame->width() / 2;
- yp -= frame->height() / 2;
- }
-
- if (slot.depth > 1) {
- // Draw the frame with depth processing
- _owner._bgSurface->copyFrom(frame, xp, yp, slot.depth, _owner._depthSurface, 100,
- frame->getTransparencyIndex());
- } else {
- // No depth, so simply draw the image
- frame->copyTo(_owner._bgSurface, xp, yp, frame->getTransparencyIndex());
- }
- }
- }
- }
-
- // Flag any remaining dirty areas as inactive
- for (uint i = startIndex; i < DIRTY_AREAS_TEXT_DISPLAY_IDX; ++i)
- _owner._dirtyAreas[i].active = false;
-}
-
-void MadsSpriteSlots::drawForeground(M4Surface *viewport) {
- DepthList depthList;
-
- // Get a list of sprite object depths for active objects
- for (int i = 0; i < startIndex; ++i) {
- if (_entries[i].spriteType >= SPRITE_ZERO) {
- DepthEntry rec(16 - _entries[i].depth, i);
- depthList.push_back(rec);
- }
- }
-
- // Sort the list in order of the depth
- Common::sort(depthList.begin(), depthList.end(), sortHelper);
-
- // Loop through each of the objects
- DepthList::iterator i;
- for (i = depthList.begin(); i != depthList.end(); ++i) {
- DepthEntry &de = *i;
- MadsSpriteSlot &slot = _entries[de.index];
- assert(slot.spriteListIndex < (int)_sprites.size());
- SpriteAsset &spriteSet = *_sprites[slot.spriteListIndex];
-
- // Get the sprite frame
- int frameNumber = slot.frameNumber & 0x7fff;
- bool flipped = (slot.frameNumber & 0x8000) != 0;
- M4Sprite *sprite = spriteSet.getFrame(frameNumber - 1);
-
- M4Surface *spr = sprite;
- if (flipped) {
- // Create a flipped copy of the sprite temporarily
- spr = sprite->flipHorizontal();
- }
-
- if ((slot.scale < 100) && (slot.scale != -1)) {
- // Minimalised drawing
- viewport->copyFrom(spr, slot.xp, slot.yp, slot.depth, _owner._depthSurface, slot.scale,
- sprite->getTransparencyIndex());
- } else {
- int xp, yp;
-
- if (slot.scale == -1) {
- xp = slot.xp - _owner._posAdjust.x;
- yp = slot.yp - _owner._posAdjust.y;
- } else {
- xp = slot.xp - (spr->width() / 2) - _owner._posAdjust.x;
- yp = slot.yp - spr->height() - _owner._posAdjust.y + 1;
- }
-
- if (slot.depth > 1) {
- // Draw the frame with depth processing
- viewport->copyFrom(spr, xp, yp, slot.depth, _owner._depthSurface, 100, sprite->getTransparencyIndex());
- } else {
- // No depth, so simply draw the image
- spr->copyTo(viewport, xp, yp, sprite->getTransparencyIndex());
- }
- }
-
- // Free sprite if it was a flipped one
- if (flipped)
- delete spr;
- }
-}
-
-void MadsSpriteSlots::setDirtyAreas() {
- for (int i = 0; i < startIndex; ++i) {
- if (_entries[i].spriteType >= 0) {
- _owner._dirtyAreas.setSpriteSlot(i, _entries[i]);
-
- _owner._dirtyAreas[i].textActive = (_entries[i].spriteType <= 0) ? 0 : 1;
- _entries[i].spriteType = 0;
- }
- }
-}
-
-/**
- * Flags the entire screen to be redrawn during the next drawing cycle
- */
-void MadsSpriteSlots::fullRefresh() {
- int idx = getIndex();
-
- _entries[idx].spriteType = FULL_SCREEN_REFRESH;
- _entries[idx].seqIndex = -1;
-}
-
-/**
- * Removes any sprite slots that are no longer needed
- */
-void MadsSpriteSlots::cleanUp() {
- // Delete any entries that aren't needed
- int idx = 0;
- while (idx < startIndex) {
- if (_entries[idx].spriteType < 0) {
- _entries.remove_at(idx);
- --startIndex;
- } else {
- ++idx;
- }
- }
-
- // Original engine sprite slot list was a fixed array, so to keep the engine similiar, for
- // now I'm adding in new entries to make up the original fixed total again
- while (_entries.size() < SPRITE_SLOTS_SIZE) {
- MadsSpriteSlot rec;
- _entries.push_back(rec);
- }
-}
-
-//--------------------------------------------------------------------------
-
-MadsTextDisplay::MadsTextDisplay(MadsView &owner): _owner(owner) {
- for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i) {
- MadsTextDisplayEntry rec;
- rec.active = false;
- rec.expire = 0;
- _entries.push_back(rec);
- }
-}
-
-void MadsTextDisplay::clear() {
- for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i)
- _entries[i].active = false;
-}
-
-int MadsTextDisplay::add(int xp, int yp, uint fontColor, int charSpacing, const char *msg, Font *font) {
- int usedSlot = -1;
-
- for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) {
- if (!_entries[idx].active) {
- usedSlot = idx;
-
- _entries[idx].bounds.left = xp;
- _entries[idx].bounds.top = yp;
- _entries[idx].font = font;
- _entries[idx].msg = msg;
- _entries[idx].bounds.setWidth(font->getWidth(msg, charSpacing));
- _entries[idx].bounds.setHeight(font->getHeight());
- _entries[idx].color1 = fontColor & 0xff;
- _entries[idx].color2 = fontColor >> 8;
- _entries[idx].spacing = charSpacing;
- _entries[idx].expire = 1;
- _entries[idx].active = true;
- break;
- }
- }
-
- return usedSlot;
-}
-
-void MadsTextDisplay::setDirtyAreas() {
- // Determine dirty areas for active text areas
- for (uint idx = 0, dirtyIdx = DIRTY_AREAS_TEXT_DISPLAY_IDX; dirtyIdx < DIRTY_AREAS_SIZE; ++idx, ++dirtyIdx) {
- if ((_entries[idx].expire >= 0) || !_entries[idx].active)
- _owner._dirtyAreas[dirtyIdx].active = false;
- else {
- _owner._dirtyAreas[dirtyIdx].textActive = true;
- _owner._dirtyAreas.setTextDisplay(dirtyIdx, _entries[idx]);
- }
- }
-}
-
-void MadsTextDisplay::setDirtyAreas2() {
- // Determine dirty areas for active text areas
- for (uint idx = 0, dirtyIdx = DIRTY_AREAS_TEXT_DISPLAY_IDX; dirtyIdx < DIRTY_AREAS_SIZE; ++idx, ++dirtyIdx) {
- if (_entries[idx].active && (_entries[idx].expire >= 0)) {
- _owner._dirtyAreas.setTextDisplay(dirtyIdx, _entries[idx]);
- _owner._dirtyAreas[dirtyIdx].textActive = (_entries[idx].expire <= 0) ? 0 : 1;
- }
- }
-}
-
-void MadsTextDisplay::draw(M4Surface *view) {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if (_entries[idx].active && (_entries[idx].expire >= 0)) {
- _entries[idx].font->setColors(_entries[idx].color1, _entries[idx].color2, 0);
- _entries[idx].font->writeString(view, _entries[idx].msg,
- _entries[idx].bounds.left, _entries[idx].bounds.top, _entries[idx].bounds.width(),
- _entries[idx].spacing);
- }
- }
-}
-
-/**
- * Deactivates any text display entries that are finished
- */
-void MadsTextDisplay::cleanUp() {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if (_entries[idx].expire < 0) {
- _entries[idx].active = false;
- _entries[idx].expire = 0;
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-MadsKernelMessageList::MadsKernelMessageList(MadsView &owner): _owner(owner) {
- for (int i = 0; i < TIMED_TEXT_SIZE; ++i) {
- MadsKernelMessageEntry rec;
- _entries.push_back(rec);
- }
-
- _owner._textSpacing = -1;
- _talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS);
- word_8469E = 0;
-}
-
-void MadsKernelMessageList::clear() {
- for (uint i = 0; i < _entries.size(); ++i)
- _entries[i].flags = 0;
-
- _owner._textSpacing = -1;
- _talkFont = _vm->_font->getFont(FONT_CONVERSATION_MADS);
-}
-
-int MadsKernelMessageList::add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers, uint32 timeout, const char *msg) {
- // Find a free slot
- uint idx = 0;
- while ((idx < _entries.size()) && ((_entries[idx].flags & KMSG_ACTIVE) != 0))
- ++idx;
- if (idx == _entries.size()) {
- if (abortTimers == 0)
- return -1;
-
- error("MadsKernelList overflow");
- }
-
- MadsKernelMessageEntry &rec = _entries[idx];
- strcpy(rec.msg, msg);
- rec.flags = flags | KMSG_ACTIVE;
- rec.color1 = fontColor & 0xff;
- rec.color2 = fontColor >> 8;
- rec.position = pt;
- rec.textDisplayIndex = -1;
- rec.timeout = timeout;
- rec.frameTimer = _madsVm->_currentTimer;
- rec.abortTimers = abortTimers;
- rec.abortMode = _owner._abortTimersMode2;
-
- for (int i = 0; i < 3; ++i)
- rec.actionNouns[i] = _madsVm->globals()->actionNouns[i];
-
- if (flags & KMSG_PLAYER_TIMEOUT)
- rec.frameTimer = _madsVm->_player._ticksAmount + _madsVm->_player._priorTimer;
-
- return idx;
-}
-
-int MadsKernelMessageList::addQuote(int quoteId, int abortTimers, uint32 timeout) {
- const char *quoteStr = _madsVm->globals()->getQuote(quoteId);
- return add(Common::Point(0, 0), 0x1110, KMSG_PLAYER_TIMEOUT | KMSG_CENTER_ALIGN, abortTimers, timeout, quoteStr);
-}
-
-void MadsKernelMessageList::scrollMessage(int msgIndex, int numTicks, bool quoted) {
- if (msgIndex < 0)
- return;
-
- _entries[msgIndex].flags |= quoted ? (KMSG_SCROLL | KMSG_QUOTED) : KMSG_SCROLL;
- _entries[msgIndex].msgOffset = 0;
- _entries[msgIndex].numTicks = numTicks;
- _entries[msgIndex].frameTimer2 = _madsVm->_currentTimer;
-
- const char *msgP = _entries[msgIndex].msg;
- _entries[msgIndex].asciiChar = *msgP;
- _entries[msgIndex].asciiChar2 = *(msgP + 1);
-
- if (_entries[msgIndex].flags & KMSG_PLAYER_TIMEOUT)
- _entries[msgIndex].frameTimer2 = _madsVm->_player._ticksAmount + _madsVm->_player._priorTimer;
-
- _entries[msgIndex].frameTimer = _entries[msgIndex].frameTimer2;
-}
-
-void MadsKernelMessageList::setSeqIndex(int msgIndex, int seqIndex) {
- if (msgIndex >= 0) {
- _entries[msgIndex].flags |= KMSG_SEQ_ENTRY;
- _entries[msgIndex].sequenceIndex = seqIndex;
- }
-}
-
-void MadsKernelMessageList::remove(int msgIndex) {
- MadsKernelMessageEntry &rec = _entries[msgIndex];
-
- if (rec.flags & KMSG_ACTIVE) {
- if (rec.flags & KMSG_SCROLL) {
- *(rec.msg + rec.msgOffset) = rec.asciiChar;
- *(rec.msg + rec.msgOffset + 1) = rec.asciiChar2;
- }
-
- if (rec.textDisplayIndex >= 0)
- _owner._textDisplay.expire(rec.textDisplayIndex);
-
- rec.flags &= ~KMSG_ACTIVE;
- }
-}
-
-void MadsKernelMessageList::reset() {
- for (uint i = 0; i < _entries.size(); ++i)
- remove(i);
-
- // sub_20454
-}
-
-void MadsKernelMessageList::update() {
- uint32 currentTimer = _madsVm->_currentTimer;
-
- for (uint i = 0; i < _entries.size(); ++i) {
- if (((_entries[i].flags & KMSG_ACTIVE) != 0) && (currentTimer >= _entries[i].frameTimer))
- processText(i);
- }
-}
-
-void MadsKernelMessageList::processText(int msgIndex) {
- MadsKernelMessageEntry &msg = _entries[msgIndex];
- uint32 currentTimer = _madsVm->_currentTimer;
- bool flag = false;
-
- if ((msg.flags & KMSG_EXPIRE) != 0) {
- _owner._textDisplay.expire(msg.textDisplayIndex);
- msg.flags &= !KMSG_ACTIVE;
- return;
- }
-
- if ((msg.flags & KMSG_SCROLL) == 0) {
- msg.timeout -= 3;
- }
-
- if (msg.flags & KMSG_SEQ_ENTRY) {
- MadsSequenceEntry &seqEntry = _owner._sequenceList[msg.sequenceIndex];
- if (seqEntry.doneFlag || !seqEntry.active)
- msg.timeout = 0;
- }
-
- if ((msg.timeout <= 0) && (_owner._abortTimers == 0)) {
- msg.flags |= KMSG_EXPIRE;
- if (msg.abortTimers != 0) {
- _owner._abortTimers = msg.abortTimers;
- _owner._abortTimersMode = msg.abortMode;
-
- if (_owner._abortTimersMode != ABORTMODE_1) {
- for (int i = 0; i < 3; ++i)
- _madsVm->globals()->actionNouns[i] = msg.actionNouns[i];
- }
- }
- }
-
- msg.frameTimer = currentTimer + 3;
- int x1 = 0, y1 = 0;
-
- if (msg.flags & KMSG_SEQ_ENTRY) {
- MadsSequenceEntry &seqEntry = _owner._sequenceList[msg.sequenceIndex];
- if (!seqEntry.nonFixed) {
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame(seqEntry.frameIndex - 1);
- x1 = frame->bounds().left;
- y1 = frame->bounds().top;
- } else {
- x1 = seqEntry.msgPos.x;
- y1 = seqEntry.msgPos.y;
- }
- }
-
- if (msg.flags & KMSG_PLAYER_TIMEOUT) {
- if (word_8469E != 0) {
- // TODO: Figure out various flags
- } else {
- x1 = 160;
- y1 = 78;
- }
- }
-
- x1 += msg.position.x;
- y1 += msg.position.y;
-
- if ((msg.flags & KMSG_SCROLL) && (msg.frameTimer >= currentTimer)) {
- msg.msg[msg.msgOffset] = msg.asciiChar;
- char *msgP = &msg.msg[++msg.msgOffset];
- *msgP = msg.asciiChar2;
-
- msg.asciiChar = *msgP;
- msg.asciiChar2 = *(msgP + 1);
-
- if (!msg.asciiChar) {
- // End of message
- *msgP = '\0';
- msg.flags &= ~KMSG_SCROLL;
- } else if (msg.flags & KMSG_QUOTED) {
- *msgP = '"';
- *(msgP + 1) = '\0';
- }
-
- msg.frameTimer = msg.frameTimer2 = currentTimer + msg.numTicks;
- flag = true;
- }
-
- int strWidth = _talkFont->getWidth(msg.msg, _owner._textSpacing);
-
- if (msg.flags & (KMSG_RIGHT_ALIGN | KMSG_CENTER_ALIGN)) {
- x1 -= (msg.flags & KMSG_CENTER_ALIGN) ? strWidth / 2 : strWidth;
- }
-
- // Make sure text appears entirely on-screen
- int x2 = x1 + strWidth;
- if (x2 > MADS_SURFACE_WIDTH)
- x1 -= x2 - MADS_SURFACE_WIDTH;
- if (x1 > (MADS_SURFACE_WIDTH - 1))
- x1 = MADS_SURFACE_WIDTH - 1;
- if (x1 < 0)
- x1 = 0;
-
- if (y1 > (MADS_SURFACE_HEIGHT - 1))
- y1 = MADS_SURFACE_HEIGHT - 1;
- if (y1 < 0)
- y1 = 0;
-
- if (msg.textDisplayIndex >= 0) {
- MadsTextDisplayEntry textEntry = _owner._textDisplay[msg.textDisplayIndex];
-
- if (flag || (textEntry.bounds.left != x1) || (textEntry.bounds.top != y1)) {
- // Mark the associated text entry as deleted, so it can be re-created
- _owner._textDisplay.expire(msg.textDisplayIndex);
- msg.textDisplayIndex = -1;
- }
- }
-
- if (msg.textDisplayIndex < 0) {
- // Need to create a new text display entry for this message
- int idx = _owner._textDisplay.add(x1, y1, msg.color1 | (msg.color2 << 8), _owner._textSpacing, msg.msg, _talkFont);
- if (idx >= 0)
- msg.textDisplayIndex = idx;
- }
-}
-
-//--------------------------------------------------------------------------
-
-ScreenObjects::ScreenObjects(MadsView &owner): _owner(owner) {
- _v832EC = 0;
- _v7FECA = 0;
- _v7FED6 = 0;
- _v8332A = 0;
- _yp = 0;
- _v8333C = 0;
- _selectedObject = 0;
- _category = 0;
- _objectIndex = 0;
-}
-
-/**
- * Clears the entries list
- */
-void ScreenObjects::clear() {
- _entries.clear();
-}
-
-/**
- * Adds a new entry to the list of screen objects
- */
-void ScreenObjects::add(const Common::Rect &bounds, int layer, int idx, int category) {
- ScreenObjectEntry rec;
- rec.bounds = bounds;
- rec.layer = layer;
- rec.index = idx;
- rec.category = category;
- rec.active = true;
-
- _entries.push_back(rec);
-}
-
-/**
- * Scans the list for an element that contains the given mode. The result will be 1 based for a match,
- * with 0 indicating no entry was found
- */
-int ScreenObjects::scan(int xp, int yp, int layer) {
- for (uint i = 0; i < _entries.size(); ++i) {
- if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer))
- return i + 1;
- }
-
- // Entry not found
- return 0;
-}
-
-int ScreenObjects::scanBackwards(int xp, int yp, int layer) {
- for (int i = (int)_entries.size() - 1; i >= 0; --i) {
- if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer))
- return i + 1;
- }
-
- // Entry not found
- return 0;
-}
-
-void ScreenObjects::setActive(int category, int idx, bool active) {
- for (uint i = 0; i < _entries.size(); ++i) {
- if (_entries[i].active && (_entries[i].category == category) && (_entries[i].index == idx))
- _entries[i].active = active;
- }
-}
-
-void ScreenObjects::check(bool scanFlag, bool mouseClick) {
- if (!mouseClick || _v832EC)
- _v7FECA = 0;
-
- if (!_v7FED6 && !_v8332A && !_yp && (_v8333C != 0)) {
- if (scanFlag) {
- _category = CAT_NONE;
- _selectedObject = scanBackwards(_madsVm->_mouse->currentPos().x, _madsVm->_mouse->currentPos().y,
- LAYER_GUI);
-
- if (_selectedObject > 0) {
- ScreenObjectEntry &obj = _entries[_selectedObject];
- _category = obj.category & 7;
- _objectIndex = obj.index;
- }
-
- // TODO: Other stuff related to the user interface
- }
- }
-
- _owner._action.refresh();
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsDynamicHotspots::MadsDynamicHotspots(MadsView &owner): _owner(owner) {
- for (int i = 0; i < DYNAMIC_HOTSPOTS_SIZE; ++i) {
- DynamicHotspot rec;
- rec.active = false;
- _entries.push_back(rec);
- }
- _changed = true;
- _count = 0;
-}
-
-int MadsDynamicHotspots::add(int descId, int field14, int seqIndex, const Common::Rect &bounds) {
- // Find a free slot
- uint idx = 0;
- while ((idx < _entries.size()) && _entries[idx].active)
- ++idx;
- if (idx == _entries.size())
- error("MadsDynamicHotspots overflow");
-
- _entries[idx].active = true;
- _entries[idx].descId = descId;
- _entries[idx].seqIndex = seqIndex;
- _entries[idx].bounds = bounds;
- _entries[idx].pos.x = -3;
- _entries[idx].pos.y = 0;
- _entries[idx].facing = 5;
- _entries[idx].field_14 = field14;
- _entries[idx].articleNumber = 6;
- _entries[idx].field_17 = 0;
-
- ++_count;
- _changed = true;
-
- if (seqIndex >= 0)
- _owner._sequenceList[seqIndex].dynamicHotspotIndex = idx;
-
- return idx;
-}
-
-int MadsDynamicHotspots::setPosition(int index, int xp, int yp, int facing) {
- if (index >= 0) {
- _entries[index].pos.x = xp;
- _entries[index].pos.y = yp;
- _entries[index].facing = facing;
- }
-
- return index;
-}
-
-int MadsDynamicHotspots::set17(int index, int v) {
- if (index >= 0)
- _entries[index].field_17 = v;
-
- return index;
-}
-
-void MadsDynamicHotspots::remove(int index) {
- if (_entries[index].active) {
- if (_entries[index].seqIndex >= 0)
- _owner._sequenceList[_entries[index].seqIndex].dynamicHotspotIndex = -1;
- _entries[index].active = false;
-
- --_count;
- _changed = true;
- }
-}
-
-void MadsDynamicHotspots::reset() {
- for (uint i = 0; i < _entries.size(); ++i)
- _entries[i].active = false;
-
- _count = 0;
- _changed = false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-void MadsDirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) {
- if (bounds.left % 2) {
- --bounds.left;
- ++width;
- }
-
- if (bounds.left < 0)
- bounds.left = 0;
- else if (bounds.left > maxWidth)
- bounds.left = maxWidth;
- int right = bounds.left + width;
- if (right < 0)
- right = 0;
- if (right > maxWidth)
- right = maxWidth;
-
- bounds.right = right;
- bounds2.left = bounds.width() / 2;
- bounds2.right = bounds.left + (bounds.width() + 1) / 2 - 1;
-
- if (bounds.top < 0)
- bounds.top = 0;
- else if (bounds.top > maxHeight)
- bounds.top = maxHeight;
- int bottom = bounds.top + height;
- if (bottom < 0)
- bottom = 0;
- if (bottom > maxHeight)
- bottom = maxHeight;
-
- bounds.bottom = bottom;
- bounds2.top = bounds.height() / 2;
- bounds2.bottom = bounds.top + (bounds.height() + 1) / 2 - 1;
-
- active = true;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsDirtyAreas::MadsDirtyAreas(MadsView &owner): _owner(owner) {
- for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) {
- MadsDirtyArea rec;
- rec.active = false;
- _entries.push_back(rec);
- }
-}
-
-void MadsDirtyAreas::setSpriteSlot(int dirtyIdx, const MadsSpriteSlot &spriteSlot) {
- int width, height;
- MadsDirtyArea &dirtyArea = _entries[dirtyIdx];
-
- if (spriteSlot.spriteType == FULL_SCREEN_REFRESH) {
- // Special entry to refresh the entire screen
- dirtyArea.bounds.left = 0;
- dirtyArea.bounds.top = 0;
- width = MADS_SURFACE_WIDTH;
- height = MADS_SURFACE_HEIGHT;
- } else {
- // Standard sprite slots
- dirtyArea.bounds.left = spriteSlot.xp - _owner._posAdjust.x;
- dirtyArea.bounds.top = spriteSlot.yp - _owner._posAdjust.y;
-
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(spriteSlot.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame(((spriteSlot.frameNumber & 0x7fff) - 1) & 0x7f);
-
- if (spriteSlot.scale == -1) {
- width = frame->width();
- height = frame->height();
- } else {
- width = frame->width() * spriteSlot.scale / 100;
- height = frame->height() * spriteSlot.scale / 100;
-
- dirtyArea.bounds.left -= width / 2;
- dirtyArea.bounds.top += -(height - 1);
- }
- }
-
- dirtyArea.setArea(width, height, MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT);
-}
-
-void MadsDirtyAreas::setTextDisplay(int dirtyIdx, const MadsTextDisplayEntry &textDisplay) {
- MadsDirtyArea &dirtyArea = _entries[dirtyIdx];
- dirtyArea.bounds.left = textDisplay.bounds.left;
- dirtyArea.bounds.top = textDisplay.bounds.top;
-
- dirtyArea.setArea(textDisplay.bounds.width(), textDisplay.bounds.height(), MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT);
-}
-
-/**
- * Merge together any designated dirty areas that overlap
- * @param startIndex 1-based starting dirty area starting index
- * @param count Number of entries to process
- */
-void MadsDirtyAreas::merge(int startIndex, int count) {
-return;//***DEBUG***
- if (startIndex >= count)
- return;
-
- for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) {
- if (!_entries[outerCtr].active)
- continue;
-
- for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) {
- if (!_entries[innerCtr].active || !intersects(outerCtr, innerCtr))
- continue;
-
- if (_entries[outerCtr].textActive && _entries[innerCtr].textActive)
- mergeAreas(outerCtr, innerCtr);
- }
- }
-}
-
-/**
- * Returns true if two dirty areas intersect
- */
-bool MadsDirtyAreas::intersects(int idx1, int idx2) {
- return _entries[idx1].bounds2.intersects(_entries[idx2].bounds2);
-}
-
-void MadsDirtyAreas::mergeAreas(int idx1, int idx2) {
- MadsDirtyArea &da1 = _entries[idx1];
- MadsDirtyArea &da2 = _entries[idx2];
-
- da1.bounds.extend(da2.bounds);
-
- da1.bounds2.left = da1.bounds.width() / 2;
- da1.bounds2.right = da1.bounds.left + (da1.bounds.width() + 1) / 2 - 1;
- da1.bounds2.top = da1.bounds.height() / 2;
- da1.bounds2.bottom = da1.bounds.top + (da1.bounds.height() + 1) / 2 - 1;
-
- da2.active = false;
- da1.textActive = true;
-}
-
-void MadsDirtyAreas::copy(M4Surface *dest, M4Surface *src, const Common::Point &posAdjust) {
- for (uint i = 0; i < _entries.size(); ++i) {
- const Common::Rect &srcBounds = _entries[i].bounds;
-
- Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
- srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
-
- if (_entries[i].active && _entries[i].bounds.isValidRect())
- src->copyTo(dest, bounds, _entries[i].bounds.left, _entries[i].bounds.top);
- }
-}
-
-void MadsDirtyAreas::clear() {
- for (uint i = 0; i < _entries.size(); ++i)
- _entries[i].active = false;
-}
-
-/*--------------------------------------------------------------------------*/
-
-MadsSequenceList::MadsSequenceList(MadsView &owner): _owner(owner) {
- for (int i = 0; i < TIMER_LIST_SIZE; ++i) {
- MadsSequenceEntry rec;
- rec.active = 0;
- rec.dynamicHotspotIndex = -1;
- _entries.push_back(rec);
- }
-}
-
-void MadsSequenceList::clear() {
- for (uint i = 0; i < _entries.size(); ++i) {
- _entries[i].active = 0;
- _entries[i].dynamicHotspotIndex = -1;
- }
-}
-
-bool MadsSequenceList::addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal) {
- if (_entries[index].entries.count >= TIMER_ENTRY_SUBSET_MAX)
- return true;
-
- int subIndex = _entries[index].entries.count++;
- _entries[index].entries.mode[subIndex] = mode;
- _entries[index].entries.frameIndex[subIndex] = frameIndex;
- _entries[index].entries.abortVal[subIndex] = abortVal;
-
- return false;
-}
-
-int MadsSequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks,
- int msgX, int msgY, bool nonFixed, char scale, uint8 depth, int frameInc, SpriteAnimType animType, int numSprites,
- int frameStart) {
-
- // Find a free slot
- uint seqIndex = 0;
- while ((seqIndex < _entries.size()) && (_entries[seqIndex].active))
- ++seqIndex;
- if (seqIndex == _entries.size())
- error("TimerList full");
-
- if (frameStart <= 0)
- frameStart = 1;
- if (numSprites == 0)
- numSprites = _madsVm->scene()->_spriteSlots.getSprite(spriteListIndex).getCount();
- if (frameStart == numSprites)
- frameInc = 0;
-
- // Set the list entry fields
- _entries[seqIndex].active = true;
- _entries[seqIndex].spriteListIndex = spriteListIndex;
- _entries[seqIndex].flipped = flipped;
- _entries[seqIndex].frameIndex = frameIndex;
- _entries[seqIndex].frameStart = frameStart;
- _entries[seqIndex].numSprites = numSprites;
- _entries[seqIndex].animType = animType;
- _entries[seqIndex].frameInc = frameInc;
- _entries[seqIndex].depth = depth;
- _entries[seqIndex].scale = scale;
- _entries[seqIndex].nonFixed = nonFixed;
- _entries[seqIndex].msgPos.x = msgX;
- _entries[seqIndex].msgPos.y = msgY;
- _entries[seqIndex].numTicks = numTicks;
- _entries[seqIndex].extraTicks = extraTicks;
-
- _entries[seqIndex].timeout = _madsVm->_currentTimer + delayTicks;
-
- _entries[seqIndex].triggerCountdown = triggerCountdown;
- _entries[seqIndex].doneFlag = false;
- _entries[seqIndex].field_13 = 0;
- _entries[seqIndex].dynamicHotspotIndex = -1;
- _entries[seqIndex].entries.count = 0;
- _entries[seqIndex].abortMode = _owner._abortTimersMode2;
-
- for (int i = 0; i < 3; ++i)
- _entries[seqIndex].actionNouns[i] = _madsVm->globals()->actionNouns[i];
-
- return seqIndex;
-}
-
-void MadsSequenceList::remove(int seqIndex) {
- if (_entries[seqIndex].active) {
- if (_entries[seqIndex].dynamicHotspotIndex >= 0)
- _owner._dynamicHotspots.remove(_entries[seqIndex].dynamicHotspotIndex);
- }
-
- _entries[seqIndex].active = false;
- _owner._spriteSlots.deleteTimer(seqIndex);
-}
-
-void MadsSequenceList::setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot) {
- MadsSequenceEntry &timerEntry = _entries[seqIndex];
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(timerEntry.spriteListIndex);
-
- spriteSlot.spriteType = spriteSet.isBackground() ? BACKGROUND_SPRITE : FOREGROUND_SPRITE;
- spriteSlot.seqIndex = seqIndex;
- spriteSlot.spriteListIndex = timerEntry.spriteListIndex;
- spriteSlot.frameNumber = (timerEntry.flipped ? 0x8000 : 0) | timerEntry.frameIndex;
- spriteSlot.depth = timerEntry.depth;
- spriteSlot.scale = timerEntry.scale;
-
- if (!timerEntry.nonFixed) {
- spriteSlot.xp = timerEntry.msgPos.x;
- spriteSlot.yp = timerEntry.msgPos.y;
- } else {
- spriteSlot.xp = spriteSet.getFrame(timerEntry.frameIndex - 1)->x;
- spriteSlot.yp = spriteSet.getFrame(timerEntry.frameIndex - 1)->y;
- }
-}
-
-bool MadsSequenceList::loadSprites(int seqIndex) {
- MadsSequenceEntry &seqEntry = _entries[seqIndex];
- int slotIndex;
- bool result = false;
- int idx = -1;
-
- _owner._spriteSlots.deleteTimer(seqIndex);
- if (seqEntry.doneFlag) {
- remove(seqIndex);
- return false;
- }
-
- if (seqEntry.spriteListIndex == -1) {
- // Doesn't have an associated sprite anymore, so mark as done
- seqEntry.doneFlag = true;
- } else if ((slotIndex = _owner._spriteSlots.getIndex()) >= 0) {
- MadsSpriteSlot &spriteSlot = _owner._spriteSlots[slotIndex];
- setSpriteSlot(seqIndex, spriteSlot);
-
- int x2 = 0, y2 = 0;
-
- if ((seqEntry.field_13 != 0) || (seqEntry.dynamicHotspotIndex >= 0)) {
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex);
- M4Sprite *frame = spriteSet.getFrame(seqEntry.frameIndex - 1);
- int width = frame->width() * seqEntry.scale / 200;
- int height = frame->height() * seqEntry.scale / 100;
-
- warning("frame size %d x %d", width, height);
-
- // TODO: Missing stuff here, and I'm not certain about the dynamic hotspot stuff below
-
- if (seqEntry.dynamicHotspotIndex >= 0) {
- DynamicHotspot &dynHotspot = _owner._dynamicHotspots[seqEntry.dynamicHotspotIndex];
-
- dynHotspot.bounds.left = MAX(x2 - width, 0);
- dynHotspot.bounds.right = MAX(x2 - width, 319) - dynHotspot.bounds.left + 1;
- dynHotspot.bounds.top = MAX(y2 - height, 0);
- dynHotspot.bounds.bottom = MIN(y2, 155) - dynHotspot.bounds.top;
-
- _owner._dynamicHotspots._changed = true;
- }
- }
-
- // Frame adjustments
- if (seqEntry.frameStart != seqEntry.numSprites)
- seqEntry.frameIndex += seqEntry.frameInc;
-
- if (seqEntry.frameIndex >= seqEntry.frameStart) {
- if (seqEntry.frameIndex > seqEntry.numSprites) {
- result = true;
- if (seqEntry.animType == ANIMTYPE_CYCLED) {
- // Reset back to the starting frame (cyclic)
- seqEntry.frameIndex = seqEntry.frameStart;
- } else {
- // Switch into reverse mode
- seqEntry.frameIndex = seqEntry.numSprites - 1;
- seqEntry.frameInc = -1;
- }
- }
- } else {
- // Currently in reverse mode and moved past starting frame
- result = true;
-
- if (seqEntry.animType == ANIMTYPE_CYCLED)
- {
- // Switch back to forward direction again
- seqEntry.frameIndex = seqEntry.frameStart + 1;
- seqEntry.frameInc = 1;
- } else {
- // Otherwise reset back to last sprite for further reverse animating
- seqEntry.frameIndex = seqEntry.numSprites;
- }
- }
-
- if (result && (seqEntry.triggerCountdown != 0)) {
- if (--seqEntry.triggerCountdown == 0)
- seqEntry.doneFlag = true;
- }
- } else {
- // Out of sprite display slots, so mark entry as done
- seqEntry.doneFlag = true;
- }
-
- if (seqEntry.entries.count > 0) {
- for (int i = 0; i <= seqEntry.entries.count; ++i) {
- switch (seqEntry.entries.mode[i]) {
- case SM_0:
- case SM_1:
- if (((seqEntry.entries.mode[i] == SM_0) && seqEntry.doneFlag) ||
- ((seqEntry.entries.mode[i] == SM_1) && result))
- idx = i;
- break;
-
- case SM_FRAME_INDEX: {
- int v = seqEntry.entries.frameIndex[i];
- if ((v == seqEntry.frameIndex) || (v == 0))
- idx = i;
- }
-
- default:
- break;
- }
- }
- }
-
- if (idx >= 0) {
- _owner._abortTimers = seqEntry.entries.abortVal[idx];
- _owner._abortTimersMode = seqEntry.abortMode;
- }
-
- return result;
-}
-
-/**
- * Handles counting down entries in the timer list for action
- */
-void MadsSequenceList::tick() {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if ((_owner._abortTimers2 == 0) && (_owner._abortTimers != 0))
- break;
-
- MadsSequenceEntry &seqEntry = _entries[idx];
- uint32 currentTimer = _madsVm->_currentTimer;
-
- if (!seqEntry.active || (currentTimer < seqEntry.timeout))
- continue;
-
- // Set the next timeout for the timer entry
- seqEntry.timeout = currentTimer + seqEntry.numTicks;
-
- // Action the sprite
- if (loadSprites(idx)) {
- seqEntry.timeout += seqEntry.extraTicks;
- }
- }
-}
-
-void MadsSequenceList::delay(uint32 v1, uint32 v2) {
- for (uint idx = 0; idx < _entries.size(); ++idx) {
- if (_entries[idx].active) {
- _entries[idx].timeout += v1 - v2;
- }
- }
-}
-
-void MadsSequenceList::setAnimRange(int seqIndex, int startVal, int endVal) {
- MadsSequenceEntry &seqEntry = _entries[seqIndex];
- SpriteAsset &spriteSet = _owner._spriteSlots.getSprite(seqEntry.spriteListIndex);
- int numSprites = spriteSet.getCount();
- int tempStart = startVal, tempEnd = endVal;
-
- switch (startVal) {
- case -2:
- tempStart = numSprites;
- break;
- case -1:
- tempStart = 1;
- break;
- }
-
- switch (endVal) {
- case -2:
- case 0:
- tempEnd = numSprites;
- break;
- case -1:
- tempEnd = 1;
- break;
- default:
- tempEnd = numSprites;
- break;
- }
-
- seqEntry.frameStart = tempStart;
- seqEntry.numSprites = tempEnd;
-
- seqEntry.frameIndex = (seqEntry.frameInc < 0) ? tempStart : tempEnd;
-}
-
-void MadsSequenceList::scan() {
- for (uint i = 0; i < _entries.size(); ++i) {
- if (!_entries[i].active && (_entries[i].spriteListIndex != -1)) {
- int idx = _owner._spriteSlots.getIndex();
- setSpriteSlot(i, _owner._spriteSlots[idx]);
- }
- }
-}
-
-/**
- * Sets the depth of the specified entry in the sequence list
- */
-void MadsSequenceList::setDepth(int seqIndex, int depth) {
- _entries[seqIndex].depth = depth;
-}
-
-//--------------------------------------------------------------------------
-
-Animation::Animation(MadsM4Engine *vm): _vm(vm) {
-}
-
-Animation::~Animation() {
-}
-
-//--------------------------------------------------------------------------
-
-MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceList(*this),
- _kernelMessages(*this), _spriteSlots(*this), _dirtyAreas(*this), _textDisplay(*this),
- _screenObjects(*this), _action(*this) {
-
- _textSpacing = -1;
- _newTimeout = 0;
- _abortTimers = 0;
- _abortTimers2 = 0;
- _abortTimersMode = ABORTMODE_0;
- _abortTimersMode2 = ABORTMODE_0;
-
- _depthSurface = NULL;
- _bgSurface = NULL;
- _viewport = NULL;
- _sceneAnimation = new MadsAnimation(_vm, this);
-}
-
-MadsView::~MadsView() {
- delete _sceneAnimation;
- delete _viewport;
-}
-
-void MadsView::refresh() {
- if (!_viewport)
- setViewport(_view->bounds());
-
- // Draw any sprites
- _dirtyAreas.clear();
- _spriteSlots.drawBackground();
-
- // Process dirty areas
- _textDisplay.setDirtyAreas();
-
- // Merge any identified dirty areas
- _dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
-
- // Copy dirty areas to the main display surface
- _dirtyAreas.copy(_viewport, _bgSurface, _posAdjust);
-
- // Handle dirty areas for foreground objects
- _spriteSlots.setDirtyAreas();
- _textDisplay.setDirtyAreas2();
- _dirtyAreas.merge(1, DIRTY_AREAS_SIZE);
-
- // Draw foreground sprites
- _spriteSlots.drawForeground(_viewport);
-
- // Draw text elements onto the view
- _textDisplay.draw(_viewport);
-
- // Remove any sprite slots that are no longer needed
- _spriteSlots.cleanUp();
-
- // Deactivate any text display entries that are no longer needed
- _textDisplay.cleanUp();
-}
-
-void MadsView::update() {
- _sequenceList.tick();
- _kernelMessages.update();
-}
-
-void MadsView::clearLists() {
- _textDisplay.clear();
- _kernelMessages.clear();
- _spriteSlots.clear();
-}
-
-void MadsView::setViewport(const Common::Rect &bounds) {
- delete _viewport;
- _viewport = new M4Surface(bounds.width(), bounds.height(), _view->getBasePtr(bounds.left, bounds.top),
- _view->getPitch());
-}
-
-} // End of namespace M4
diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h
deleted file mode 100644
index 41caaa2ded..0000000000
--- a/engines/m4/mads_views.h
+++ /dev/null
@@ -1,494 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_MADS_VIEWS_H
-#define M4_MADS_VIEWS_H
-
-#include "m4/gui.h"
-#include "m4/viewmgr.h"
-#include "common/rect.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-namespace M4 {
-
-class MadsView;
-
-enum MadsActionMode {ACTMODE_NONE = 0, ACTMODE_VERB = 1, ACTMODE_OBJECT = 3, ACTMODE_TALK = 6};
-enum MadsActionMode2 {ACTMODE2_0 = 0, ACTMODE2_2 = 2, ACTMODE2_4 = 4, ACTMODE2_5 = 5};
-enum AbortTimerMode {ABORTMODE_0 = 0, ABORTMODE_1 = 1, ABORTMODE_2 = 2};
-
-struct ActionDetails {
- int verbId;
- int objectNameId;
- int indirectObjectId;
-};
-
-struct MadsActionSavedFields {
- int articleNumber;
- int actionMode;
- int actionMode2;
- bool lookFlag;
- int selectedRow;
-};
-
-class MadsAction {
-private:
- MadsView &_owner;
- char _statusText[100];
- char _dialogTitle[100];
-
- void appendVocab(int vocabId, bool capitalise = false);
-public:
- ActionDetails _action, _activeAction;
- int _currentAction;
- int8 _flags1, _flags2;
- MadsActionMode _actionMode;
- MadsActionMode2 _actionMode2;
- int _articleNumber;
- bool _lookFlag;
- int _selectedRow;
- bool _textChanged;
- int _selectedAction;
- bool _startWalkFlag;
- int _statusTextIndex;
- int _hotspotId;
- MadsActionSavedFields _savedFields;
- bool _walkFlag;
-
- // Unknown fields
- int16 _v86F3A;
- int16 _v86F42;
- int16 _v86F4E;
- bool _v86F4A;
- int16 _v86F4C;
- int _v83338;
- bool _inProgress;
- AbortTimerMode _v8453A;
-
-public:
- MadsAction(MadsView &owner);
-
- void clear();
- void set();
- const char *statusText() const { return _statusText; }
- void refresh();
- void startAction();
- void checkAction();
- bool isAction(int verbId, int objectNameId = 0, int indirectObjectId = 0);
-};
-
-class SpriteSlotSubset {
-public:
- int spriteListIndex;
- int frameNumber;
- int xp;
- int yp;
- int depth;
- int scale;
-};
-
-class MadsSpriteSlot {
-public:
- int spriteType;
- int seqIndex;
- int spriteListIndex;
- int frameNumber;
- int xp;
- int yp;
- int depth;
- int scale;
-
- MadsSpriteSlot() { }
-
- bool operator==(const SpriteSlotSubset &other) const;
- void copy(const SpriteSlotSubset &other);
-};
-
-#define SPRITE_SLOTS_SIZE 50
-
-enum SpriteIdSpecial {
- BACKGROUND_SPRITE = -4, FULL_SCREEN_REFRESH = -2, EXPIRED_SPRITE = -1, SPRITE_ZERO = 0, FOREGROUND_SPRITE = 1
-};
-
-class MadsSpriteSlots {
-private:
- MadsView &_owner;
- Common::Array<MadsSpriteSlot> _entries;
- Common::Array<SpriteAsset *> _sprites;
-public:
- int startIndex;
-
- MadsSpriteSlots(MadsView &owner);
- ~MadsSpriteSlots();
-
- MadsSpriteSlot &operator[](int idx) {
- assert(idx < SPRITE_SLOTS_SIZE);
- return _entries[idx];
- }
- SpriteAsset &getSprite(int idx) {
- assert(idx < (int)_sprites.size());
- return *_sprites[idx];
- }
-
- int getIndex();
- int addSprites(const char *resName, bool suppressErrors = false, int flags = 0);
- int addSprites(SpriteAsset *spriteSet);
- void deleteSprites(int listIndex);
- void clear();
- void deleteTimer(int seqIndex);
-
- void drawBackground();
- void drawForeground(M4Surface *viewport);
- void setDirtyAreas();
- void fullRefresh();
- void cleanUp();
-};
-
-class MadsTextDisplayEntry {
-public:
- bool active;
- int expire;
- int spacing;
- Common::Rect bounds;
- uint8 color1;
- uint8 color2;
- Font *font;
- const char *msg;
-
- MadsTextDisplayEntry() { active = false; }
-};
-
-#define TEXT_DISPLAY_SIZE 40
-
-class MadsTextDisplay {
-private:
- MadsView &_owner;
- Common::Array<MadsTextDisplayEntry> _entries;
-public:
- MadsTextDisplay(MadsView &owner);
-
- MadsTextDisplayEntry &operator[](int idx) {
- assert(idx < TEXT_DISPLAY_SIZE);
- return _entries[idx];
- }
-
- void expire(int idx) {
- assert(idx < TEXT_DISPLAY_SIZE);
- _entries[idx].expire = -1;
- }
-
- int add(int xp, int yp, uint fontColor, int charSpacing, const char *msg, Font *font);
- void clear();
- void draw(M4Surface *view);
- void setDirtyAreas();
- void setDirtyAreas2();
- void cleanUp();
-};
-
-#define TIMED_TEXT_SIZE 10
-#define INDEFINITE_TIMEOUT 9999999
-
-enum KernelMessageFlags {KMSG_QUOTED = 1, KMSG_PLAYER_TIMEOUT = 2, KMSG_SEQ_ENTRY = 4, KMSG_SCROLL = 8, KMSG_RIGHT_ALIGN = 0x10,
- KMSG_CENTER_ALIGN = 0x20, KMSG_EXPIRE = 0x40, KMSG_ACTIVE = 0x80};
-
-class MadsKernelMessageEntry {
-public:
- uint8 flags;
- int sequenceIndex;
- char asciiChar;
- char asciiChar2;
- int color1;
- int color2;
- Common::Point position;
- int textDisplayIndex;
- int msgOffset;
- int numTicks;
- uint32 frameTimer2;
- uint32 frameTimer;
- uint32 timeout;
- int abortTimers;
- AbortTimerMode abortMode;
- uint16 actionNouns[3];
- char msg[100];
-
- MadsKernelMessageEntry() {
- flags = 0;
- }
-};
-
-class MadsKernelMessageList {
-private:
- MadsView &_owner;
- Common::Array<MadsKernelMessageEntry> _entries;
- Font *_talkFont;
-public:
- int word_8469E;
-public:
- MadsKernelMessageList(MadsView &owner);
-
- void clear();
- int add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers, uint32 timeout, const char *msg);
- int addQuote(int quoteId, int abortTimers, uint32 timeout);
- void scrollMessage(int msgIndex, int numTicks, bool quoted);
- void setSeqIndex(int msgIndex, int seqIndex);
- void remove(int msgIndex);
- void reset();
- void update();
- void processText(int msgIndex);
-};
-
-class ScreenObjectEntry {
-public:
- Common::Rect bounds;
- int category;
- int index;
- int layer;
- bool active;
-
- ScreenObjectEntry() { active = false; }
-};
-
-class ScreenObjects {
-private:
- MadsView &_owner;
- Common::Array<ScreenObjectEntry> _entries;
-public:
- int _v832EC;
- int _v7FECA;
- int _v7FED6;
- int _v8332A;
- int _yp;
- int _v8333C;
- int _selectedObject;
- int _category;
- int _objectIndex;
-
- ScreenObjects(MadsView &owner);
- ScreenObjectEntry &operator[](uint idx) {
- assert(idx <= _entries.size());
- return _entries[idx - 1];
- }
-
- void clear();
- void add(const Common::Rect &bounds, int layer, int idx, int category);
- void draw(View *view);
- int scan(int xp, int yp, int layer);
- int scanBackwards(int xp, int yp, int layer);
- void setActive(int category, int idx, bool active);
- void check(bool scanFlag, bool mouseClick);
-};
-
-class DynamicHotspot {
-public:
- bool active;
- int seqIndex;
- Common::Rect bounds;
- Common::Point pos;
- int facing;
- int descId;
- int field_14;
- int articleNumber;
- int field_17;
-
- DynamicHotspot() { active = false; }
-};
-
-#define DYNAMIC_HOTSPOTS_SIZE 8
-
-class MadsDynamicHotspots {
-private:
- MadsView &_owner;
- Common::Array<DynamicHotspot> _entries;
- int _count;
-public:
- bool _changed;
-public:
- MadsDynamicHotspots(MadsView &owner);
-
- DynamicHotspot &operator[](uint idx) { return _entries[idx]; }
- int add(int descId, int field14, int seqIndex, const Common::Rect &bounds);
- int setPosition(int index, int xp, int yp, int facing);
- int set17(int index, int v);
- void remove(int index);
- void reset();
- void refresh() {
- // TODO
- }
-};
-
-class MadsDirtyArea {
-public:
- Common::Rect bounds;
- Common::Rect bounds2;
- bool textActive;
- bool active;
-
- MadsDirtyArea() { active = false; }
- void setArea(int width, int height, int maxWidth, int maxHeight);
-};
-
-#define DIRTY_AREAS_SIZE 90
-#define DIRTY_AREAS_TEXT_DISPLAY_IDX 50
-
-class MadsDirtyAreas {
-private:
- MadsView &_owner;
- Common::Array<MadsDirtyArea> _entries;
-public:
- MadsDirtyAreas(MadsView &owner);
-
- MadsDirtyArea &operator[](uint idx) {
- assert(idx < _entries.size());
- return _entries[idx];
- }
-
- void setSpriteSlot(int dirtyIdx, const MadsSpriteSlot &spriteSlot);
- void setTextDisplay(int dirtyIdx, const MadsTextDisplayEntry &textDisplay);
- void merge(int startIndex, int count);
- bool intersects(int idx1, int idx2);
- void mergeAreas(int idx1, int idx2);
- void copy(M4Surface *dest, M4Surface *src, const Common::Point &posAdjust);
- void clear();
-};
-
-enum SpriteAnimType {ANIMTYPE_CYCLED = 1, ANIMTYPE_REVERSIBLE = 2};
-
-enum SequenceSubEntryMode {SM_0 = 0, SM_1 = 1, SM_FRAME_INDEX = 2};
-
-#define TIMER_ENTRY_SUBSET_MAX 5
-
-struct MadsSequenceSubEntries {
- int count;
- SequenceSubEntryMode mode[TIMER_ENTRY_SUBSET_MAX];
- int16 frameIndex[TIMER_ENTRY_SUBSET_MAX];
- int8 abortVal[TIMER_ENTRY_SUBSET_MAX];
-};
-
-struct MadsSequenceEntry {
- int8 active;
- int8 spriteListIndex;
- bool flipped;
-
- int frameIndex;
- int frameStart;
- int numSprites;
-
- SpriteAnimType animType;
- int frameInc;
-
- int depth;
- int scale;
- int dynamicHotspotIndex;
-
- bool nonFixed;
- int field_13;
-
- Common::Point msgPos;
- int triggerCountdown;
- bool doneFlag;
- MadsSequenceSubEntries entries;
- AbortTimerMode abortMode;
-
- uint16 actionNouns[3];
- int numTicks;
- int extraTicks;
- uint32 timeout;
-};
-
-#define TIMER_LIST_SIZE 30
-
-class MadsSequenceList {
-private:
- MadsView &_owner;
- Common::Array<MadsSequenceEntry> _entries;
-public:
- MadsSequenceList(MadsView &owner);
-
- MadsSequenceEntry &operator[](int index) { return _entries[index]; }
- void clear();
- bool addSubEntry(int index, SequenceSubEntryMode mode, int frameIndex, int abortVal);
- int add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks,
- int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, char scale, uint8 depth,
- int frameInc, SpriteAnimType animType, int numSprites, int frameStart);
- void remove(int seqIndex);
- void setSpriteSlot(int seqIndex, MadsSpriteSlot &spriteSlot);
- bool loadSprites(int seqIndex);
- void tick();
- void delay(uint32 v1, uint32 v2);
- void setAnimRange(int seqIndex, int startVal, int endVal);
- void scan();
- void setDepth(int seqIndex, int depth);
-};
-
-class Animation {
-protected:
- MadsM4Engine *_vm;
-public:
- Animation(MadsM4Engine *vm);
- virtual ~Animation();
- virtual void initialize(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) = 0;
- virtual void load(const Common::String &filename, int v0) = 0;
- virtual void update() = 0;
- virtual void setCurrentFrame(int frameNumber) = 0;
- virtual int getCurrentFrame() = 0;
-};
-
-
-class MadsView {
-private:
- View *_view;
-public:
- Animation *_sceneAnimation;
- MadsSpriteSlots _spriteSlots;
- MadsTextDisplay _textDisplay;
- MadsKernelMessageList _kernelMessages;
- ScreenObjects _screenObjects;
- MadsDynamicHotspots _dynamicHotspots;
- MadsSequenceList _sequenceList;
- MadsDirtyAreas _dirtyAreas;
- MadsAction _action;
-
- int _textSpacing;
- uint32 _newTimeout;
- int _abortTimers;
- int8 _abortTimers2;
- AbortTimerMode _abortTimersMode;
- AbortTimerMode _abortTimersMode2;
- Common::Point _posAdjust;
-
- M4Surface *_depthSurface;
- M4Surface *_bgSurface;
- M4Surface *_viewport;
-public:
- MadsView(View *view);
- ~MadsView();
-
- void refresh();
- void update();
- void clearLists();
- void setViewport(const Common::Rect &bounds);
-};
-
-}
-
-#endif
diff --git a/engines/m4/midi.cpp b/engines/m4/midi.cpp
deleted file mode 100644
index bfe77828da..0000000000
--- a/engines/m4/midi.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// FIXME: This is cribbed together from the SAGA music player. It needs cleanup
-// and testing.
-
-#include "m4/m4.h"
-#include "m4/midi.h"
-#include "audio/midiparser.h"
-#include "common/config-manager.h"
-#include "common/memstream.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _isGM(false) {
-
- MidiPlayer::createDriver();
-
- int ret = _driver->open();
- if (ret == 0) {
- _driver->setTimerCallback(this, &timerCallback);
- }
-}
-
-void MidiPlayer::send(uint32 b) {
- if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
- b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
- }
-
- Audio::MidiPlayer::send(b);
-}
-
-void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene) {
- Common::StackLock lock(_mutex);
-
- stop();
-
- char fullname[144];
- _vm->res()->changeExtension(fullname, name, "HMP");
-
- Common::SeekableReadStream *midiFile = _vm->res()->get(fullname);
- byte *hmpData = new byte[midiFile->size()];
- uint32 smfSize;
-
- midiFile->read(hmpData, midiFile->size());
- _midiData = convertHMPtoSMF(hmpData, midiFile->size(), smfSize);
- delete[] hmpData;
- _vm->res()->toss(fullname);
- _vm->res()->purge();
-
- if (_midiData) {
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
-
- _parser->loadMusic(_midiData, smfSize);
- _parser->property(MidiParser::mpAutoLoop, loop);
- }
-
- setVolume(255);
-
- _isPlaying = true;
-}
-
-// This function will convert HMP music into type 1 SMF, which our SMF parser
-// will be able to handle. It is based on Hans de Goede's HMP 2 MIDI file
-// converter, which in turn is "based on the conversion algorithms found in
-// d1x, d2x-xl and jjffe". Hans's original code is licensed under the LGPL.
-//
-// TODO: It would probably be nicer to write a MIDI parser class to deal with
-// HMP data directly. Though the multi-track nature of HMP makes that tricky.
-
-byte *MidiPlayer::convertHMPtoSMF(byte *data, uint32 inSize, uint32 &outSize) {
- Common::MemoryReadStream readS(data, inSize);
- Common::MemoryWriteStreamDynamic writeS;
-
- byte buf[8];
-
- readS.read(buf, sizeof(buf));
- if (memcmp(buf, "HMIMIDIP", 8) != 0) {
- warning("convertHMPtoSMF: Invalid HMP header");
- return NULL;
- }
-
- // Read the number of tracks. Note that all the tracks are still part
- // of the same song, just like in type 1 SMF files.
-
- readS.seek(0x30);
-
- uint32 numTracks = readS.readUint32LE();
-
- // The first track starts on offset 0x300. It's currently unknown what
- // the skipped data is for.
-
- readS.seek(0x300);
-
- // For some reason, we skip the first track entirely.
-
- byte a = readS.readByte();
- byte b = readS.readByte();
- byte c = readS.readByte();
-
- while (a != 0xFF || b != 0x2F || c != 0x00) {
- a = b;
- b = c;
- c = readS.readByte();
- }
-
- // The beginning of the MIDI header
- static const byte midiHeader1[] = { 'M', 'T', 'h', 'd', 0, 0, 0, 6, 0, 1 };
- // The last 2 bytes of the midi header and track 0
- static const byte midiHeader2[] = { 0, 0xC0, 'M', 'T', 'r', 'k', 0, 0, 0, 0x0B, 0, 0xFF, 0x51, 0x03, 0x18, 0x80, 0, 0, 0xFF, 0x2F, 0 };
-
-
- // Write the MIDI header
- writeS.write(midiHeader1, sizeof(midiHeader1));
-
- // Write the number of tracks
- writeS.writeUint16BE(numTracks);
-
- // Write the rest of the MIDI header and track 0.
- writeS.write(midiHeader2, sizeof(midiHeader2));
-
- // Read and convert all the tracks
- for (uint i = 1; i < numTracks; i++) {
- if (readS.readUint32LE() != i) {
- warning("convertHMPtoSMF: Invalid HMP track number");
- delete[] writeS.getData();
- return NULL;
- }
-
- uint32 trackLength = readS.readUint32LE() - 12;
- readS.readUint32LE(); // Unused?
-
- // Write the track header
- writeS.write("MTrk", 4);
-
- // This is where we will write the length of the track.
- uint32 trackLengthPos = writeS.pos();
- writeS.writeUint32LE(0);
-
- // In the original, this is cleared once at the beginning of
- // the function, but surely the last command does not carry
- // over to the next track?
-
- byte lastCmd = 0;
-
- // Now we can finally convert the track
- int32 endPos = readS.pos() + trackLength;
- while (readS.pos() < endPos) {
- // Convert the VLQ
- byte vlq[4];
- int j = -1;
-
- do {
- j++;
- vlq[j] = readS.readByte();
- } while (!(vlq[j] & 0x80));
-
- for (int k = 0; k <= j; k++) {
- a = vlq[j - k] & 0x7F;
- if (k != j)
- a |= 0x80;
- writeS.writeByte(a);
- }
-
- a = readS.readByte();
-
- if (a == 0xFF) {
- // META event
- b = readS.readByte();
- c = readS.readByte();
-
- writeS.writeByte(a);
- writeS.writeByte(b);
- writeS.writeByte(c);
-
- if (c > 0) {
- byte *metaBuf = new byte[c];
- readS.read(metaBuf, c);
- writeS.write(metaBuf, c);
- delete[] metaBuf;
- }
-
- if (b == 0x2F) {
- if (c != 0x00) {
- warning("convertHMPtoSMF: End of track with non-zero size");
- delete[] writeS.getData();
- return NULL;
- }
- break;
- }
- } else {
- if (a != lastCmd)
- writeS.writeByte(a);
-
- switch (a & 0xF0) {
- case 0x80:
- case 0x90:
- case 0xA0:
- case 0xB0:
- case 0xE0:
- b = readS.readByte();
- c = readS.readByte();
- writeS.writeByte(b);
- writeS.writeByte(c);
- break;
- case 0xC0:
- case 0xD0:
- b = readS.readByte();
- writeS.writeByte(b);
- break;
- default:
- warning("convertHMPtoSMF: Invalid HMP command %02X", a);
- delete[] writeS.getData();
- return NULL;
- }
-
- lastCmd = a;
- }
- }
-
- if (readS.pos() != endPos) {
- warning("convertHMPtoSMF: Invalid track length");
- delete[] writeS.getData();
- return NULL;
- }
-
- WRITE_BE_UINT32(writeS.getData() + trackLengthPos, writeS.pos() - trackLengthPos - 4);
- }
-
- outSize = writeS.size();
- return writeS.getData();
-}
-
-} // End of namespace M4
diff --git a/engines/m4/midi.h b/engines/m4/midi.h
deleted file mode 100644
index 817150fd81..0000000000
--- a/engines/m4/midi.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// Music class
-
-#ifndef M4_MIDI_H
-#define M4_MIDI_H
-
-#include "audio/midiplayer.h"
-
-namespace M4 {
-
-class MidiPlayer : public Audio::MidiPlayer {
-public:
- MidiPlayer(MadsM4Engine *vm);
-
- void playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene);
-
- void setGM(bool isGM) { _isGM = isGM; }
-
- // MidiDriver_BASE interface implementation
- virtual void send(uint32 b);
-
-protected:
- MadsM4Engine *_vm;
-
- bool _isGM;
-
- bool _randomLoop;
-
- byte *_musicData;
- uint16 *_buf;
- size_t _musicDataSize;
-
- byte *convertHMPtoSMF(byte *data, uint32 inSize, uint32 &outSize);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/module.mk b/engines/m4/module.mk
deleted file mode 100644
index f60757ba3b..0000000000
--- a/engines/m4/module.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-MODULE := engines/m4
-
-MODULE_OBJS = \
- actor.o \
- animation.o \
- assets.o \
- compression.o \
- console.o \
- converse.o \
- detection.o \
- dialogs.o \
- events.o \
- font.o \
- globals.o \
- graphics.o \
- gui.o \
- hotspot.o \
- m4.o \
- m4_menus.o \
- m4_scene.o \
- m4_views.o \
- mads_anim.o \
- mads_logic.o \
- mads_menus.o \
- mads_player.o \
- mads_scene.o \
- mads_views.o \
- midi.o \
- rails.o \
- resource.o \
- saveload.o \
- scene.o \
- script.o \
- sound.o \
- sprite.o \
- staticres.o \
- viewmgr.o \
- woodscript.o \
- ws_machine.o \
- ws_sequence.o
-
-
-# This module can be built as a plugin
-ifeq ($(ENABLE_M4), DYNAMIC_PLUGIN)
-PLUGIN := 1
-endif
-
-# Include common rules
-include $(srcdir)/rules.mk
diff --git a/engines/m4/rails.cpp b/engines/m4/rails.cpp
deleted file mode 100644
index f51d81c8f4..0000000000
--- a/engines/m4/rails.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- TODO:
- - rewrite functions (GetShortestPath etc.)
-*/
-
-#include "graphics/primitives.h"
-#include "common/list.h"
-#include "common/rect.h"
-#include "common/util.h"
-
-#include "m4/rails.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-#define TOP_EDGE 1 << 0
-#define LEFT_EDGE 1 << 1
-#define BOTTOM_EDGE 1 << 2
-#define RIGHT_EDGE 1 << 3
-
-
-Rails::Rails() {
-}
-
-
-Rails::~Rails() {
- clearRails();
-}
-
-
-void Rails::clearRails() {
- uint32 i;
- Common::List<NoWalkRect *>::iterator j;
- RailNode *tempNode;
-
- for (i = 0; i < _nodes.size(); i++) {
- tempNode = _nodes[i];
- _nodes.remove_at(i);
- delete tempNode;
- }
-
- _edges.clear();
-
- for (j = _noWalkRects.begin(); j != _noWalkRects.end(); ++j)
- delete (*j);
- _noWalkRects.clear();
-}
-
-static void checkPoint(int x, int y, int color, void *data) {
- IsWalkableData *isWalkableData = (IsWalkableData*)data;
- if (!isWalkableData->result)
- return;
- else {
- M4Surface *codes = isWalkableData->codes;
- if (x >= 0 && x < codes->width() && y >= 0 && y < codes->height()) {
- isWalkableData->result = !((*((uint8*)codes->getBasePtr(x, y))) & 0x10);
- } else {
- isWalkableData->result = false;
- }
- }
-}
-
-bool Rails::isLineWalkable(int x0, int y0, int x1, int y1) {
- IsWalkableData isWalkableData;
- isWalkableData.codes = _walkCodes;
- isWalkableData.result = true;
- Graphics::drawLine(x0, y0, x1, y1, 0, &checkPoint, &isWalkableData);
- return isWalkableData.result;
-}
-
-uint8 Rails::getDepth(const Common::Point &pt) {
- // TODO: Check based on sceneResources
- const byte *b = _walkCodes->getBasePtr(pt.x, pt.y);
- return *b & 0xf;
-}
-
-// helper function
-uint8 getEndCode(int32 x, int32 y, Common::Rect rect) {
- uint8 endCode = 0;
- endCode = (x < rect.left) ? LEFT_EDGE : endCode;
- endCode = (x > rect.right) ? RIGHT_EDGE : endCode;
- endCode = (y < rect.top) ? endCode | TOP_EDGE : endCode;
- endCode = (y > rect.bottom) ? endCode | BOTTOM_EDGE : endCode;
- return endCode;
-}
-
-bool Rails::lineCrossesRect(int32 x1, int32 y1, int32 x2, int32 y2, Common::Rect rect) {
- int32 mX, mY;
- int32 pX1 = x1, pX2 = x2, pY1 = y1, pY2 = y2;
- uint8 endCode1, endCode2, midCode;
-
- if (rect.left > rect.right || rect.top > rect.bottom)
- return false;
-
- // Cohen-Sutherland line clipping algorithm
-
- endCode1 = getEndCode(pX1, pY1, rect);
- endCode2 = getEndCode(pX2, pY2, rect);
-
- if (!endCode1 || !endCode2) // if both endcodes are zero
- return true; // point is inside the rectangle, therefore the line intersects
-
- while (true) {
- if (endCode1 & endCode2) // if both endcodes have a common bitset
- return false; // line is completely off one edge
-
- // calculate midpoint
- mX = (pX1 + pX2)>>1;
- mY = (pY1 + pY2)>>1;
-
- // avoid round-off error: make sure that the midpoint isn't the same as one of the
- // two endpoints
- if (((mX == pX1) && (mY == pY1)) || ((mX == pX2) && (mY == pY2)))
- return false;
-
- midCode = getEndCode(mX, mY, rect);
-
- if (!midCode) {
- return true;
- } else if (midCode & endCode1) {
- // the midCode and an end point form a line segment completely off one edge, so
- // remove that half of the line segment
- pX1 = mX;
- pY1 = mY;
- endCode1 = midCode;
- } else {
- pX2 = mX;
- pY2 = mY;
- endCode2 = midCode;
- }
- }
-}
-
-
-bool Rails::linePassesThroughRect(int32 x1, int32 y1, int32 x2, int32 y2) {
- if (_noWalkRects.empty())
- return false;
-
- bool intersected = false;
- Common::List<NoWalkRect *>::iterator i;
-
- for (i = _noWalkRects.begin(); i != _noWalkRects.end(); ++i) {
- intersected = lineCrossesRect(x1, y1, x2, y2, Common::Rect((*i)->x1, (*i)->y1, (*i)->x2, (*i)->y2));
- if (intersected)
- break;
- }
-
- return intersected;
-}
-
-long SqrtF16(long n) {
- uint32 r = 0, s;
- uint32 v = (uint32)n;
-
- for (int i = 15; i >= 0; --i) {
- s = r + (1L << i * 2);
- r >>= 1;
- if (s <= v) {
- v -= s;
- r |= (1L << i * 2);
- }
- }
-
- return (long)r;
-}
-
-void Rails::createEdge(int32 node1, int32 node2) {
- uint32 index;
- int32 x1, y1, x2, y2;
- bool valid;
- long deltaX, deltaY, distance;
-
- if ((node1 < 0) || (node1 >= MAXRAILNODES) || (node2 < 0) || (node2 >= MAXRAILNODES))
- return;
-
- if (node1 == node2)
- return;
-
- if (node2 < node1)
- SWAP(node1, node2); // ensure node1 < node2
-
- // Find the table entry i.e. tableWidth * node1 + node2 and then subtract
- // n(n+1)/2, since only the upper triangle of the table is stored
- index = (MAXRAILNODES-1) * node1 + node2 - 1 - (node1*(node1+1)>>1);
- if (index > _edges.size() - 1)
- _edges.resize(index + 1);
- _edges.insert_at(index, 0);
- valid = true;
-
- if (_nodes.size() <= (uint32)node1 || _nodes.size() <= (uint32)node2)
- return;
-
- x1 = _nodes[node1]->x;
- y1 = _nodes[node1]->y;
- x2 = _nodes[node2]->x;
- y2 = _nodes[node2]->y;
-
- // Make sure that the algorithm is symmetric
- if (x2 < x1) {
- SWAP(x1, x2);
- SWAP(y1, y2);
- }
-
- valid = isLineWalkable(_nodes[node1]->x, _nodes[node1]->y,
- _nodes[node2]->x, _nodes[node2]->y);
- debugCN(kDebugCore, "test code says: %d\n", valid);
-
- // Check if the line passes through a forbidden rectangle
- if (valid) {
- if (linePassesThroughRect(x1, y1, x2, y2)) {
- valid = false;
- }
- }
-
- if (valid) {
- deltaX = ABS(((long)(x2 - x1)) << 16);
- deltaY = ABS(((long)(y2 - y1)) << 16);
- if ((deltaX >= 0x800000) || (deltaY >= 0x800000)) {
- deltaX >>= 16;
- deltaY >>= 16;
- distance = (long)(SqrtF16(deltaX * deltaX + deltaY * deltaY) << 16);
- } else {
- distance = SqrtF16(FixedMul(deltaX, deltaX) + FixedMul(deltaY, deltaY)) << 8;
- }
- _edges.insert_at(index, distance >> 16);
- }
-
- debugCN(kDebugCore, "node1 = %d, node2 = %d, valid = %d\n", node1, node2, valid);
-
-}
-
-
-void Rails::restoreNodeEdges(int32 nodeID) {
- for (int32 i = 0; i < MAXRAILNODES; i++) {
- createEdge(i, nodeID);
- }
-}
-
-void Rails::restoreEdgeList() {
- int32 j;
- for (int32 i = 0; i < MAXRAILNODES; i++) {
- for (j = i + 1; j < MAXRAILNODES; j++) {
- createEdge(i, j);
- }
- }
-}
-
-int32 Rails::addRailNode(int32 x, int32 y, bool restoreEdges) {
- uint32 i = _nodes.size();
- if (i >= MAXRAILNODES)
- return -1;
-
- RailNode *newNode = new RailNode();
- newNode->nodeID = i;
- newNode->x = x;
- newNode->y = y;
- _nodes.insert_at(i, newNode);
- if (restoreEdges) {
- for (uint32 j=0; j<_nodes.size(); j++)
- createEdge(i, j);
- }
- return i;
-}
-
-bool Rails::removeRailNode(int32 nodeID, bool restoreEdges) {
- if (nodeID < 0 || nodeID >= MAXRAILNODES)
- return false;
-
- if (_nodes.empty() || _edges.empty())
- return false;
-
- RailNode *tempNode = _nodes[nodeID];
- _nodes.remove_at(nodeID);
- delete tempNode;
-
- if (restoreEdges) {
- restoreNodeEdges(nodeID);
- }
- return true;
-}
-
-int16 Rails::getEdgeLength(int32 node1, int32 node2) {
- int32 index;
- if (_edges.empty() || node1 == node2)
- return 0;
- if (node2 < node1)
- SWAP(node1, node2);
- // Find the table entry i.e. tableWidth * node1 + node2 and then subtract
- // n(n+1)/2, since only the upper triangle of the table is stored
- index = (MAXRAILNODES-1)*node1 + node2 - 1 - (node1*(node1+1)>>1);
- return _edges[index];
-}
-
-void Rails::disposePath(RailNode *pathStart) {
- RailNode *tempNode = pathStart;
- while (tempNode) {
- pathStart = pathStart->shortPath;
- delete tempNode;
- tempNode = pathStart;
- }
-}
-
-/*
-static RailNode* duplicatePath(RailNode *pathStart) {
- RailNode *newNode = NULL;
- RailNode *firstNode = NULL;
- RailNode *prevNode = NULL;
- // A valid path is assumed
- RailNode *pathNode = pathStart;
-
- while (pathNode) {
- newNode = new RailNode();
- newNode->x = pathNode->x;
- newNode->y = pathNode->y;
- newNode->shortPath = NULL;
-
- if (!firstNode)
- firstNode = newNode;
- else
- prevNode->shortPath = newNode;
-
- prevNode = newNode;
- // Get the next node
- pathNode = pathNode->shortPath;
- }
-
- return firstNode;
-}
-*/
-
-bool Rails::getShortestPath(int32 origID, int32 destID, RailNode **shortPath) {
- // TODO
- return true;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/rails.h b/engines/m4/rails.h
deleted file mode 100644
index 80bb55e9de..0000000000
--- a/engines/m4/rails.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_RAILS_H
-#define M4_RAILS_H
-
-#include "m4/graphics.h"
-#include "common/list.h"
-#include "common/array.h"
-#include "common/rect.h"
-
-// TODO: This needs cleaning up
-
-namespace M4 {
-
-#define MAXRAILNODES 32
-#define PATH_END 0xffff
-
-struct RailNode {
- uint8 nodeID;
- int32 x, y;
- RailNode *shortPath;
- int32 pathWeight;
-};
-
-struct NoWalkRect {
- int32 x1, y1, x2, y2;
- int32 alternateWalkToNode;
- int32 walkAroundNode1;
- int32 walkAroundNode2;
- int32 walkAroundNode3;
- int32 walkAroundNode4;
-};
-
-struct PathNode {
- PathNode *next;
- int8 nodeID;
-};
-
-struct IsWalkableData {
- M4Surface *codes;
- bool result;
-};
-
-class Rails {
-public:
- Rails();
- ~Rails();
-
- void setCodeSurface(M4Surface *surface) { _walkCodes = surface; }
- void clearRails();
- int32 addRailNode(int32 x, int32 y, bool restoreEdges);
- uint8 getDepth(const Common::Point &pt);
-
-private:
- Common::Array<RailNode *> _nodes;
- Common::Array<int16> _edges;
- Common::List<NoWalkRect *> _noWalkRects;
- M4Surface *_walkCodes;
-
- bool lineCrossesRect(int32 x1, int32 y1, int32 x2, int32 y2, Common::Rect rect);
- bool linePassesThroughRect(int32 x1, int32 y1, int32 x2, int32 y2);
- void createEdge(int32 node1, int32 node2);
- bool removeRailNode(int32 nodeID, bool restoreEdges);
- int16 getEdgeLength(int32 node1, int32 node2);
-
- void restoreNodeEdges(int32 nodeID);
- void restoreEdgeList();
- void disposePath(RailNode *pathStart);
- bool getShortestPath(int32 origID, int32 destID, RailNode **shortPath);
- bool isLineWalkable(int x0, int y0, int x1, int y1);
-};
-
-long SqrtF16(long n);
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/resource.cpp b/engines/m4/resource.cpp
deleted file mode 100644
index f5b2050052..0000000000
--- a/engines/m4/resource.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/m4.h"
-#include "m4/resource.h"
-#include "m4/events.h"
-
-#include "common/substream.h"
-#include "common/textconsole.h"
-
-namespace M4 {
-
-FileSystem::FileSystem(const char *hashFilename) {
-
- for (int i = 0; i < 10; i++) {
- _hagEntries[i].filename[0] = '\0';
- _hagEntries[i].fileIndex = 0; // Was -1
- _hagEntries[i].hagFile = 0;
- }
-
- Common::File hashFile;
- uint32 hashSize;
-
- hashFile.open(hashFilename);
-
- if (!hashFile.isOpen()) {
- debugCN(kDebugCore, "FileSystem::FileSystem: error opening hash %s\n", hashFilename);
- }
-
- hashSize = hashFile.readUint32LE();
-
- //debugCN(kDebugCore, "FileSystem::FileSystem: hashSize = %d\n", hashSize);
-
- /* load file records and add them to the hash list */
- for (uint i = 0; i < hashSize; i++) {
- HashFileEntry entry;
- hashFile.read(entry.filename, kM4MaxFilenameSize);
- str_lower(entry.filename);
- entry.hagfile = hashFile.readByte();
- hashFile.readByte();
- entry.offset = hashFile.readUint32LE();
- entry.size = hashFile.readUint32LE();
- hashFile.readUint32LE();
-
- if (entry.filename[0]) {
- /*
- debugCN(kDebugCore, " filename: %s\n", entry.filename);
- debugCN(kDebugCore, " hagfile: %d\n", entry.hagfile);
- debugCN(kDebugCore, " disks: %d\n", entry.disks);
- debugCN(kDebugCore, " offset: %08X\n", entry.offset);
- debugCN(kDebugCore, " size: %d\n", entry.size);
- debugCN(kDebugCore, " next: %08X\n", entry.next);
- */
- _fileEntries[entry.filename] = entry;
- }
-
- }
-
- /* load hagfile records and update the list */
- while (!hashFile.eos()) {
- HashHagEntry entry;
- hashFile.read(entry.filename, kM4MaxFilenameSize);
- entry.fileIndex = hashFile.readByte();
- if (hashFile.eos())
- break;
-
- changeExtension(_hagEntries[entry.fileIndex].filename, entry.filename, "HAG");
- _hagEntries[entry.fileIndex].fileIndex = entry.fileIndex;
-
- _hagEntries[entry.fileIndex].hagFile = new Common::File();
- _hagEntries[entry.fileIndex].hagFile->open(_hagEntries[entry.fileIndex].filename);
-
- if (!_hagEntries[entry.fileIndex].hagFile->isOpen()) {
- debugCN(kDebugCore, "FileSystem::FileSystem: error opening hag %s\n", _hagEntries[entry.fileIndex].filename);
- }
-
- }
-
- hashFile.close();
-
-}
-
-FileSystem::~FileSystem() {
-
- for (int i = 0; i < 10; i++) {
- if (_hagEntries[i].hagFile)
- delete _hagEntries[i].hagFile;
- }
-
-}
-
-Common::SeekableReadStream *FileSystem::loadFile(const char *resourceName, bool preloadFlag) {
- const HashFileEntry *hfe = getHashFileEntry(resourceName);
- Common::SeekableReadStream *result = NULL;
-
- if (hfe) {
- //debugCN(kDebugCore, "FileSystem::loadFile() success opening %s\n", filename);
- HashHagEntry *hagEntry = &_hagEntries[hfe->hagfile];
-
- if (preloadFlag) {
- // Creates a MemoryReadStream object that contains all of the resource in memory
- hagEntry->hagFile->seek(hfe->offset);
- result = _hagEntries[hfe->hagfile].hagFile->readStream(hfe->size);
- }
- else
- // Creates a SeekableSubReadStream, which will read the data in from disk as the
- // caller reads in data
- result = new Common::SeekableSubReadStream(hagEntry->hagFile, hfe->offset,
- hfe->offset + hfe->size);
-
- } else {
- debugCN(kDebugCore, "FileSystem::loadFile() error opening %s\n", resourceName);
- }
-
- return result;
-}
-
-const FileSystem::HashFileEntry *FileSystem::getHashFileEntry(const char *filename) {
- char resourceName[20];
- strcpy(resourceName, filename);
- str_lower(resourceName);
-
- FileHashMap::const_iterator entry = _fileEntries.find(filename);
- if (entry != _fileEntries.end())
- return &(entry->_value);
- else
- return NULL;
-}
-
-void FileSystem::changeExtension(char *destName, const char *sourceName, const char *extension) {
- if (sourceName != destName)
- strcpy(destName, sourceName);
- char *dot = strrchr(destName, '.');
- if (dot != NULL)
- *dot = 0;
-
- strcat(destName, ".");
- strcat(destName, extension);
-
- str_upper(destName);
-}
-
-//--------------------------------------------------------------------------
-
-ResourceManager::~ResourceManager() {
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
- delete r->stream;
- }
-}
-
-Common::SeekableReadStream *ResourceManager::get(const char *resourceName, bool preloadFlag) {
- char lowerName[kM4MaxFilenameSize];
-
- strcpy(lowerName, resourceName);
- str_lower(lowerName);
-
- // Check whether the resource is already loaded
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
- if (!strcmp(r->name, resourceName)) {
- // Just in case resource was marked to be purged, reactive it again
- r->flags &= ~kResourcePurge;
-
- // Return the existing copy of the resource
- r->stream->seek(0, SEEK_SET);
- return r->stream;
- }
- }
-
- // the resource wasn't found in the list, load it from disk
- Resource *newRes = new Resource();
- strncpy(newRes->name, resourceName, 63);
- newRes->name[63] = '\0';
- newRes->flags = 0;
- newRes->stream = loadResource(resourceName, preloadFlag);
-
- _resources.push_back(ResourceList::value_type(newRes));
- return newRes->stream;
-}
-
-void ResourceManager::toss(const char *resourceName) {
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
-
- if (!strcmp(r->name, resourceName)) {
- r->flags |= kResourcePurge;
- //debugCN(kDebugCore, "M4ResourceManager::toss: mark resource %s to be purged\n", resourceName);
- }
- }
-}
-
-void ResourceManager::purge() {
- ResourceIterator i = _resources.begin();
- while (i != _resources.end()) {
- Resource *r = (*i).get();
-
- if (r->flags & kResourcePurge) {
- delete r->stream;
- i = _resources.erase(i);
- } else {
- ++i;
- }
- }
-}
-
-void ResourceManager::dump() {
- _vm->_events->getConsole()->DebugPrintf("Scene resources:\n");
-
- int index = 0;
- ResourceIterator i;
- for (i = _resources.begin(); i != _resources.end(); ++i) {
- Resource *r = (*i).get();
-
- if (!(r->flags & kResourcePurge)) {
- _vm->_events->getConsole()->DebugPrintf(
- "Resource #%i, name: %s, handle pointer: %p, size: %d, flags: %02X\n",
- index++, r->name, r->buffer, r->stream->size(), r->flags);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-const char *madsConcatString = "MADSCONCAT";
-
-ResourceType MADSResourceManager::getResourceType(const char *resourceName) {
- if (!strncmp(resourceName, "RM", 2)) {
- // Room resource
- return RESTYPE_ROOM;
- } else if (!strncmp(resourceName, "SC", 2)) {
- // SC resource
- return RESTYPE_SC;
- } else if (strstr(resourceName, ".TXT")) {
- // Text resource
- return RESTYPE_TEXT;
- } else if (strstr(resourceName, ".QUO")) {
- // QUO resource
- return RESTYPE_QUO;
- } else if (*resourceName == 'I') {
- // I resource
- return RESTYPE_I;
- } else if (!strncmp(resourceName, "OB", 2)) {
- // OB resource
- return RESTYPE_OB;
- } else if (!strncmp(resourceName, "FONT", 4)) {
- // FONT resource
- return RESTYPE_FONT;
- } else if (!strncmp(resourceName, "SOUND", 5)) {
- // SOUND resource
- return RESTYPE_SOUND;
- } else if (!strncmp(resourceName, "SPCHC", 5)) {
- // SPEECH resource
- return RESTYPE_SPEECH;
- }
-
- // Check for a known extension
- const char *extPos = strchr(resourceName, '.');
- if (extPos) {
- ++extPos;
- if (!strcmp(extPos, "FL") || !strcmp(extPos, "LBM") || !strcmp(extPos, "ANM") ||
- !strcmp(extPos, "AA") || !strcmp(extPos, "SS")) {
- return RESTYPE_HAS_EXT;
- }
- }
-
- return RESTYPE_NO_EXT;
-}
-
-const char *MADSResourceManager::getResourceFilename(const char *resourceName) {
- static char outputFilename[64];
-
- ResourceType resType = getResourceType(resourceName);
-
- strcpy(outputFilename, "GLOBAL.HAG");
-
- if ((resType == RESTYPE_ROOM) || (resType == RESTYPE_SC)) {
- int value = atoi(resourceName + 2);
- int hagFileNum = (resType == RESTYPE_ROOM) ? value / 100 : value;
-
- if (hagFileNum > 0)
- sprintf(outputFilename, "SECTION%d.HAG", hagFileNum);
- }
-
- if (resType == RESTYPE_SPEECH)
- strcpy(outputFilename, "SPEECH.HAG");
-
- return outputFilename;
-}
-
-/**
- * Forms a resource name based on the passed specifiers
- */
-const char *MADSResourceManager::getResourceName(char asciiCh, int prefix, ExtensionType extType,
- const char *suffix, int index) {
- static char resourceName[100];
-
- if (prefix <= 0)
- strcpy(resourceName, "*");
- else {
- if (prefix < 100)
- strcpy(resourceName, "*SC");
- else
- strcpy(resourceName, "*RM");
- sprintf(resourceName + 3, "%.3d", prefix);
- }
-
- // Append the specified ascii prefix character
- char asciiStr[2];
- asciiStr[0] = asciiCh;
- asciiStr[1] = '\0';
- strcat(resourceName, asciiStr);
-
- // Add in the index specified
- if (index >= 0)
- sprintf(resourceName + strlen(resourceName), "%d", index);
-
- // Add in any suffix
- if (suffix)
- strcat(resourceName, suffix);
-
- // Handle extension types
- switch (extType) {
- case EXTTYPE_SS:
- strcat(resourceName, ".SS");
- break;
- case EXTTYPE_AA:
- strcat(resourceName, ".AA");
- break;
- case EXTTYPE_DAT:
- strcat(resourceName, ".DAT");
- break;
- case EXTTYPE_HH:
- strcat(resourceName, ".HH");
- break;
- case EXTTYPE_ART:
- strcat(resourceName, ".ART");
- break;
- case EXTTYPE_INT:
- strcat(resourceName, ".INT");
- break;
- default:
- break;
- }
-
- return &resourceName[0];
-}
-
-/**
- * Another variation for forming resource names
- */
-const char *MADSResourceManager::getResourceName(ResourcePrefixType prefixType, int idx, const char *extension) {
- static char resourceName[100];
-
- strcpy(resourceName, "*");
-
- if (extension) {
- switch (prefixType) {
- case RESPREFIX_GL:
- strcat(resourceName, "GL000");
- break;
- case RESPREFIX_SC:
- case RESPREFIX_RM:
- strcat(resourceName, (prefixType == RESPREFIX_SC) ? "SC" : "RM");
- sprintf(resourceName + 3, "%.3d", idx);
- break;
- default:
- break;
- }
-
- strcat(resourceName, extension);
- }
-
- return &resourceName[0];
-}
-
-/**
- * Forms an AA resource name based on the given passed index
- */
-const char *MADSResourceManager::getAAName(int index) {
- return getResourceName('I', 0, EXTTYPE_AA, NULL, index);
-}
-
-Common::SeekableReadStream *MADSResourceManager::loadResource(const char *resourceName, bool loadFlag) {
- Common::File hagFile;
- uint32 offset = 0, size = 0;
-
- // If the first character is a '@' then look for an external file
-
- if (*resourceName == '@') {
- ++resourceName;
-
- hagFile.open(resourceName);
- if (loadFlag)
- return hagFile.readStream(hagFile.size());
- else
- return new Common::SeekableSubReadStream(&hagFile, 0, hagFile.size());
- }
-
- // If the first character is the wildcard (resource indicator), skip over it
- if (*resourceName == '*')
- ++resourceName;
-
- char resName[20];
- strcpy(resName, resourceName);
- str_upper(resName);
-
- hagFile.open(getResourceFilename(resName));
-
- // Validate hag file header
- char headerBuffer[16];
- if ((hagFile.read(headerBuffer, 16) != 16) || (strncmp(headerBuffer, madsConcatString, 10) != 0))
- error("Invalid HAG file opened");
-
- int numEntries = hagFile.readUint16LE();
-
- int resIndex = -1;
- while (++resIndex < numEntries) {
- // Read in the details of the next resource
- char resourceBuffer[14];
- offset = hagFile.readUint32LE();
- size = hagFile.readUint32LE();
- hagFile.read(resourceBuffer, 14);
-
- if (!strcmp(resName, resourceBuffer))
- break;
- }
-
- if (resIndex == numEntries)
- error("Invalid resource '%s' specified", resourceName);
-
- // Get the resource, either loading it in it's entirely or getting a stream reference
-
- if (loadFlag) {
- hagFile.seek(offset);
- return hagFile.readStream(size);
- } else {
- return new Common::SeekableSubReadStream(&hagFile, offset, offset + size);
- }
-}
-
-bool MADSResourceManager::resourceExists(const char *resourceName) {
- Common::File hagFile;
-
- // If the first character is the wildcard (resource indicator), skip over it
- if (*resourceName == '*')
- ++resourceName;
-
- char resName[20];
- strcpy(resName, resourceName);
- str_upper(resName);
-
- hagFile.open(getResourceFilename(resName));
-
- // Validate hag file header
- char headerBuffer[16];
- if ((hagFile.read(headerBuffer, 16) != 16) || (strncmp(headerBuffer, madsConcatString, 10) != 0))
- error("Invalid HAG file opened");
-
- int numEntries = hagFile.readUint16LE();
-
- int resIndex = -1;
- while (++resIndex < numEntries) {
- // Read in the details of the next resource
- char resourceBuffer[14];
- hagFile.readUint32LE(); // offset
- hagFile.readUint32LE(); // size
- hagFile.read(resourceBuffer, 14);
-
- if (!strcmp(resName, resourceBuffer))
- break;
- }
-
- if (resIndex == numEntries)
- return false;
- else
- return true;
-}
-
-//--------------------------------------------------------------------------
-
-M4ResourceManager::M4ResourceManager(MadsM4Engine *vm): ResourceManager(vm) {
- _hfs = new FileSystem(_vm->getGameFile(kFileTypeHash));
-}
-
-M4ResourceManager::~M4ResourceManager() {
-}
-
-Common::SeekableReadStream *M4ResourceManager::loadResource(const char *resourceName, bool preloadFlag) {
- //debugCN(kDebugCore, "M4ResourceManager::loadResource() loading resource %s\n", resourceName);
- Common::SeekableReadStream* result = NULL;
- if (_hfs) {
- // actually load the resource
- result = _hfs->loadFile(resourceName, preloadFlag);
- if (!result) {
- error("M4ResourceManager::loadResource() Resource %s not found", resourceName);
- }
- } else {
- error("M4ResourceManager::loadResource() No FileSystem attached");
- }
- return result;
-}
-
-bool M4ResourceManager::resourceExists(const char *resourceName) {
- return (_hfs->getHashFileEntry(resourceName) != NULL);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/resource.h b/engines/m4/resource.h
deleted file mode 100644
index c13c293544..0000000000
--- a/engines/m4/resource.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_RESOURCE_H
-#define M4_RESOURCE_H
-
-#include "common/scummsys.h"
-#include "common/stream.h"
-#include "common/endian.h"
-#include "common/file.h"
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-#include "common/list.h"
-#include "common/ptr.h"
-
-/*
- TODO:
- - change array to HashMap if it turns out to be slow
-*/
-
-namespace M4 {
-
-#define MAX_RESOURCES 128
-#define kM4MaxFilenameSize 33
-
-enum {
- kResourcePurge = 1 << 1
-};
-
-
-class FileSystem {
-public:
- struct HashHagEntry {
- char filename[kM4MaxFilenameSize];
- byte fileIndex;
- Common::File *hagFile;
- };
-
- struct HashFileEntry {
- char filename[kM4MaxFilenameSize];
- byte hagfile;
- uint32 offset, size;
- };
-
- FileSystem(const char *hashFilename);
- ~FileSystem();
-
- Common::SeekableReadStream *loadFile(const char *resourceName, bool preloadFlag);
- static void changeExtension(char *destName, const char *sourceName, const char *extension);
- const HashFileEntry *getHashFileEntry(const char *filename);
-
-private:
- typedef Common::HashMap<Common::String,HashFileEntry,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> FileHashMap;
-
- HashHagEntry _hagEntries[10]; // GLOBAL.HAG and SECTION1.HAG to SECTION9.HAG
- FileHashMap _fileEntries;
-};
-
-struct Resource {
- char name[64];
- Common::SeekableReadStream *stream;
- uint8 *buffer;
- uint8 flags;
-};
-
-class ResourceManager {
-protected:
- typedef Common::List<Common::SharedPtr<Resource> > ResourceList;
- typedef ResourceList::iterator ResourceIterator;
- ResourceList _resources;
- MadsM4Engine *_vm;
-
- virtual Common::SeekableReadStream *loadResource(const char *resourceName, bool loadFlag) = 0;
-public:
- ResourceManager(MadsM4Engine *vm): _vm(vm) {}
- virtual ~ResourceManager();
-
- Common::SeekableReadStream *get(const char *resourceName, bool loadFlag = true);
- void toss(const char *resourceName);
- void purge();
- void dump();
- virtual bool resourceExists(const char *resourceName) = 0;
-
- Common::SeekableReadStream *openFile(const char *resourceName) { return get(resourceName, false); }
- void changeExtension(char *destName, const char *sourceName, const char *extension) {
- FileSystem::changeExtension(destName, sourceName, extension);
- }
-};
-
-enum ResourceType {RESTYPE_ROOM, RESTYPE_SC, RESTYPE_TEXT, RESTYPE_QUO, RESTYPE_I,
- RESTYPE_OB, RESTYPE_FONT, RESTYPE_SOUND, RESTYPE_SPEECH, RESTYPE_HAS_EXT, RESTYPE_NO_EXT};
-
-enum ExtensionType {EXTTYPE_SS = 1, EXTTYPE_AA = 2, EXTTYPE_DAT = 3, EXTTYPE_HH = 4, EXTTYPE_ART = 5,
- EXTTYPE_INT = 6, EXTTYPE_NONE = -1};
-
-enum ResourcePrefixType {RESPREFIX_GL = 1, RESPREFIX_SC = 2, RESPREFIX_RM = 3};
-
-class MADSResourceManager : public ResourceManager {
-private:
- ResourceType getResourceType(const char *resourceName);
- const char *getResourceFilename(const char *resourceName);
-protected:
- Common::SeekableReadStream *loadResource(const char *resourceName, bool loadFlag);
-public:
- MADSResourceManager(MadsM4Engine *vm): ResourceManager(vm) {}
- bool resourceExists(const char *resourceName);
-
- static const char *getResourceName(char asciiCh, int prefix, ExtensionType extType, const char *suffix, int index);
- static const char *getResourceName(ResourcePrefixType prefixType, int idx, const char *extension);
- static const char *getAAName(int index);
-};
-
-class M4ResourceManager : public ResourceManager {
-protected:
- Common::SeekableReadStream *loadResource(const char *resourceName, bool loadFlag);
-public:
- M4ResourceManager(MadsM4Engine *vm);
- ~M4ResourceManager();
- bool resourceExists(const char *resourceName);
-
-private:
- FileSystem *_hfs;
-};
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/saveload.cpp b/engines/m4/saveload.cpp
deleted file mode 100644
index a7615fa4b6..0000000000
--- a/engines/m4/saveload.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/file.h"
-#include "common/savefile.h"
-
-#include "m4/m4.h"
-#include "m4/saveload.h"
-#include "m4/sprite.h"
-
-namespace M4 {
-
-const char *orionSavesList = "saves.dir";
-
-SaveLoad::SaveLoad(MadsM4Engine *vm) : _vm(vm) {
- // For Orion Burger, check the existance of a 'saves.dir' file to determine whether to
- // act exactly like the original. Otherwise, we'll use the ScummVM standard, where we'll
- // keep all the data for a savegame in a single file
-
- Common::File file;
- _emulateOriginal = file.exists(orionSavesList);
-}
-
-const char *SaveLoad::generateSaveName(int slotNumber) {
- static char buffer[15];
-
- sprintf(buffer, _emulateOriginal ? "burg%.3d.sav" : "burger.%.3d", slotNumber);
- return buffer;
-}
-
-bool SaveLoad::hasSaves() {
- // Return true if a savegame file exists for the first slot
-
- if (_emulateOriginal) {
- Common::File f;
- return f.exists(generateSaveName(1));
-
- } else {
- Common::ReadStream *f = _vm->saveManager()->openForLoading(generateSaveName(1));
- if (f == NULL)
- return false;
-
- delete f;
- return true;
- }
-}
-
-SaveGameList *SaveLoad::getSaves() {
- SaveGameList *result = new SaveGameList();
- char saveName[MAX_SAVEGAME_NAME];
- Common::ReadStream *f = NULL;
-
- if (_emulateOriginal) {
- Common::File *saveFile = new Common::File();
- saveFile->open(orionSavesList);
- f = saveFile;
- }
-
- for (int slotNumber = 1; slotNumber <= 99; ++slotNumber) {
- if (_emulateOriginal) {
- // Read in savegame name from save directory
- bool isPresent = (f->readByte() != 0);
- f->read(&saveName[0], MAX_SAVEGAME_NAME);
-
- if (isPresent)
- result->push_back(Common::String(saveName));
- else {
- result->push_back(Common::String());
- }
-
- } else {
- // Read in savegame name from savegame files directly
- Common::ReadStream *saveFile = _vm->saveManager()->openForLoading(
- generateSaveName(slotNumber));
- if (!saveFile) {
- // No savegame prsent at that slot
- result->push_back(Common::String());
- } else {
- // Skip over byte offset
- uint32 offset = saveFile->readUint32LE();
- assert(offset < 0x100);
-
- // Read in savegame name
- saveFile->read(&saveName[0], MAX_SAVEGAME_NAME);
- result->push_back(Common::String(saveName));
-
- delete saveFile;
- }
- }
- }
-
- if (_emulateOriginal)
- delete f;
-
- return result;
-}
-
-M4Surface *SaveLoad::getThumbnail(int slotNumber) {
- Common::SeekableReadStream *saveFile;
- uint32 dataOffset;
-
- if (_emulateOriginal) {
- // Get savegame file from original game folder
- Common::File *f = new Common::File();
- if (!f->open(generateSaveName(slotNumber))) {
- delete f;
- return NULL;
- }
-
- saveFile = f;
- } else {
- // Open up savegame for access via savefile manager
- saveFile = _vm->saveManager()->openForLoading(generateSaveName(slotNumber));
- }
- if (!saveFile)
- return NULL;
-
- dataOffset = saveFile->readUint32LE();
- assert(dataOffset < 0x100);
- saveFile->seek(dataOffset, SEEK_CUR);
-
- // Read in the sprite data
-
- saveFile->seek(16, SEEK_CUR);
- int width = saveFile->readUint32LE();
- int height = saveFile->readUint32LE();
- saveFile->seek(21, SEEK_CUR);
- saveFile->readUint32LE(); // sprite data size
-
- M4Sprite *result = new M4Sprite(saveFile, 0, 0, width, height);
- delete saveFile;
-
- return result;
-}
-
-bool SaveLoad::load(int slotNumber) {
- // TODO: Currently it's hardcoded to return a failure
- return false;
-}
-
-bool SaveLoad::save(int slotNumber, Common::String saveName) {
- // TODO: Currently it's hardcoded to return a failure
- return false;
-}
-
-
-} // End of namespace M4
diff --git a/engines/m4/saveload.h b/engines/m4/saveload.h
deleted file mode 100644
index 9b76054e65..0000000000
--- a/engines/m4/saveload.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_SAVELOAD_H
-#define M4_SAVELOAD_H
-
-#include "m4/graphics.h"
-#include "common/ptr.h"
-
-#define MAX_SAVEGAME_NAME 80
-
-namespace M4 {
-
-typedef Common::List<Common::String> SaveGameList;
-typedef SaveGameList::iterator SaveGameIterator;
-
-class SaveLoad {
-private:
- MadsM4Engine *_vm;
- bool _emulateOriginal;
-
- const char *generateSaveName(int slotNumber);
-public:
- SaveLoad(MadsM4Engine *vm);
-
- bool hasSaves();
- SaveGameList *getSaves();
- M4Surface *getThumbnail(int slotNumber);
- bool load(int slotNumber);
- bool save(int slotNumber, Common::String saveName);
-};
-
-}
-
-#endif
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
deleted file mode 100644
index be49dcb13f..0000000000
--- a/engines/m4/scene.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-
-#include "m4/dialogs.h"
-#include "m4/globals.h"
-#include "m4/scene.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-#include "m4/rails.h"
-#include "m4/font.h"
-#include "m4/m4_views.h"
-#include "m4/mads_views.h"
-#include "m4/compression.h"
-#include "m4/staticres.h"
-
-namespace M4 {
-
-Scene::Scene(MadsM4Engine *vm, SceneResources *res): View(vm, Common::Rect(0, 0, vm->_screen->width(),
- vm->_screen->height())), _sceneResources(res) {
- _screenType = VIEWID_SCENE;
-
- _sceneResources->hotspots = new HotSpotList();
- _sceneResources->dynamicHotspots = new HotSpotList();
- _backgroundSurface = new M4Surface();
- _walkSurface = new M4Surface();
- _palData = NULL;
- _interfacePal = NULL;
- _interfaceSurface = NULL;
- _vm->_rails->setCodeSurface(_walkSurface);
- _currentScene = -1;
-}
-
-Scene::~Scene() {
- leaveScene();
- _vm->_scene = NULL;
-}
-
-void Scene::loadScene(int sceneNumber) {
- _previousScene = _currentScene;
- _currentScene = sceneNumber;
- _nextScene = sceneNumber;
-}
-
-void Scene::leaveScene() {
- if (_palData) {
- _vm->_palette->deleteRange(_palData);
- delete _palData;
- _palData = NULL;
- }
- if (_interfacePal) {
- _vm->_palette->deleteRange(_interfacePal);
- delete _interfacePal;
- _interfacePal = NULL;
- }
-}
-
-void Scene::show() {
- _vm->_viewManager->addView(this);
-}
-
-void Scene::showInterface() {
- _vm->_viewManager->addView(_interfaceSurface);
-}
-
-void Scene::hideInterface() {
- _vm->_viewManager->deleteView(_interfaceSurface);
-}
-
-void Scene::showSprites() {
- // TODO: This is all experimental code, it needs heavy restructuring
- // and cleanup
-
- // taken from set_walker_scaling() in adv_walk.cpp. A proper implementation will need
- // to store these in global variables
- int minScaling = FixedDiv(_sceneResources->backScale << 16, 100 << 16);
- int maxScaling = FixedDiv(_sceneResources->frontScale << 16, 100 << 16);
- int scaler;
-
- _vm->_actor->setWalkerDirection(kFacingSouthEast);
- //_vm->_actor->setWalkerPalette();
-
- // taken from set_walker_scaling() in adv_walk.cpp
- if (_sceneResources->frontY == _sceneResources->backY)
- scaler = 0;
- else
- scaler = FixedDiv(maxScaling - minScaling,
- (_sceneResources->frontY << 16) - (_sceneResources->backY << 16));
-
- // FIXME: For now, we (incorrectly) scale the walker to 50% of the scene's max scaling
- _vm->_actor->setWalkerScaling(scaler / 2);
- // Test code to display the protagonist
- _vm->_actor->placeWalkerSpriteAt(0, 320, 200);
-
- // Test code to display scene sprites
- // TODO
-}
-
-// Test function, shows all scene hotspots
-void Scene::showHotSpots() {
- int i = 0;
- HotSpot *currentHotSpot;
-
- // hotspots (green)
- for (i = 0; i < _sceneResources->hotspots->size(); i++) {
- currentHotSpot = _sceneResources->hotspots->get(i);
- _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->GREEN);
- }
-
- // Dynamic hotspots (red)
- for (i = 0; i < _sceneResources->dynamicHotspots->size(); i++) {
- currentHotSpot = _sceneResources->dynamicHotspots->get(i);
- _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->RED);
- }
-}
-
-/**
- * Debug function that shows the walkable areas by copying them over the current background surface
- */
-void Scene::showCodes() {
- if (_vm->isM4()) {
- // Show the walk areas for the M4 engine in black and white
- const byte *srcP = (const byte *)_walkSurface->getBasePtr(0, 0);
- byte *destP = _backgroundSurface->getBasePtr(0, 0);
-
- for (int i = 0; i < _walkSurface->width() * _walkSurface->height(); i++)
- destP[i] = (srcP[i] & 0x10) ? 0xFF : 0;
-
- byte colors[256 * 3];
- memset(colors, 0, sizeof(colors));
- colors[255 * 3 + 0] = 255;
- colors[255 * 3 + 1] = 255;
- colors[255 * 3 + 2] = 255;
- _vm->_palette->setPalette(colors, 0, 256);
- } else {
- // MADS handling
-
- // copy the walk data to the background, in whatever current palette is active
- _walkSurface->copyTo(_backgroundSurface);
-
- // Show all the scene's walk nodes
- SceneNodeList &nodeList = _madsVm->scene()->getSceneResources()._nodes;
- _backgroundSurface->setColor(_madsVm->_palette->WHITE);
- for (uint i = 0; i < nodeList.size() - 2; ++i) {
- // Draw a little cross at the node's position
- _backgroundSurface->hLine(nodeList[i].pt.x - 2, nodeList[i].pt.x + 2, nodeList[i].pt.y);
- _backgroundSurface->vLine(nodeList[i].pt.x, nodeList[i].pt.y - 2, nodeList[i].pt.y + 2);
- }
-
- ((MadsScene *)this)->_spriteSlots.fullRefresh();
- }
-}
-
-void Scene::playIntro() {
-
-}
-
-void Scene::onRefresh(RectList *rects, M4Surface *destSurface) {
- update();
- View::onRefresh(rects, destSurface);
-}
-
-bool Scene::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) {
- //if (_vm->getGameType() != GType_Burger)
- // return false;
-
- // If the game is currently paused, don't do any scene processing
- if (_vm->_kernel->paused)
- return false;
-
- switch (eventType) {
- case MEVENT_LEFT_CLICK:
- leftClick(x, y);
- break;
- case MEVENT_RIGHT_CLICK:
- rightClick(x, y);
- break;
- case MEVENT_MOVE:
- mouseMove(x, y);
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/scene.h b/engines/m4/scene.h
deleted file mode 100644
index 5086cc0db0..0000000000
--- a/engines/m4/scene.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_SCENE_H
-#define M4_SCENE_H
-
-class View;
-
-#include "m4/assets.h"
-#include "m4/font.h"
-#include "m4/hotspot.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-#include "m4/gui.h"
-#include "m4/m4_views.h"
-#include "common/array.h"
-
-namespace M4 {
-
-#define MAX_CHK_FILENAME_SIZE 144
-
-enum MADSVerbs {
- kVerbNone = 0,
- kVerbLook = 3,
- kVerbTake = 4,
- kVerbPush = 5,
- kVerbOpen = 6,
- kVerbPut = 7,
- kVerbTalkTo = 8,
- kVerbGive = 9,
- kVerbPull = 10,
- kVerbClose = 11,
- kVerbThrow = 12,
- kVerbWalkTo = 13,
- kVerbLookAt = 209
-};
-
-class SceneResources {
-public:
- char artBase[MAX_CHK_FILENAME_SIZE];
- char pictureBase[MAX_CHK_FILENAME_SIZE];
- HotSpotList *hotspots;
- HotSpotList *dynamicHotspots;
- int32 frontY, backY;
- int32 frontScale, backScale;
- int16 depthTable[16];
- int32 railNodeCount; // # of rails
-};
-
-class M4Engine;
-class MadsEngine;
-class InterfaceView;
-
-class Scene : public View {
-private:
- HotSpotList _sceneHotspots;
-protected:
- GameInterfaceView *_interfaceSurface;
- M4Surface *_backgroundSurface;
- M4Surface *_walkSurface;
- RGBList *_palData;
- RGBList *_interfacePal;
- SceneResources *_sceneResources;
-public:
- int _currentScene;
- int _previousScene;
- int _nextScene;
-public:
- Scene(MadsM4Engine *vm, SceneResources *res);
- virtual ~Scene();
-
- // Methods that differ between engines
- virtual void loadScene(int sceneNumber);
- virtual void leaveScene();
- virtual void loadSceneCodes(int sceneNumber, int index = 0) = 0;
- virtual void show();
- virtual void mouseMove(int x, int y) = 0;
- virtual void leftClick(int x, int y) = 0;
- virtual void rightClick(int x, int y) = 0;
- virtual void update() = 0;
- virtual void showHotSpots();
-
- // TODO: perhaps move playIntro() someplace else?
- void playIntro();
- void showSprites();
- void showCodes();
- int getCurrentScene() { return _currentScene; }
- M4Surface *getBackgroundSurface() const { return _backgroundSurface; }
- void showInterface();
- void hideInterface();
- GameInterfaceView *getInterface() { return _interfaceSurface; }
- SceneResources &getSceneResources() { return *_sceneResources; }
- M4Surface *getWalkSurface() const { return _walkSurface; }
-
- void onRefresh(RectList *rects, M4Surface *destSurface);
- bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents);
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/script.cpp b/engines/m4/script.cpp
deleted file mode 100644
index 026c025f45..0000000000
--- a/engines/m4/script.cpp
+++ /dev/null
@@ -1,1389 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/system.h"
-#include "common/textconsole.h"
-
-#include "m4/m4.h"
-#include "m4/script.h"
-#include "m4/resource.h"
-
-namespace M4 {
-
-enum OpcodeType {
- opRet = 0,
- opCall,
- opCallKernel,
- opPush,
- opPush0,
- opPush1,
- opPushNeg1,
- opPop,
- opMov,
- opAdd,
- opSub,
- opInc,
- opDec,
- opCmp,
- opJmp,
- opJmpByTable,
- opJz,
- opJnz,
- opJe,
- opJne,
- opJl,
- opJle,
- opJg,
- opJge,
- opXor,
- opShl,
- opShr,
-
- opDebug,
-
- opInvalid
-};
-
-const char *opcodeNames[] = {
- "opRet",
- "opCall",
- "opCallKernel",
- "opPush",
- "opPush0",
- "opPush1",
- "opPushNeg1",
- "opPop",
- "opMov",
- "opAdd",
- "opSub",
- "opInc",
- "opDec",
- "opCmp",
- "opJmp",
- "opJmpByTable",
- "opJz",
- "opJnz",
- "opJe",
- "opJne",
- "opJl",
- "opJle",
- "opJg",
- "opJge",
- "opXor",
- "opShl",
- "opShr",
- "opDebug",
- "opInvalid"
-};
-
-StringTable::StringTable() : _stringsData(NULL) {
-}
-
-StringTable::~StringTable() {
- delete[] _stringsData;
-}
-
-void StringTable::load(Common::File *fd) {
- int stringSize = fd->readUint32LE();
- int stringCount = fd->readUint32LE();
- _stringsData = new char[stringSize];
- fd->read(_stringsData, stringSize);
- char *stringPtr = _stringsData;
- for (int i = 0; i < stringCount; i++) {
- _strings.push_back((const char*)stringPtr);
- stringPtr += strlen(stringPtr) + 1;
- }
-}
-
-SeriesStreamBreakList::~SeriesStreamBreakList() {
-}
-
-void SeriesStreamBreakList::load(Common::File *fd) {
- uint32 count = fd->readUint32LE();
- debugCN(kDebugScript, "SeriesStreamBreakList::load() count = %d\n", count);
- for (uint32 i = 0; i < count; i++) {
- SeriesStreamBreakItem *item = new SeriesStreamBreakItem();
- item->frameNum = fd->readUint32LE();
- item->digiName = _inter->loadGlobalString(fd);
- item->digiChannel = fd->readUint32LE();
- item->digiVolume = fd->readUint32LE();
- item->trigger = fd->readUint32LE();
- item->flags = fd->readUint32LE();
- item->variable.type = kGameVar;
- item->variable.value = fd->readUint32LE();
- item->value = fd->readUint32LE();
- _items.push_back(item);
-
- debugCN(kDebugScript, "%02d: frameNum = %d; digiName = %s; digiChannel = %d; digiVolume = %d; trigger = %d; flags = %d; variable = %d; value = %d\n",
- i, item->frameNum, item->digiName, item->digiChannel, item->digiVolume, item->trigger, item->flags, item->variable.value, item->value);
-
- }
-}
-
-SaidArray::~SaidArray() {
-}
-
-void SaidArray::load(Common::File *fd) {
- uint32 count = fd->readUint32LE();
- debugCN(kDebugScript, "SaidArray::load() count = %d\n", count);
- for (uint32 i = 0; i < count; i++) {
- SaidArrayItem *item = new SaidArrayItem();
- item->itemName = _inter->loadGlobalString(fd);
- item->digiNameLook = _inter->loadGlobalString(fd);
- item->digiNameTake = _inter->loadGlobalString(fd);
- item->digiNameGear = _inter->loadGlobalString(fd);
- _items.push_back(item);
-
- debugCN(kDebugScript, "itemName = %s; digiNameLook = %s; digiNameTake = %s; digiNameGear = %s\n",
- item->itemName, item->digiNameLook, item->digiNameTake, item->digiNameGear);
-
- }
-}
-
-ParserArray::~ParserArray() {
-}
-
-void ParserArray::load(Common::File *fd) {
- uint32 count = fd->readUint32LE();
- debugCN(kDebugScript, "ParserArray::load() count = %d\n", count);
- for (uint32 i = 0; i < count; i++) {
- ParserArrayItem *item = new ParserArrayItem();
- item->w0 = _inter->loadGlobalString(fd);
- item->w1 = _inter->loadGlobalString(fd);
- item->trigger = fd->readUint32LE();
- item->testVariable.type = kGameVar;
- item->testVariable.value = fd->readUint32LE();
- item->testValue = fd->readUint32LE();
- item->variable.type = kGameVar;
- item->variable.value = fd->readUint32LE();
- item->value = fd->readUint32LE();
- _items.push_back(item);
-
- debugCN(kDebugScript, "w0 = %s; w1 = %s; trigger = %d; testVariable = %d; testValue = %d; variable = %d; value = %d\n",
- item->w0, item->w1, item->trigger, item->testVariable.value, item->testValue, item->variable.value, item->value);
-
- }
-}
-
-ScriptFunction::ScriptFunction(ScriptInterpreter *inter) : _inter(inter) {
-}
-
-ScriptFunction::~ScriptFunction() {
- delete _code;
-}
-
-void ScriptFunction::load(Common::File *fd) {
- debugCN(kDebugScript, "ScriptFunction::load()\n");
- uint32 size = fd->readUint32LE();
- debugCN(kDebugScript, "ScriptFunction::load() size = %d\n", size);
- _code = fd->readStream(size);
-}
-
-void ScriptFunction::jumpAbsolute(uint32 ofs) {
- _code->seek(ofs);
-}
-
-void ScriptFunction::jumpRelative(int32 ofs) {
- _code->seek(ofs, SEEK_CUR);
-}
-
-byte ScriptFunction::readByte() {
- return _code->readByte();
-}
-
-uint32 ScriptFunction::readUint32() {
- return _code->readUint32LE();
-}
-
-
-ScriptInterpreter::ScriptInterpreter(MadsM4Engine *vm) : _scriptFile(NULL), _vm(vm) {
- initScriptKernel();
- _dataCache = new ScriptDataCache(this);
- _runningFunction = NULL;
-}
-
-ScriptInterpreter::~ScriptInterpreter() {
- close();
- delete _dataCache;
-}
-
-void ScriptInterpreter::open(const char *filename) {
- if (_scriptFile)
- close();
- _scriptFile = new Common::File();
- _scriptFile->open(filename);
- if (!_scriptFile->isOpen())
- error("ScriptInterpreter::open() Error opening %s", filename);
-
- _scriptFile->readUint32LE(); // skip magic for now
- uint32 version = _scriptFile->readUint32LE();
- if (version != kScriptFileVersion) {
- error("ScriptInterpreter::open() DAT file version mismatch; requested %li, got %i", kScriptFileVersion, version);
- }
-
- int functionCount = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "functionCount = %d\n", functionCount);
- for (int i = 0; i < functionCount; i++) {
- uint32 offset = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "func(%d) offset = %08X\n", i, offset);
- uint32 len = _scriptFile->readUint32LE();
- if (len > 0) {
- char *funcName = new char[len + 1];
- _scriptFile->read(funcName, len);
- funcName[len] = '\0';
- debugCN(kDebugScript, "func(%d) name = %s\n", i, funcName);
- _functionNames[Common::String(funcName)] = _functions.size();
- // DEBUG
- _scriptFunctionNames.push_back(Common::String(funcName));
- delete[] funcName;
- }
- _functions.push_back(new ScriptFunctionEntry(offset));
- }
-
- int dataCount = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "dataCount = %d\n", dataCount);
- for (int i = 0; i < dataCount; i++) {
- uint32 offset = _scriptFile->readUint32LE();
- ScriptDataType type = (ScriptDataType)_scriptFile->readUint32LE();
- debugCN(kDebugScript, "data(%d) offset = %08X; type = %d\n", i, offset, type);
- _data.push_back(new ScriptDataEntry(offset, type));
- }
-
- _globalVarCount = _scriptFile->readUint32LE();
- debugCN(kDebugScript, "_globalVarCount = %d\n", _globalVarCount);
-
- uint32 stringOfs = _scriptFile->readUint32LE();
- _scriptFile->seek(stringOfs);
- _constStrings.load(_scriptFile);
-
- for (int i = 0; i < ARRAYSIZE(_globalVars); i++) {
- _globalVars[i].type = kInteger;
- _globalVars[i].value = 0;
- }
-
- memset(_logicGlobals, 0, sizeof(_logicGlobals));
-
- memset(_registers, 0, sizeof(_registers));
- memset(_stack, 0, sizeof(_stack));
- _stackPtr = 0;
-
-}
-
-void ScriptInterpreter::close() {
- delete _scriptFile;
-}
-
-void ScriptInterpreter::initScriptKernel() {
-
-#include "m4/scripttab.h"
-
- _kernelFunctions = kernelFunctions;
- _kernelFunctionsMax = ARRAYSIZE(kernelFunctions) + 1;
-
- _kernelVars = kernelVars;
- _kernelVarsMax = ARRAYSIZE(kernelVars) + 1;
-
-}
-
-
-ScriptFunction *ScriptInterpreter::loadFunction(uint32 index) {
- //GONE WHILE DEBUGGING assert(index < _functions.size());
- if (index >= _functions.size()) return NULL;
- ScriptFunction *scriptFunction;
- scriptFunction = _functions[index]->func;
- if (!scriptFunction) {
- scriptFunction = new ScriptFunction(this);
- _scriptFile->seek(_functions[index]->offset);
- scriptFunction->load(_scriptFile);
- _functions[index]->func = scriptFunction;
- }
- return scriptFunction;
-}
-
-ScriptFunction *ScriptInterpreter::loadFunction(const Common::String &name) {
- FunctionNameMap::iterator iter = _functionNames.find(name);
- if (iter == _functionNames.end()) {
- debugCN(kDebugScript, "ScriptInterpreter::loadFunction() Function '%s' not found!\n", name.c_str());
- return NULL;
- }
- uint32 funcIndex = (*iter)._value;
- debugCN(kDebugScript, "ScriptInterpreter::loadFunction() index('%s') = %d\n", name.c_str(), funcIndex);
- return loadFunction(funcIndex);
-}
-
-void ScriptInterpreter::unloadFunctions() {
- for (uint32 i = 0; i < _functions.size(); i++) {
- if (_functions[i]->func) {
- delete _functions[i]->func;
- _functions[i]->func = NULL;
- }
- }
-}
-
-int ScriptInterpreter::runFunction(ScriptFunction *scriptFunction) {
- bool done = false;
-
- int oldLocalStackPtr = _localStackPtr;
- ScriptFunction *oldRunningFunction = _runningFunction;
-
- // TODO: Also initialize _localStackPtr
-
- _runningFunction = scriptFunction;
- _runningFunction->jumpAbsolute(0);
- while (!done) {
- byte opcode = _runningFunction->readByte();
- done = !execOpcode(opcode);
- }
-
- _localStackPtr = oldLocalStackPtr;
- _runningFunction = oldRunningFunction;
-
- return 0;
-}
-
-void ScriptInterpreter::push(const ScriptValue &value) {
- if (_stackPtr == ARRAYSIZE(_stack))
- error("ScriptInterpreter::push() Stack overflow");
- _stack[_stackPtr++] = value;
-}
-
-void ScriptInterpreter::pop(ScriptValue &value) {
- if (_stackPtr == 0)
- error("ScriptInterpreter::pop() Stack underflow");
- value = _stack[_stackPtr--];
-}
-
-void ScriptInterpreter::dumpStack() {
- debugCN(kDebugScript, "ScriptInterpreter::dumpStack()\n");
- for (int i = 0; i < _stackPtr; i++) {
- debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _stack[i].type, _stack[i].value);
- }
-}
-
-void ScriptInterpreter::dumpRegisters() {
- debugCN(kDebugScript, "ScriptInterpreter::dumpRegisters()\n");
- for (int i = 0; i < ARRAYSIZE(_registers); i++) {
- debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _registers[i].type, _registers[i].value);
- }
-}
-
-void ScriptInterpreter::dumpGlobalVars() {
- debugCN(kDebugScript, "ScriptInterpreter::dumpGlobalVars()\n");
- for (int i = 0; i < ARRAYSIZE(_globalVars); i++) {
- if (_globalVars[i].type != -1)
- debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _globalVars[i].type, _globalVars[i].value);
- }
-}
-
-int ScriptInterpreter::toInteger(const ScriptValue &value) {
-
- switch (value.type) {
-
- case kInteger:
- return value.value;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::toInteger() Invalid type %d!\n", value.type);
- return 0;
-
- }
-
-}
-
-const char *ScriptInterpreter::toString(const ScriptValue &value) {
-
- switch (value.type) {
-
- case kInteger:
- return NULL;
-
- case kConstString:
- return _constStrings[value.value];
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::toString() Invalid type %d!\n", value.type);
- return NULL;
-
- }
-
-}
-
-const char *ScriptInterpreter::loadGlobalString(Common::File *fd) {
- uint32 index = fd->readUint32LE();
- if (index != 0xFFFFFFFF)
- return getGlobalString(index);
- else
- return NULL;
-}
-
-void ScriptInterpreter::test() {
-}
-
-void ScriptInterpreter::loadValue(ScriptValue &value) {
-
- value.type = (ScriptValueType)_runningFunction->readByte();
-
- switch (value.type) {
-
- case kGameVar:
- case kInteger:
- case kConstString:
- case kDataRef:
- case kLogicVar:
- case kLogicVarRef:
- case kKernelVar:
- value.value = _runningFunction->readUint32();
- break;
-
- case kRegister:
- value.value = _runningFunction->readByte();
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::loadValue() Invalid value type %d!\n", value.type);
-
- }
-
-}
-
-void ScriptInterpreter::copyValue(ScriptValue &destValue, ScriptValue &sourceValue) {
-
- if (sourceValue.type == -1) {
- debugCN(kDebugScript, "ScriptInterpreter::copyValue() Trying to read uninitialized value!\n");
- }
-
- switch (destValue.type) {
-
- case kGameVar:
- _globalVars[destValue.value] = sourceValue;
- break;
-
- case kRegister:
- _registers[destValue.value] = sourceValue;
- break;
-
- case kLogicVar:
- // TODO: Move to own method
- if (sourceValue.type == kInteger) {
- _logicGlobals[destValue.value] = sourceValue.value;
- } else {
- debugCN(kDebugScript, "ScriptInterpreter::copyValue() Invalid source value type %d!\n", sourceValue.type);
- }
- break;
-
- case kKernelVar:
- setKernelVar(destValue.value, sourceValue);
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::copyValue() Invalid dest value type %d!\n", destValue.type);
-
- }
-
-}
-
-void ScriptInterpreter::derefValue(ScriptValue &value) {
-
- switch (value.type) {
-
- case kGameVar:
- value = _globalVars[value.value];
- break;
-
- case kInteger:
- case kConstString:
- case kDataRef:
- case kLogicVarRef:
- // These need no dereferencing
- break;
-
- case kRegister:
- value = _registers[value.value];
- break;
-
- case kLogicVar:
- // TODO: Move to own method
- value = _logicGlobals[value.value];
- break;
-
- case kKernelVar:
- getKernelVar(value.value, value);
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::derefValue() Invalid value type %d!\n", value.type);
-
- }
-
-}
-
-void ScriptInterpreter::callKernelFunction(uint32 index) {
-
- debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() index = %d\n", index);
-
- if (index > _kernelFunctionsMax) {
- debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() Invalid kernel functionindex (%d)\n", index);
- return;
- }
-
- debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() name = %s\n", _kernelFunctions[index].desc);
-
- int args = (this->*(_kernelFunctions[index].proc))();
- // Now remove values from the stack if the function used any
- if (args > 4)
- _stackPtr -= args - 4;
-
- debugCN(kDebugScript, "-------------\n");
-
-}
-
-ScriptValue ScriptInterpreter::getArg(uint32 index) {
- if (index < 4) {
- return _registers[index];
- } else {
- index -= 4;
- return _stack[_stackPtr - index - 1];
- }
-}
-
-void ScriptInterpreter::dumpArgs(uint32 count) {
- debugCN(kDebugScript, "ScriptInterpreter::dumpArgs() ");
- for (uint32 i = 0; i < count; i++) {
- ScriptValue argValue = getArg(i);
- if (argValue.type == kConstString) {
- debugCN(kDebugScript, "'%s'", toString(argValue));
- } else {
- debugCN(kDebugScript, "%d", argValue.value);
- }
- if (i + 1 < count)
- debugCN(kDebugScript, ", ");
- }
- debugCN(kDebugScript, "\n");
-}
-
-void ScriptInterpreter::callFunction(uint32 index) {
- // NOTE: This is a temporary hack for script functions not yet in the m4.dat
- if (index == 0xFFFFFFFF)
- return;
- debugCN(kDebugScript, "ScriptInterpreter::callFunction() index = %d [%s]\n", index, _scriptFunctionNames[index].c_str());
- ScriptFunction *subFunction = loadFunction(index);
- if (!subFunction) {
- // This *should* never happen since the linker checks this
- debugCN(kDebugScript, "ScriptInterpreter::callFunction() Function %d could not be loaded!\n", index);
- return;
- }
- runFunction(subFunction);
-}
-
-bool ScriptInterpreter::execOpcode(byte opcode) {
-
- debugCN(kDebugScript, "opcode = %d (%s)\n", opcode, opcodeNames[opcode]);
-
- ScriptValue value1, value2, value3;
- uint32 temp;
-
- /* TODO: Put all opcodes into separate functions and into an array
- (but only after all needed opcodes are known and frozen)
- */
-
- switch (opcode) {
-
- case opRet:
- return false;
-
- case opPush:
- loadValue(value1);
- derefValue(value1);
- push(value1);
- return true;
-
- case opPush0:
- push(ScriptValue(0));
- return true;
-
- case opPush1:
- push(ScriptValue(1));
- return true;
-
- case opPushNeg1:
- push(ScriptValue(-1));
- return true;
-
- case opPop:
- loadValue(value1);
- pop(value2);
- copyValue(value1, value2);
- return true;
-
- case opMov:
- loadValue(value1);
- loadValue(value2);
- derefValue(value2);
- copyValue(value1, value2);
- return true;
-
- // Possibly join all jump variants into one opcode
-
- case opJmp:
- temp = _runningFunction->readUint32();
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- return true;
-
- case opJl:
- temp = _runningFunction->readUint32();
- if (_cmpFlags < 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJle:
- temp = _runningFunction->readUint32();
- if (_cmpFlags <= 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJg:
- temp = _runningFunction->readUint32();
- if (_cmpFlags > 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJge:
- temp = _runningFunction->readUint32();
- if (_cmpFlags >= 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJz:
- temp = _runningFunction->readUint32();
- if (_cmpFlags == 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJnz:
- temp = _runningFunction->readUint32();
- if (_cmpFlags != 0) {
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- }
- return true;
-
- case opJmpByTable:
- temp = _runningFunction->readUint32();
- debugCN(kDebugScript, "-> index = %d\n", _registers[0].value);
- _runningFunction->jumpRelative(_registers[0].value * 4);
- temp = _runningFunction->readUint32();
- debugCN(kDebugScript, "-> ofs = %08X\n", temp);
- _runningFunction->jumpAbsolute(temp);
- return true;
-
- case opCmp:
- loadValue(value1);
- loadValue(value2);
- derefValue(value1);
- derefValue(value2);
- if (value1.type != kInteger || value2.type != kInteger)
- warning("ScriptInterpreter::execOpcode() Trying to compare non-integer values (%d, %d, line %d)", value1.type, value2.type, _lineNum);
- _cmpFlags = value1.value - value2.value;
- debugCN(kDebugScript, "-> cmp %d, %d\n", value1.value, value2.value);
- debugCN(kDebugScript, "-> _cmpFlags = %d\n", _cmpFlags);
- return true;
-
- case opCall:
- temp = _runningFunction->readUint32();
- callFunction(temp);
- return true;
-
- case opCallKernel:
- temp = _runningFunction->readUint32();
- callKernelFunction(temp);
- return true;
-
- case opInc:
- loadValue(value1);
- value2 = value1;
- derefValue(value2);
- value2.value++;
- copyValue(value1, value2);
- return true;
-
- case opDec:
- loadValue(value1);
- value2 = value1;
- derefValue(value2);
- value2.value--;
- copyValue(value1, value2);
- return true;
-
- case opAdd:
- loadValue(value1);
- value3 = value1;
- loadValue(value2);
- derefValue(value3);
- derefValue(value2);
- value3.value += value2.value;
- copyValue(value1, value3);
- return true;
-
- case opSub:
- loadValue(value1);
- value3 = value1;
- loadValue(value2);
- derefValue(value3);
- derefValue(value2);
- value3.value -= value2.value;
- copyValue(value1, value3);
- return true;
-
- case opDebug:
- _lineNum = (int)_runningFunction->readUint32();
- return true;
-
- default:
- debugCN(kDebugScript, "Invalid opcode %d!\n", opcode);
- return false;
-
- }
-
-}
-
-// Kernel functions
-
-#define STRING(arg) (toString(getArg(arg)))
-#define INTEGER(arg) (toInteger(getArg(arg)))
-#define DATA(arg, T) (toData<T>(getArg(arg)))
-#define RETURN(value) (_registers[0] = (value))
-
-int ScriptInterpreter::o1_handleStreamBreak() {
- return 0;
-}
-
-int ScriptInterpreter::o1_handlePlayBreak() {
- return 0;
-}
-
-int ScriptInterpreter::o1_dispatchTriggerOnSoundState() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getTicks() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setSoundVolume() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getSoundStatus() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getSoundDuration() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setSeriesFrameRate() {
- return 0;
-}
-
-int ScriptInterpreter::o1_terminateMachine() {
- return 0;
-}
-
-int ScriptInterpreter::o1_sendWoodScriptMessage() {
- return 0;
-}
-
-int ScriptInterpreter::o1_runConversation() {
- return 0;
-}
-
-int ScriptInterpreter::o1_exportConversationValue() {
- return 0;
-}
-
-int ScriptInterpreter::o1_exportConversationPointer() {
- return 0;
-}
-
-int ScriptInterpreter::o1_playBreakSeries() {
- return 0;
-}
-
-int ScriptInterpreter::o1_hideWalker() {
- return 0;
-}
-
-int ScriptInterpreter::o1_showWalker() {
- return 0;
-}
-
-int ScriptInterpreter::o1_walk() {
- return 0;
-}
-
-int ScriptInterpreter::o1_overrideCrunchTime() {
- return 0;
-}
-
-int ScriptInterpreter::o1_addBlockingRect() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setPlayerCommandsAllowed() {
- return 0;
-}
-
-int ScriptInterpreter::o1_getPlayerCommandsAllowed() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setPlayerFacingAngle() {
- return 0;
-}
-
-int ScriptInterpreter::o1_disablePlayerFadeToBlack() {
- return 0;
-}
-
-int ScriptInterpreter::o1_enablePlayer() {
- return 0;
-}
-
-int ScriptInterpreter::o1_disablePlayer() {
- return 0;
-}
-
-int ScriptInterpreter::o1_freshenSentence() {
- return 0;
-}
-
-int ScriptInterpreter::o1_playerGiveItem() {
- return 0;
-}
-
-int ScriptInterpreter::o1_moveObject() {
- return 0;
-}
-
-int ScriptInterpreter::o1_setStopSoundsBetweenRooms() {
- return 0;
-}
-
-int ScriptInterpreter::o1_backupPalette() {
- return 0;
-}
-
-int ScriptInterpreter::o1_unloadWilburWalker() {
- return 0;
-}
-
-int ScriptInterpreter::o1_wilburTalk() {
- return 0;
-}
-
-int ScriptInterpreter::o1_wilburFinishedTalking() {
- return 0;
-}
-
-int ScriptInterpreter::o1_preloadSound() {
- const char *name = STRING(0);
- int room = INTEGER(1);
- debugCN(kDebugScript, "name = %s; room = %d\n", name, room);
- return 2;
-}
-
-int ScriptInterpreter::o1_unloadSound() {
- const char *name = STRING(0);
- int room = INTEGER(1);
- debugCN(kDebugScript, "name = %s; room = %d\n", name, room);
- return 2;
-}
-
-int ScriptInterpreter::o1_playSound() {
- const char *name = STRING(0);
- int channel = INTEGER(1);
- int volume = INTEGER(2);
- int trigger = INTEGER(3);
- int room = INTEGER(4);
- debugCN(kDebugScript, "name = %s; channel = %d; volume = %d; trigger = %d; room = %d\n",
- name, channel, volume, trigger, room);
-
- Common::String soundName = Common::String(name) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
-
- // HACK until fixed
- _vm->_kernel->sendTrigger(trigger);
-
- return 5;
-}
-
-int ScriptInterpreter::o1_playLoopingSound() {
- const char *name = STRING(0);
- int channel = INTEGER(1);
- int volume = INTEGER(2);
- int trigger = INTEGER(3);
- int room = INTEGER(4);
- debugCN(kDebugScript, "name = %s; channel = %d; volume = %d; trigger = %d; room = %d\n",
- name, channel, volume, trigger, room);
-
- // HACK until fixed
- _vm->_kernel->sendTrigger(trigger);
-
- return 5;
-}
-
-int ScriptInterpreter::o1_stopSound() {
- int channel = INTEGER(0);
- debugCN(kDebugScript, "channel = %d\n", channel);
- return 1;
-}
-
-int ScriptInterpreter::o1_fadeSetStart() {
- // skip arg 0: palette ptr
- int percent = INTEGER(1);
- debugCN(kDebugScript, "percent = %d\n", percent);
- return 2;
-}
-
-int ScriptInterpreter::o1_fadeInit() {
- // skip arg 0: palette ptr
- int first = INTEGER(1);
- int last = INTEGER(2);
- int percent = INTEGER(3);
- int ticks = INTEGER(4);
- int trigger = INTEGER(5);
- debugCN(kDebugScript, "first = %d; last = %d; percent = %d; ticks = %d; trigger = %d\n",
- first, last, percent, ticks, trigger);
-
- // HACK until palette fading is implemented
- _vm->_kernel->sendTrigger(trigger);
-
- return 6;
-}
-
-int ScriptInterpreter::o1_fadeToBlack() {
- return 0;
-}
-
-int ScriptInterpreter::o1_initPaletteCycle() {
- int first = INTEGER(0);
- int last = INTEGER(1);
- int delay = INTEGER(2);
- int ticks = INTEGER(3);
- int trigger = INTEGER(4);
- debugCN(kDebugScript, "first = %d; last = %d; delay = %d; ticks = %d; trigger = %d\n",
- first, last, delay, ticks, trigger);
-
- // HACK until palette cycling is implemented
- _vm->_kernel->sendTrigger(trigger);
-
- return 5;
-}
-
-int ScriptInterpreter::o1_stopPaletteCycle() {
- return 0;
-}
-
-int ScriptInterpreter::o1_hasPlayerSaid() {
- const char *words[3];
- for (int i = 0; i < 3; i++)
- words[i] = STRING(i);
- debugCN(kDebugScript, "'%s', '%s', '%s'\n", words[0], words[1], words[2]);
-
- int result = _vm->_player->said(words[0], words[1], words[2]);
-
- debugCN(kDebugScript, " -> '%d'\n", result);
-
- RETURN(result);
- return 3;
-}
-
-int ScriptInterpreter::o1_hasPlayerSaidAny() {
- const char *words[10];
- for (int i = 0; i < 10; i++)
- words[i] = STRING(i);
-
- debugCN(kDebugScript, "'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'\n",
- words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]);
-
- int result = _vm->_player->saidAny(words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]);
- debugCN(kDebugScript, " -> '%d'\n", result);
-
- RETURN(result);
- return 10;
-}
-
-int ScriptInterpreter::o1_updatePlayerInfo() {
- // skip arg 0: player info struct
- return 1;
-}
-
-int ScriptInterpreter::o1_playerHotspotWalkOverride() {
- int x1 = INTEGER(0);
- int y1 = INTEGER(1);
- int x2 = INTEGER(2);
- int y2 = INTEGER(3);
- debugCN(kDebugScript, "(%d, %d); (%d, %d)\n", x1, y1, x2, y2);
- return 4;
-}
-
-int ScriptInterpreter::o1_playerHasItem() {
- const char *name = STRING(0);
- debugCN(kDebugScript, "item = '%s'\n", name);
- // TODO
- RETURN(0);
- return 1;
-}
-
-int ScriptInterpreter::o1_setWalkerLocation() {
- // skip arg 0: walker
- int x = INTEGER(1);
- int y = INTEGER(2);
- debugCN(kDebugScript, "x = %d; y = %d\n", x, y);
- return 3;
-}
-
-int ScriptInterpreter::o1_setWalkerFacing() {
- // skip arg 0: walker
- int facing = INTEGER(1);
- debugCN(kDebugScript, "facing = %d\n", facing);
- return 2;
-}
-
-int ScriptInterpreter::o1_setHotspot() {
- // skip arg 0: hotspot list
- const char *name = STRING(1);
- int value = INTEGER(2);
- debugCN(kDebugScript, "name = '%s' -> %d\n", name, value);
-
- _vm->_scene->getSceneResources().hotspots->setActive(name, (value != 0));
-
- return 2;
-}
-
-int ScriptInterpreter::o1_loadConversation() {
- const char *name = STRING(0);
- //int trigger = INTEGER(1);
- //int flag = INTEGER(2);
-
- // TODO; just to show something
- _m4Vm->_converse->startConversation(name);
-
- return 3;
-}
-
-int ScriptInterpreter::o1_playSeries() {
- const char *name = STRING(0);
- int layer = INTEGER(1);
- int flags = INTEGER(2);
- int trigger = INTEGER(3);
- int frameRate = INTEGER(4);
- int loopCount = INTEGER(5);
- int scale = INTEGER(6);
- int x = INTEGER(7);
- int y = INTEGER(8);
- int firstFrame = INTEGER(9);
- int lastFrame = INTEGER(10);
-
- debugCN(kDebugScript, "name = %s; layer = %04X; flags = %08X; trigger = %d; frameRate = %d; loopCount = %d; scale = %d; x = %d; y = %d: firstFrame = %d; lastFrame = %d\n",
- name, layer, flags, trigger, frameRate, loopCount, scale, x, y, firstFrame, lastFrame);
-
- // TODO: Return the machine to the script
- _vm->_ws->playSeries(name, layer, flags, trigger, frameRate, loopCount, scale, x, y, firstFrame, lastFrame);
-
- return 11;
-}
-
-int ScriptInterpreter::o1_showSeries() {
- const char *name = STRING(0);
- int layer = INTEGER(1);
- int flags = INTEGER(2);
- int trigger = INTEGER(3);
- int duration = INTEGER(4);
- int frameIndex = INTEGER(5);
- int scale = INTEGER(6);
- int x = INTEGER(7);
- int y = INTEGER(8);
-
- debugCN(kDebugScript, "name = %s; layer = %04X; flags = %08X; trigger = %d; duration = %d; frameIndex = %d; scale = %d; x = %d; y = %d\n",
- name, layer, flags, trigger, duration, frameIndex, scale, x, y);
-
- // TODO: Return the machine to the script
- _vm->_ws->showSeries(name, layer, flags, trigger, duration, frameIndex, scale, x, y);
-
- return 9;
-}
-
-int ScriptInterpreter::o1_loadSeries() {
- const char *name = STRING(0);
- int hash = INTEGER(1);
- // skip arg 3: palette ptr
-
- debugCN(kDebugScript, "name = %s; hash = %d\n", name, hash);
-
- int result = _vm->_ws->loadSeries(name, hash, NULL);
-
- RETURN(result);
- return 3;
-}
-
-int ScriptInterpreter::o1_unloadSeries() {
- return 0;
-}
-
-int ScriptInterpreter::o1_preloadBreakSeries() {
- //const SeriesStreamBreakList& seriesStreamBreakList = DATA(0, SeriesStreamBreakList);
- return 1;
-}
-
-int ScriptInterpreter::o1_unloadBreakSeries() {
- //const SeriesStreamBreakList& seriesStreamBreakList = DATA(0, SeriesStreamBreakList);
- return 1;
-}
-
-int ScriptInterpreter::o1_startBreakSeries() {
- //const SeriesStreamBreakList& seriesStreamBreakList = DATA(0, SeriesStreamBreakList);
- return 1;
-}
-
-int ScriptInterpreter::o1_globalTriggerProc() {
- int value1 = INTEGER(0);
- int value2 = INTEGER(1);
- int value3 = INTEGER(2);
- debugCN(kDebugScript, "%d; %d; %d\n", value1, value2, value3);
- return 3;
-}
-
-int ScriptInterpreter::o1_triggerTimerProc() {
- int value1 = INTEGER(0);
- int value2 = INTEGER(1);
- int value3 = INTEGER(2);
- debugCN(kDebugScript, "%d; %d; %d\n", value1, value2, value3);
- return 3;
-}
-
-int ScriptInterpreter::o1_dispatchTrigger() {
- int trigger = INTEGER(0);
- debugCN(kDebugScript, "trigger = %d\n", trigger);
-
- _vm->_kernel->sendTrigger(trigger);
- //g_system->delayMillis(5000);
-
- return 1;
-}
-
-int ScriptInterpreter::o1_getRangedRandomValue() {
- int minValue = INTEGER(0);
- int maxValue = INTEGER(1);
- RETURN(_vm->imath_ranged_rand(minValue, maxValue));
- return 2;
-}
-
-int ScriptInterpreter::o1_wilburSaid() {
- const SaidArray& saidArray = DATA(0, SaidArray);
-
- int result = 0;
-
- // NOTE: The "Common::String soundName" stuff is just temporary until playVoice is fixed.
-
- for (int i = 0; i < saidArray.size(); i++) {
- SaidArrayItem *item = saidArray[i];
-
- if (_vm->_player->said("LOOK AT", item->itemName) && item->digiNameLook) {
- debugCN(kDebugScript, " -> LOOK AT: '%s'\n", item->digiNameLook);
- Common::String soundName = Common::String(item->digiNameLook) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
- result = 1;
- break;
- }
-
- if (_vm->_player->said("TAKE", item->itemName) && item->digiNameTake) {
- debugCN(kDebugScript, " -> TAKE: '%s'\n", item->digiNameTake);
- Common::String soundName = Common::String(item->digiNameTake) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
- result = 1;
- break;
- }
-
- if (_vm->_player->said("GEAR", item->itemName) && item->digiNameGear) {
- debugCN(kDebugScript, " -> GEAR: '%s'\n", item->digiNameGear);
- Common::String soundName = Common::String(item->digiNameGear) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
- result = 1;
- break;
- }
-
- /*
- debugCN(kDebugScript, "##### itemName = '%s'; digiNameLook = %s; digiNameTake = %s; digiNameGear = %s\n",
- item->itemName, item->digiNameLook, item->digiNameTake, item->digiNameGear);
- */
- }
- debugCN(kDebugScript, " -> '%d'\n", result);
-
- RETURN(result);
- return 1;
-}
-
-int ScriptInterpreter::o1_wilburParse() {
- //const ParserArray& parserArray = DATA(0, ParserArray);
- RETURN(0);
- return 1;
-}
-
-int ScriptInterpreter::o1_wilburSpeech() {
- const char *name = STRING(0);
- int trigger = INTEGER(1);
- int room = INTEGER(2);
- int flag = INTEGER(3);
- int volume = INTEGER(4);
- int slot = INTEGER(5);
-
- debugCN(kDebugScript, "%s; %d; %d; %d; %d; %d\n", name, trigger, room, flag, volume, slot);
- //g_system->delayMillis(5000);
-
- KernelTriggerType oldTriggerMode = _vm->_kernel->triggerMode;
-
- // TODO
- Common::String soundName = Common::String(name) + ".raw";
- _vm->_sound->playVoice(soundName.c_str(), 100);
-
- _vm->_kernel->triggerMode = oldTriggerMode;
-
- return 6;
-}
-
-// Kernel vars
-
-void ScriptInterpreter::getKernelVar(int index, ScriptValue &value) {
-
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() index = %d\n", index);
-
- if (index > _kernelVarsMax) {
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() Invalid kernel var index %d!\n", index);
- return;
- }
-
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() name = %s\n", _kernelVars[index].desc);
-
- ScriptKernelVariable var = _kernelVars[index].var;
-
- switch (var) {
-
- case kKernelTrigger:
- value = _vm->_kernel->trigger;
- break;
-
- case kKernelTriggerMode:
- value = (int)_vm->_kernel->triggerMode;
- break;
-
- case kKernelContinueHandlingTrigger:
- value = (int)_vm->_kernel->daemonTriggerAvailable;
- break;
-
- case kGameVersion:
- // TODO
- value = 0;
- break;
-
- case kGameLanguage:
- // TODO
- value = 0;
- break;
-
- case kGameNewRoom:
- // TODO
- value = 0;
- break;
-
- case kPlayerCommandReady:
- value = (int)_vm->_player->commandReady;
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() Invalid kernel var %d!\n", var);
- //g_system->delayMillis(2000);
-
- }
-
-}
-
-void ScriptInterpreter::setKernelVar(int index, const ScriptValue &value) {
-
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() index = %d\n", index);
-
- if (index > _kernelVarsMax) {
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() Invalid kernel var index %d!\n", index);
- return;
- }
-
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() name = %s\n", _kernelVars[index].desc);
-
- ScriptKernelVariable var = _kernelVars[index].var;
-
- switch (var) {
-
- case kKernelTrigger:
- _vm->_kernel->trigger = toInteger(value);
- debugCN(kDebugScript, "kKernelTrigger -> %d\n", toInteger(value));
- break;
-
- case kKernelTriggerMode:
- _vm->_kernel->triggerMode = (KernelTriggerType)toInteger(value);
- debugCN(kDebugScript, "kKernelTrigger -> %d\n", toInteger(value));
- break;
-
- case kKernelContinueHandlingTrigger:
- _vm->_kernel->daemonTriggerAvailable = (toInteger(value) != 0);
- debugCN(kDebugScript, "kKernelContinueHandlingTrigger -> %d\n", toInteger(value));
- break;
-
- case kGameNewRoom:
- _vm->_kernel->newRoom = toInteger(value);
- debugCN(kDebugScript, "kGameNewRoom -> %d\n", toInteger(value));
- break;
-
- case kPlayerCommandReady:
- // TODO
- debugCN(kDebugScript, "kPlayerCommandReady -> %d\n", toInteger(value));
- break;
-
- default:
- debugCN(kDebugScript, "ScriptInterpreter::setKernelVar() Invalid kernel var %d!\n", var);
- //g_system->delayMillis(2000);
-
- }
-
-}
-
-} // End of namespace M4
diff --git a/engines/m4/script.h b/engines/m4/script.h
deleted file mode 100644
index 22f07fd062..0000000000
--- a/engines/m4/script.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_SCRIPT_H
-#define M4_SCRIPT_H
-
-#include "common/file.h"
-#include "common/stream.h"
-#include "common/hashmap.h"
-#include "common/str.h"
-#include "common/stack.h"
-
-#include "m4/woodscript.h"
-
-namespace M4 {
-
-const unsigned long kScriptFileMagic = 0x5845344D;
-const unsigned long kScriptFileVersion = 1;
-
-enum ScriptValueType {
- kInteger,
- kConstString,
- kLogicVar,
- kLogicVarRef,
- kGameVar,
- kKernelVar,
- kDataRef,
- kRegister,
- kStackVar
-};
-
-enum ScriptDataType {
- kStreamBreakSeries,
- kStreamPlaySeries,
- kSaidArray,
- kParserArray,
- kSpeechArray,
- kCreditsArray,
- kInvObj,
- kMineRoom,
- kButtonItem
-};
-
-class ScriptInterpreter;
-
-class StringTable {
-public:
- StringTable();
- ~StringTable();
- void load(Common::File *fd);
- int size() { return _strings.size(); }
- const char *operator[](uint32 index) const {
- assert(index < _strings.size() );
- return _strings[index];
- }
-protected:
- Common::Array<const char*> _strings;
- char *_stringsData;
-};
-
-struct ScriptValue {
-
- ScriptValueType type;
-
- union {
- int value;
- };
-
- ScriptValue() : type(kInteger), value(0) {}
- ScriptValue(ScriptValueType itype, int ivalue) : type(itype), value(ivalue) {}
-
- ScriptValue(const int intValue) : type(kInteger), value(intValue) {}
-
- ScriptValue& operator=(const int intValue) {
- type = kInteger;
- value = intValue;
- return *this;
- }
-
-};
-
-class ScriptDataItem {
-public:
- ScriptDataItem() : _inter(NULL) {}
- ScriptDataItem(ScriptInterpreter *inter) : _inter(inter) {}
- virtual ~ScriptDataItem() {}
- virtual void load(Common::File *fd) = 0;
- static int type() { return -1; }
-protected:
- ScriptInterpreter *_inter;
-};
-
-class ScriptDataCache {
-public:
- ScriptDataCache(ScriptInterpreter *inter) : _inter(inter) {
- }
- ~ScriptDataCache() {
- clear();
- }
-
- // WORKAROUND: The old prototype for this function was:
- // template<class T> T *load(Common::File *fd, uint32 ofs);
- // that caused a parser error in g++ 3.3.6 used by our
- // "motoezx" target of our buildbot. The actual parser
- // error happended, when calling the function like this:
- // "T *result = _dataCache->load<T>(_scriptFile, _data[value.value]->offset);"
- // in ScriptInterpreter::toData. To work around this
- // we moved the return value as parameter instead.
- template<class T>
- void load(Common::File *fd, uint32 ofs, T *&item) {
- if (_cache.contains(ofs)) {
- item = (T*)(_cache[ofs]);
- } else {
- item = new T(_inter);
- fd->seek(ofs + 4); // "+4" skips the data size
- item->load(fd);
- _cache[ofs] = item;
- }
- }
- void clear() {
- // TODO: Free all cached items
- }
-protected:
- typedef Common::HashMap<uint32, ScriptDataItem*> CacheMap;
- CacheMap _cache;
- ScriptInterpreter *_inter;
-};
-
-struct SeriesStreamBreakItem {
- int frameNum;
- const char *digiName;
- int digiChannel;
- int digiVolume;
- int trigger;
- int flags;
- ScriptValue variable;
- int value;
-};
-
-class SeriesStreamBreakList : public ScriptDataItem {
-public:
- SeriesStreamBreakList(ScriptInterpreter *inter) : ScriptDataItem(inter) {}
- ~SeriesStreamBreakList();
- void load(Common::File *fd);
- int size() const { return _items.size(); }
- SeriesStreamBreakItem *operator[](int index) const { return _items[index]; }
- static int type() { return 0; }
-protected:
- Common::Array<SeriesStreamBreakItem*> _items;
-};
-
-struct SaidArrayItem {
- const char *itemName;
- const char *digiNameLook;
- const char *digiNameTake;
- const char *digiNameGear;
-};
-
-class SaidArray : public ScriptDataItem {
-public:
- SaidArray(ScriptInterpreter *inter) : ScriptDataItem(inter) {}
- ~SaidArray();
- void load(Common::File *fd);
- int size() const { return _items.size(); }
- SaidArrayItem *operator[](int index) const { return _items[index]; }
- static int type() { return 2; }
-protected:
- Common::Array<SaidArrayItem*> _items;
-};
-
-struct ParserArrayItem {
- const char *w0;
- const char *w1;
- int trigger;
- ScriptValue testVariable;
- int testValue;
- ScriptValue variable;
- int value;
-};
-
-class ParserArray : public ScriptDataItem {
-public:
- ParserArray(ScriptInterpreter *inter) : ScriptDataItem(inter) {}
- ~ParserArray();
- void load(Common::File *fd);
- int size() const { return _items.size(); }
- ParserArrayItem *operator[](int index) const { return _items[index]; }
- static int type() { return 3; }
-protected:
- Common::Array<ParserArrayItem*> _items;
-};
-
-class ScriptFunction {
-public:
- ScriptFunction(ScriptInterpreter *inter);
- ~ScriptFunction();
- void load(Common::File *fd);
- void jumpAbsolute(uint32 ofs);
- void jumpRelative(int32 ofs);
- byte readByte();
- uint32 readUint32();
-protected:
- ScriptInterpreter *_inter;
- Common::SeekableReadStream *_code;
-};
-
-struct ScriptFunctionEntry {
- uint32 offset;
- ScriptFunction *func;
- ScriptFunctionEntry(uint32 funcOffset) : offset(funcOffset), func(NULL) {
- }
-};
-
-struct ScriptDataEntry {
- uint32 offset;
- ScriptDataType type;
- ScriptDataEntry(uint32 dataOffset, ScriptDataType dataType) : offset(dataOffset), type(dataType) {
- }
-};
-
-enum ScriptKernelVariable {
- kGameLanguage,
- kGameVersion,
- kGameCurrentRoom,
- kGameNewRoom,
- kGamePreviousRoom,
- kGameNewSection,
- kKernelTrigger,
- kKernelTriggerMode,
- kKernelFirstFade,
- kKernelSuppressFadeUp,
- kKernelContinueHandlingTrigger,
- kKernelUseDebugMonitor,
- kPlayerPosX,
- kPlayerPosY,
- kPlayerFacing,
- kPlayerScale,
- kPlayerDepth,
- kPlayerWalkX,
- kPlayerWalkY,
- kPlayerReadyToWalk,
- kPlayerNeedToWalk,
- kPlayerCommandReady,
- kPlayerWalkerInThisScene,
- kPlayerVerb,
- kWalkerInitialized,
- kCallDaemonEveryLoop,
- kConvCurrentTalker,
- kConvCurrentNode,
- kConvCurrentEntry,
- kConvSoundToPlay,
- kInterfaceVisible
-};
-
-class ScriptInterpreter {
-public:
- ScriptInterpreter(MadsM4Engine *vm);
- ~ScriptInterpreter();
- /* Opens a M4 program file */
- void open(const char *filename);
- void close();
- /* Loads a function via the index. Creates the function object if it's not already loaded. */
- ScriptFunction *loadFunction(uint32 index);
- /* Loads a function via the exported name. */
- ScriptFunction *loadFunction(const Common::String &name);
- /* Unload all loaded functions.
- This should be called before entering a new room to free unused functions. */
- void unloadFunctions();
- //TODO void unloadData();
- /* Executes a function. */
- int runFunction(ScriptFunction *scriptFunction);
-
- void push(const ScriptValue &value);
- void pop(ScriptValue &value);
- void dumpStack();
- void dumpRegisters();
- void dumpGlobalVars();
-
- int toInteger(const ScriptValue &value);
-
- const char *toString(const ScriptValue &value);
-
- // Is this ok?
- template<class T>
- const T& toData(const ScriptValue &value) {
- debugCN(kDebugScript, "ScriptInterpreter::toData() index = %d; type = %d; max = %d\n", value.value, _data[value.value]->type, _data.size());
- assert((uint32)value.value < _data.size());
- T *result = 0;
- _dataCache->load(_scriptFile, _data[value.value]->offset, result);
- return *result;
- }
-
- const char *getGlobalString(int index) const {
- return _constStrings[index];
- }
-
- const char *loadGlobalString(Common::File *fd);
-
- void test();
-
-protected:
-
- MadsM4Engine *_vm;
-
- typedef Common::HashMap<Common::String, uint32, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FunctionNameMap;
- Common::File *_scriptFile;
- /* An array of offset/ScriptFunction* pairs for each script function */
- Common::Array<ScriptFunctionEntry*> _functions;
-
- // DEBUG only
- Common::Array<Common::String> _scriptFunctionNames;
-
- Common::Array<ScriptDataEntry*> _data;
- /* Maps function name -> index of function in _functions array */
- FunctionNameMap _functionNames;
- StringTable _constStrings;
- /* The currently running function */
- ScriptFunction *_runningFunction;
- int _localStackPtr;
-
- ScriptValue _registers[8];
-
- ScriptValue _stack[512];
- int _stackPtr;
-
- int _globalVarCount;
- ScriptValue _globalVars[1024];
-
- int _logicGlobals[512];
-
- int _cmpFlags;
-
- ScriptDataCache *_dataCache;
-
- int _lineNum;
-
- typedef int (ScriptInterpreter::*KernelFunction)();
- struct KernelFunctionEntry {
- KernelFunction proc;
- const char *desc;
- };
- const KernelFunctionEntry *_kernelFunctions;
- uint16 _kernelFunctionsMax;
-
- struct KernelVariableEntry {
- ScriptKernelVariable var;
- const char *desc;
- };
- const KernelVariableEntry *_kernelVars;
- int16 _kernelVarsMax;
-
- void initScriptKernel();
-
- void loadValue(ScriptValue &value);
- void writeValue(ScriptValue &value);
- void copyValue(ScriptValue &destValue, ScriptValue &sourceValue);
- void derefValue(ScriptValue &value);
-
- void callKernelFunction(uint32 index);
- ScriptValue getArg(uint32 index);
- void dumpArgs(uint32 count);
-
- void callFunction(uint32 index);
-
- bool execOpcode(byte opcode);
-
- // Kernel functions
- int o1_handleStreamBreak();
- int o1_handlePlayBreak();
- int o1_dispatchTriggerOnSoundState();
- int o1_getRangedRandomValue();
- int o1_getTicks();
- int o1_preloadSound();
- int o1_unloadSound();
- int o1_stopSound();
- int o1_playSound();
- int o1_playLoopingSound();
- int o1_setSoundVolume();
- int o1_getSoundStatus();
- int o1_getSoundDuration();
- int o1_loadSeries();
- int o1_unloadSeries();
- int o1_showSeries();
- int o1_playSeries();
- int o1_setSeriesFrameRate();
- int o1_playBreakSeries();
- int o1_preloadBreakSeries();
- int o1_unloadBreakSeries();
- int o1_startBreakSeries();
- int o1_dispatchTrigger();
- int o1_terminateMachine();
- int o1_sendWoodScriptMessage();
- int o1_runConversation();
- int o1_loadConversation();
- int o1_exportConversationValue();
- int o1_exportConversationPointer();
- int o1_fadeInit();
- int o1_fadeSetStart();
- int o1_fadeToBlack();
- int o1_initPaletteCycle();
- int o1_stopPaletteCycle();
- int o1_setHotspot();
- int o1_hideWalker();
- int o1_showWalker();
- int o1_setWalkerLocation();
- int o1_setWalkerFacing();
- int o1_walk();
- int o1_overrideCrunchTime();
- int o1_addBlockingRect();
- int o1_triggerTimerProc();
- int o1_setPlayerCommandsAllowed();
- int o1_getPlayerCommandsAllowed();
- int o1_updatePlayerInfo();
- int o1_hasPlayerSaid();
- int o1_hasPlayerSaidAny();
- int o1_playerHotspotWalkOverride();
- int o1_setPlayerFacingAngle();
- int o1_disablePlayerFadeToBlack();
- int o1_enablePlayer();
- int o1_disablePlayer();
- int o1_freshenSentence();
- int o1_playerHasItem();
- int o1_playerGiveItem();
- int o1_moveObject();
- int o1_setStopSoundsBetweenRooms();
- int o1_backupPalette();
- int o1_unloadWilburWalker();
- int o1_globalTriggerProc();
- int o1_wilburSpeech();
- int o1_wilburSaid();
- int o1_wilburParse();
- int o1_wilburTalk();
- int o1_wilburFinishedTalking();
- //int ();
-
- // Kernel vars
- void getKernelVar(int index, ScriptValue &value);
- void setKernelVar(int index, const ScriptValue &value);
-
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/scripttab.h b/engines/m4/scripttab.h
deleted file mode 100644
index 3264ae743c..0000000000
--- a/engines/m4/scripttab.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* This file has been autogenerated by the linker.
- Do not edit it or merge it with script.cpp! */
-#define FUNCTION(x) { &ScriptInterpreter::x, #x }
- static KernelFunctionEntry kernelFunctions[] = {
- /* 000 */
- FUNCTION(o1_handleStreamBreak),
- FUNCTION(o1_handlePlayBreak),
- FUNCTION(o1_dispatchTriggerOnSoundState),
- FUNCTION(o1_getRangedRandomValue),
- /* 004 */
- FUNCTION(o1_getTicks),
- FUNCTION(o1_preloadSound),
- FUNCTION(o1_unloadSound),
- FUNCTION(o1_stopSound),
- /* 008 */
- FUNCTION(o1_playSound),
- FUNCTION(o1_playLoopingSound),
- FUNCTION(o1_setSoundVolume),
- FUNCTION(o1_getSoundStatus),
- /* 012 */
- FUNCTION(o1_getSoundDuration),
- FUNCTION(o1_loadSeries),
- FUNCTION(o1_unloadSeries),
- FUNCTION(o1_showSeries),
- /* 016 */
- FUNCTION(o1_playSeries),
- FUNCTION(o1_setSeriesFrameRate),
- FUNCTION(o1_playBreakSeries),
- FUNCTION(o1_preloadBreakSeries),
- /* 020 */
- FUNCTION(o1_unloadBreakSeries),
- FUNCTION(o1_startBreakSeries),
- FUNCTION(o1_dispatchTrigger),
- FUNCTION(o1_terminateMachine),
- /* 024 */
- FUNCTION(o1_sendWoodScriptMessage),
- FUNCTION(o1_runConversation),
- FUNCTION(o1_runConversation),
- FUNCTION(o1_loadConversation),
- /* 028 */
- FUNCTION(o1_exportConversationValue),
- FUNCTION(o1_exportConversationPointer),
- FUNCTION(o1_runConversation),
- FUNCTION(o1_fadeInit),
- /* 032 */
- FUNCTION(o1_fadeSetStart),
- FUNCTION(o1_fadeToBlack),
- FUNCTION(o1_initPaletteCycle),
- FUNCTION(o1_stopPaletteCycle),
- /* 036 */
- FUNCTION(o1_setHotspot),
- FUNCTION(o1_hideWalker),
- FUNCTION(o1_showWalker),
- FUNCTION(o1_setWalkerLocation),
- /* 040 */
- FUNCTION(o1_setWalkerFacing),
- FUNCTION(o1_walk),
- FUNCTION(o1_overrideCrunchTime),
- FUNCTION(o1_addBlockingRect),
- /* 044 */
- FUNCTION(o1_triggerTimerProc),
- FUNCTION(o1_setPlayerCommandsAllowed),
- FUNCTION(o1_getPlayerCommandsAllowed),
- FUNCTION(o1_updatePlayerInfo),
- /* 048 */
- FUNCTION(o1_hasPlayerSaid),
- FUNCTION(o1_hasPlayerSaidAny),
- FUNCTION(o1_playerHotspotWalkOverride),
- FUNCTION(o1_setPlayerFacingAngle),
- /* 052 */
- FUNCTION(o1_disablePlayerFadeToBlack),
- FUNCTION(o1_enablePlayer),
- FUNCTION(o1_disablePlayer),
- FUNCTION(o1_freshenSentence),
- /* 056 */
- FUNCTION(o1_playerHasItem),
- FUNCTION(o1_playerGiveItem),
- FUNCTION(o1_moveObject),
- FUNCTION(o1_setStopSoundsBetweenRooms),
- /* 060 */
- FUNCTION(o1_backupPalette),
- FUNCTION(o1_unloadWilburWalker),
- FUNCTION(o1_globalTriggerProc),
- FUNCTION(o1_wilburSpeech),
- /* 064 */
- FUNCTION(o1_wilburParse),
- FUNCTION(o1_wilburSaid),
- FUNCTION(o1_wilburTalk),
- FUNCTION(o1_wilburFinishedTalking)
- };
-#undef FUNCTION
-
-#define VARIABLE(x) { x, #x }
- static KernelVariableEntry kernelVars[] = {
- /* 000 */
- VARIABLE(kGameLanguage),
- VARIABLE(kGameVersion),
- VARIABLE(kGameCurrentRoom),
- VARIABLE(kGameNewRoom),
- /* 004 */
- VARIABLE(kGamePreviousRoom),
- VARIABLE(kGameNewSection),
- VARIABLE(kKernelTrigger),
- VARIABLE(kKernelTriggerMode),
- /* 008 */
- VARIABLE(kKernelFirstFade),
- VARIABLE(kKernelSuppressFadeUp),
- VARIABLE(kKernelContinueHandlingTrigger),
- VARIABLE(kKernelUseDebugMonitor),
- /* 012 */
- VARIABLE(kPlayerPosX),
- VARIABLE(kPlayerPosY),
- VARIABLE(kPlayerFacing),
- VARIABLE(kPlayerScale),
- /* 016 */
- VARIABLE(kPlayerDepth),
- VARIABLE(kPlayerWalkX),
- VARIABLE(kPlayerWalkY),
- VARIABLE(kPlayerReadyToWalk),
- /* 020 */
- VARIABLE(kPlayerNeedToWalk),
- VARIABLE(kPlayerCommandReady),
- VARIABLE(kPlayerWalkerInThisScene),
- VARIABLE(kPlayerVerb),
- /* 024 */
- VARIABLE(kWalkerInitialized),
- VARIABLE(kCallDaemonEveryLoop),
- VARIABLE(kConvCurrentTalker),
- VARIABLE(kConvCurrentNode),
- /* 028 */
- VARIABLE(kConvCurrentEntry),
- VARIABLE(kConvSoundToPlay),
- VARIABLE(kInterfaceVisible)
- };
-#undef VARIABLE
diff --git a/engines/m4/sound.cpp b/engines/m4/sound.cpp
deleted file mode 100644
index 76eae8a661..0000000000
--- a/engines/m4/sound.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/m4.h"
-#include "m4/sound.h"
-#include "m4/compression.h"
-
-#include "common/stream.h"
-#include "common/textconsole.h"
-
-#include "audio/audiostream.h"
-#include "audio/mixer.h"
-#include "audio/decoders/raw.h"
-
-namespace M4 {
-
-Sound::Sound(MadsM4Engine *vm, Audio::Mixer *mixer, int volume) :
- _vm(vm), _mixer(mixer) {
-
- for (int i = 0; i < SOUND_HANDLES; i++)
- _handles[i].type = kFreeHandle;
-
- _dsrFileLoaded = false;
-
- setVolume(volume);
-}
-
-Sound::~Sound() {
- unloadDSRFile();
-}
-
-SndHandle *Sound::getHandle() {
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kFreeHandle)
- return &_handles[i];
-
- if (!_mixer->isSoundHandleActive(_handles[i].handle)) {
- _handles[i].type = kFreeHandle;
- return &_handles[i];
- }
- }
-
- error("Sound::getHandle(): Too many sound handles");
- return NULL; // for compilers that don't support NORETURN
-}
-
-bool Sound::isHandleActive(SndHandle *handle) {
- return (_mixer->isSoundHandleActive(handle->handle));
-}
-
-void Sound::playSound(const char *soundName, int volume, bool loop, int channel) {
- Common::SeekableReadStream *soundStream = _vm->res()->get(soundName);
- SndHandle *handle;
- if (channel < 0) {
- handle = getHandle();
- } else {
- if (_handles[channel].type == kFreeHandle) {
- handle = &_handles[channel];
- } else {
- warning("Attempted to play a sound on a channel that isn't free");
- return;
- }
- }
-
- int bufferSize = soundStream->size();
- byte *buffer = new byte[bufferSize];
- soundStream->read(buffer, bufferSize);
- _vm->res()->toss(soundName);
-
- handle->type = kEffectHandle;
-
- _vm->res()->toss(soundName);
-
- // Sound format is 8bit mono, unsigned, 11025kHz
- Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(buffer, bufferSize, 11025, Audio::FLAG_UNSIGNED),
- loop ? 0 : 1);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
-}
-
-void Sound::playSound(int soundNum) {
- warning("TODO: playSound(%d)", soundNum);
-}
-
-void Sound::pauseSound() {
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kEffectHandle)
- _mixer->pauseHandle(_handles[i].handle, true);
- }
-}
-
-void Sound::resumeSound() {
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kEffectHandle)
- _mixer->pauseHandle(_handles[i].handle, false);
- }
-}
-
-void Sound::stopSound(int channel) {
- if (channel >= 0) {
- if (_handles[channel].type == kEffectHandle) {
- _mixer->stopHandle(_handles[channel].handle);
- _handles[channel].type = kFreeHandle;
- return;
- } else {
- warning("Attempted to stop a sound on a channel that is already free");
- return;
- }
- }
-
- for (int i = 0; i < SOUND_HANDLES; i++) {
- if (_handles[i].type == kEffectHandle) {
- _mixer->stopHandle(_handles[i].handle);
- _handles[i].type = kFreeHandle;
- }
- }
-}
-
-void Sound::playVoice(const char *soundName, int volume) {
- Common::SeekableReadStream *soundStream = _vm->res()->get(soundName);
- SndHandle *handle = getHandle();
- byte *buffer;
-
- buffer = (byte *)malloc(soundStream->size());
- soundStream->read(buffer, soundStream->size());
-
- handle->type = kEffectHandle;
-
- _vm->res()->toss(soundName);
-
- // Voice format is 8bit mono, unsigned, 11025kHz
- Audio::AudioStream *stream = Audio::makeRawStream(buffer, soundStream->size(), 11025, Audio::FLAG_UNSIGNED);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
-}
-
-void Sound::pauseVoice() {
- for (int i = 0; i < SOUND_HANDLES; i++)
- if (_handles[i].type == kVoiceHandle)
- _mixer->pauseHandle(_handles[i].handle, true);
-}
-
-void Sound::resumeVoice() {
- for (int i = 0; i < SOUND_HANDLES; i++)
- if (_handles[i].type == kVoiceHandle)
- _mixer->pauseHandle(_handles[i].handle, false);
-}
-
-void Sound::stopVoice() {
- for (int i = 0; i < SOUND_HANDLES; i++)
- if (_handles[i].type == kVoiceHandle) {
- _mixer->stopHandle(_handles[i].handle);
- _handles[i].type = kFreeHandle;
- }
-}
-
-void Sound::stopAll() {
- stopVoice();
- stopSound();
-}
-
-void Sound::setVolume(int volume) {
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
-}
-
-void Sound::loadDSRFile(const char *fileName) {
- if (_dsrFileLoaded)
- unloadDSRFile();
-
- Common::SeekableReadStream *fileStream = _vm->res()->get(fileName);
-
- sprintf(_dsrFile.fileName, "%s", fileName);
-
- // Read header
- _dsrFile.entryCount = fileStream->readUint16LE();
- //warning(kDebugSound, "DSR has %i entries\n", _dsrFile.entryCount);
-
- for (int i = 0; i < _dsrFile.entryCount; i++) {
- DSREntry newEntry;
- newEntry.frequency = fileStream->readUint16LE();
- newEntry.channels = fileStream->readUint32LE();
- newEntry.compSize = fileStream->readUint32LE();
- newEntry.uncompSize = fileStream->readUint32LE();
- newEntry.offset = fileStream->readUint32LE();
- _dsrFile.dsrEntries.push_back(newEntry);
-
- /*
- warning(kDebugSound, "%i: ", i);
- warning(kDebugSound, "frequency: %i ", newEntry->frequency);
- warning(kDebugSound, "channels: %i ", newEntry->channels);
- warning(kDebugSound, "comp: %i ", newEntry.compSize);
- warning(kDebugSound, "uncomp: %i ", newEntry.uncompSize);
- warning(kDebugSound, "offset: %i ", newEntry->offset);
- warning(kDebugSound, "\n");
- */
- }
-
- _vm->res()->toss(fileName);
-
- _dsrFileLoaded = true;
-}
-
-void Sound::unloadDSRFile() {
- if (!_dsrFileLoaded)
- return;
-
- _dsrFile.dsrEntries.clear();
-
- _dsrFile.entryCount = 0;
- strcpy(_dsrFile.fileName, "");
- _dsrFileLoaded = false;
-}
-
-void Sound::playDSRSound(int soundIndex, int volume, bool loop) {
- if (!_dsrFileLoaded) {
- warning("DSR file not loaded, not playing sound");
- return;
- }
-
- if (soundIndex < 0 || soundIndex > _dsrFile.entryCount - 1) {
- warning("Invalid sound index: %i, not playing sound", soundIndex);
- return;
- }
-
- SndHandle *handle = getHandle();
-
- handle->type = kEffectHandle;
-
- // Get sound data
- FabDecompressor fab;
- byte *compData = new byte[_dsrFile.dsrEntries[soundIndex].compSize];
- byte *buffer = new byte[_dsrFile.dsrEntries[soundIndex].uncompSize];
- Common::SeekableReadStream *fileStream = _vm->res()->get(_dsrFile.fileName);
- fileStream->seek(_dsrFile.dsrEntries[soundIndex].offset, SEEK_SET);
- fileStream->read(compData, _dsrFile.dsrEntries[soundIndex].compSize);
- _vm->res()->toss(_dsrFile.fileName);
-
- fab.decompress(compData, _dsrFile.dsrEntries[soundIndex].compSize,
- buffer, _dsrFile.dsrEntries[soundIndex].uncompSize);
-
- // Play sound
- Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(buffer,
- _dsrFile.dsrEntries[soundIndex].uncompSize,
- _dsrFile.dsrEntries[soundIndex].frequency, Audio::FLAG_UNSIGNED),
- loop ? 0 : 1);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &handle->handle, stream, -1, volume);
-
- /*
- // Dump the sound file
- FILE *destFile = fopen("sound.raw", "wb");
- fwrite(_dsrFile.dsrEntries[soundIndex]->data, _dsrFile.dsrEntries[soundIndex].uncompSize, 1, destFile);
- fclose(destFile);
- */
-}
-
-} // End of namespace M4
diff --git a/engines/m4/sound.h b/engines/m4/sound.h
deleted file mode 100644
index 99a2292d83..0000000000
--- a/engines/m4/sound.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// Sound class
-
-#ifndef M4_SOUND_H
-#define M4_SOUND_H
-
-#include "common/file.h"
-#include "common/array.h"
-#include "audio/mixer.h"
-#include "audio/decoders/mp3.h"
-#include "audio/decoders/vorbis.h"
-#include "audio/decoders/flac.h"
-
-namespace M4 {
-
-#define SOUND_HANDLES 10
-
-enum SOUND_FLAGS {
- SOUND_LOOP = 1
-};
-
-enum sndHandleType {
- kFreeHandle,
- kEffectHandle,
- kVoiceHandle
-};
-
-struct SndHandle {
- Audio::SoundHandle handle;
- sndHandleType type;
-};
-
-struct DSREntry {
- int16 frequency;
- int channels;
- int32 compSize;
- int32 uncompSize;
- int32 offset;
-};
-
-struct DSRFile {
- char fileName[20];
- int entryCount;
- Common::Array<DSREntry> dsrEntries;
-};
-
-class MadsM4Engine;
-
-class Sound {
-public:
-
- Sound(MadsM4Engine *vm, Audio::Mixer *mixer, int volume);
- ~Sound();
-
- void playSound(const char *soundName, int volume, bool loop, int channel = -1);
- void playSound(int soundNum);
- void pauseSound();
- void resumeSound();
- void stopSound(int channel = -1);
-
- void playVoice(const char *soundName, int volume);
- void pauseVoice();
- void resumeVoice();
- void stopVoice();
-
- void stopAll();
-
- void setVolume(int volume);
-
- bool isHandleActive(SndHandle *handle);
- SndHandle *getHandle();
-
- void loadDSRFile(const char *fileName);
- void unloadDSRFile();
- void playDSRSound(int soundIndex, int volume, bool loop);
-
- private:
-
- MadsM4Engine *_vm;
- Audio::Mixer *_mixer;
- SndHandle _handles[SOUND_HANDLES];
-
- DSRFile _dsrFile;
- bool _dsrFileLoaded;
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/sprite.cpp b/engines/m4/sprite.cpp
deleted file mode 100644
index d0741732f3..0000000000
--- a/engines/m4/sprite.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/rect.h"
-#include "common/textconsole.h"
-
-#include "m4/globals.h"
-#include "m4/graphics.h"
-#include "m4/m4.h"
-#include "m4/resource.h"
-#include "m4/sprite.h"
-
-namespace M4 {
-
-enum {
- kEndOfLine = 0,
- kEndOfSprite = 1,
- kMarker = 2
-};
-
-M4Sprite::M4Sprite(Common::SeekableReadStream* source, int xOfs, int yOfs, int widthVal, int heightVal, bool decodeRle, uint8 encodingVal)
- : M4Surface(widthVal, heightVal), encoding(encodingVal) {
-
- if (_vm->isM4()) {
- if (decodeRle) {
- loadRle(source);
- } else {
- // Raw sprite data, load directly
- byte *dst = getBasePtr();
- source->read(dst, widthVal * heightVal);
- }
- } else {
- loadMadsSprite(source);
- }
-
- x = xOffset = xOfs;
- y = yOffset = yOfs;
-
-}
-
-void M4Sprite::loadRle(Common::SeekableReadStream* rleData) {
- byte *dst = getBasePtr();
- while (1) {
- byte len = rleData->readByte();
- if (len == 0) {
- len = rleData->readByte();
- if (len <= kMarker) {
- if (len == kEndOfSprite)
- break;
- } else {
- while (len--) {
- *dst++ = rleData->readByte();
- }
- }
- } else {
- byte value = rleData->readByte();
- while (len--)
- *dst++ = value;
- }
- }
-}
-
-void M4Sprite::loadDeltaRle(Common::SeekableReadStream* rleData, int destX, int destY) {
- int lineNum = 0;
- byte *dst = getBasePtr(destX, destY);
- while (1) {
- byte len = rleData->readByte();
- if (len == 0) {
- len = rleData->readByte();
- if (len <= kMarker) {
- if (len == kEndOfLine) {
- dst = getBasePtr(destX, destY + lineNum);
- lineNum++;
- } else if (len == kEndOfSprite)
- break;
- } else {
- while (len--) {
- byte pixel = rleData->readByte();
- if (pixel == 0)
- dst++;
- else
- *dst++ = pixel;
- /* NOTE: The change below behaved differently than the old code,
- so I put the old code back in again above.
- If the pixel value is 0, nothing should be written to the
- output buffer, since 0 means transparent. */
- //*dst++ = (pixel == 0xFD) ? 0 : pixel;
- }
- }
- } else {
- byte value = rleData->readByte();
- if (value == 0)
- dst += len;
- else
- while (len--)
- *dst++ = value;
- }
- }
-}
-
-// TODO: The sprite outlines (pixel value 0xFD) are not shown
-void M4Sprite::loadMadsSprite(Common::SeekableReadStream* source) {
- bool spriteEnd = false;
-
- // Set entire sprite contents to transparent pixels
- fillRect(bounds(), TRANSPARENT_COLOR_INDEX);
-
- // Major line loop
- for (int yp = 0; yp < h; ++yp) {
- byte *destP = getBasePtr(0, yp);
- bool newLine = false;
- byte cmd = source->readByte();
- int x2 = 0;
-
- if (cmd == 0xfc) {
- // End of entire sprite
- spriteEnd = true;
- break;
- } else if (cmd == 0xff) {
- // The entire line is empty
- newLine = true;
- } else if (cmd == 0xFD) {
- // Lines contains only run lenghs of pixels
- while (x2 < w) {
- cmd = source->readByte();
- if (cmd == 0xff) {
- // End of line reached
- newLine = true;
- break;
- }
-
- byte v = source->readByte();
- while (cmd-- > 0) {
- if (x2 < w)
- *destP++ = (v == 0xFD) ? TRANSPARENT_COLOR_INDEX : v;
- ++x2;
- }
- }
- } else {
- // Line intermixes run lengths with individual pixels
- while (x2 < w) {
- cmd = source->readByte();
- if (cmd == 0xff) {
- // End of line reached
- newLine = true;
- break;
- }
-
- if (cmd == 0xFE) {
- // Handle repeated sequence
- cmd = source->readByte();
- byte v = source->readByte();
- while (cmd-- > 0) {
- if (x2 < w) {
- *destP++ = (v == 0xFD) ? TRANSPARENT_COLOR_INDEX : v;
- }
- ++x2;
- }
- } else {
- // Handle writing out single pixel
- *destP++ = (cmd == 0xFD) ? TRANSPARENT_COLOR_INDEX : cmd;
- ++x2;
- }
- }
- }
-
- // Check if we need to scan forward to find the end of the line
- if (!newLine) {
- do {
- if (source->eos()) {
- warning("M4Sprite::loadMadsSprite: unexpected end of data");
- break;
- }
- } while (source->readByte() != 0xff);
- }
- }
-
- if (!spriteEnd) {
- byte v = source->readByte();
- assert(v == 0xFC);
- }
-}
-
-byte M4Sprite::getTransparencyIndex() const {
- return TRANSPARENT_COLOR_INDEX;
-}
-
-} // End of namespace M4
diff --git a/engines/m4/sprite.h b/engines/m4/sprite.h
deleted file mode 100644
index af49d8cbaf..0000000000
--- a/engines/m4/sprite.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_SPRITE_H
-#define M4_SPRITE_H
-
-#include "common/util.h"
-#include "common/endian.h"
-#include "common/stream.h"
-#include "m4/graphics.h"
-
-/*
- TODO:
- - change DrawRequestX and RendCell
-*/
-
-namespace M4 {
-
-typedef struct
-{
- int32 x; // x position relative to GrBuff(0, 0)
- int32 y; // y position relative to GrBuff(0, 0)
- int32 scale_x; // x scale factor (can be negative for reverse draw)
- int32 scale_y; // y scale factor (can't be negative)
- uint8* depth_map; // depth code array for destination (doesn't care if srcDepth is 0)
- BGR8 *Pal; // palette for shadow draw (doesn't care if SHADOW bit is not set in Src.encoding)
- uint8* ICT; // Inverse Color Table (doesn't care if SHADOW bit is not set in Src.encoding)
- uint8 depth; // depth code for source (0 if no depth processing)
-} DrawRequestX;
-
-typedef struct
-{
- uint32 Pack;
- uint32 Stream;
- long hot_x;
- long hot_y;
- uint32 Width;
- uint32 Height;
- uint32 Comp;
- uint32 Reserved[8];
- uint8* data;
-} RendCell;
-
-#define SS_HEADER_NUM_FIELDS 14
-struct SpriteSeriesHeader {
- uint32 header;
- uint32 size;
- uint32 packing;
- uint32 frameRate;
- uint32 pixSpeed;
- uint32 maxWidth;
- uint32 maxHeight;
- uint32 reserved3;
- uint32 reserved4;
- uint32 reserved5;
- uint32 reserved6;
- uint32 reserved7;
- uint32 reserved8;
- uint32 count;
-};
-
-#define SF_HEADER_NUM_FIELDS 15
-struct SpriteFrameHeader {
- uint32 pack;
- uint32 stream;
- uint32 x;
- uint32 y;
- uint32 width;
- uint32 height;
- uint32 comp;
- uint32 reserved1;
- uint32 reserved2;
- uint32 reserved3;
- uint32 reserved4;
- uint32 reserved5;
- uint32 reserved6;
- uint32 reserved7;
- uint32 reserved8;
-};
-
-class M4Sprite : public M4Surface {
-public:
- int x, y;
- int xOffset, yOffset;
- uint8 encoding;
-
- M4Sprite(MadsM4Engine *vm): M4Surface() {}
- M4Sprite(MadsM4Engine *vm, int widthVal, int heightVal): M4Surface(widthVal, heightVal), xOffset(0), yOffset(0) {}
- // Loads a sprite from the given stream, and optionally decompresses the RLE-encoded data
- M4Sprite(Common::SeekableReadStream* source, int xOfs, int yOfs, int widthVal, int heightVal, bool decodeRle = true, uint8 encodingVal = 0);
- // Loads an RLE compressed sprite; the surface must have been created before
- void loadRle(Common::SeekableReadStream* rleData);
- void loadDeltaRle(Common::SeekableReadStream* rleData, int destX, int destY);
- void loadMadsSprite(Common::SeekableReadStream* source);
-
- byte getTransparencyIndex() const;
-protected:
-};
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/staticres.cpp b/engines/m4/staticres.cpp
deleted file mode 100644
index 520c0ad58e..0000000000
--- a/engines/m4/staticres.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/staticres.h"
-
-namespace M4 {
-
-const char *englishMADSArticleList[9] = {
- NULL, "with", "to", "at", "from", "on", "in", "under", "behind"
-};
-
-const char *cheatingEnabledDesc[3] = {
- "CHEATING ENABLED",
- "(For your convenience).",
- NULL
-};
-
-const char *atStr = "at";
-const char *lookAroundStr = "Look around";
-const char *toStr = "to ";
-const char *useStr = "Use ";
-const char *walkToStr = "Walk to ";
-const char *fenceStr = "fence";
-const char *overStr = "over";
-
-const char *GameReleaseInfoStr = "ScummVM rev: 8.43 14-Sept-92";
-const char *GameReleaseTitleStr = "GAME RELASE VERSION INFO";
-
-VerbInit verbList[10] = {
- {kVerbLook, 2, 0},
- {kVerbTake, 2, 0},
- {kVerbPush, 2, 0},
- {kVerbOpen, 2, 0},
- {kVerbPut, 1, -1},
- {kVerbTalkTo, 2, 0},
- {kVerbGive, 1, 2},
- {kVerbPull, 2, 0},
- {kVerbClose, 2, 0},
- {kVerbThrow, 1, 3}
-};
-
-} // End of namespace M4
diff --git a/engines/m4/staticres.h b/engines/m4/staticres.h
deleted file mode 100644
index e3ead3398b..0000000000
--- a/engines/m4/staticres.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_STATICRES_H
-#define M4_STATICRES_H
-
-#include "common/scummsys.h"
-#include "m4/m4.h"
-
-namespace M4 {
-
-extern const char *englishMADSArticleList[9];
-
-extern const char *cheatingEnabledDesc[3];
-
-extern const char *atStr;
-extern const char *lookAroundStr;
-extern const char *toStr;
-extern const char *useStr;
-extern const char *walkToStr;
-extern const char *fenceStr;
-extern const char *overStr;
-
-extern const char *GameReleaseInfoStr;
-extern const char *GameReleaseTitleStr;
-
-struct VerbInit {
- int verb;
- int8 flag1;
- int8 flag2;
-};
-
-extern VerbInit verbList[10];
-
-} // End of namespace M4
-
-#endif
diff --git a/engines/m4/viewmgr.cpp b/engines/m4/viewmgr.cpp
deleted file mode 100644
index 8eb40f0f17..0000000000
--- a/engines/m4/viewmgr.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-// TODO: Views have a _coords rect, so I'm not sure if x/y is needed in the onRefresh
-
-#include "m4/m4.h"
-#include "m4/viewmgr.h"
-#include "m4/mads_anim.h"
-
-namespace M4 {
-
-void returnToMainMenuFn(MadsM4Engine *vm) {
- vm->_palette->resetColorCounts();
- vm->_palette->setMadsSystemPalette();
-
- vm->loadMenu(MAIN_MENU);
-}
-
-RectList::RectList() {
-}
-
-RectList::~RectList() {
-}
-
-void RectList::addRect(int x1, int y1, int x2, int y2) {
- addRect(Common::Rect(x1, y1, x2, y2));
-}
-
-void RectList::addRect(const Common::Rect &rect) {
- /* TODO:
- Implement the following:
- - Don't add the Rect if it's contained in any Rect in the list
- - Split up the Rect if it intersects any Rect in the list
- and add the resulting partial Rects instead
- */
- push_back(rect);
-}
-
-int RectList::find(const Common::Point &pt) {
- for (uint idx = 0; idx < size(); ++idx) {
- if (this->operator [](idx).contains(pt.x, pt.y))
- return idx;
- }
- return -1;
-}
-
-//--------------------------------------------------------------------------
-
-HotkeyList::HotkeyList(View *owner) : _view(owner) {
-}
-
-HotkeyList::~HotkeyList() {
- for (uint32 i = 0; i < _hotkeys.size(); i++)
- delete _hotkeys[i];
-}
-
-void HotkeyList::add(uint32 key, Hotkey::Callback callback) {
- _hotkeys.push_back(new Hotkey(key, callback));
-}
-
-void HotkeyList::remove(uint32 key) {
- for (uint32 i = 0; i < _hotkeys.size(); i++) {
- if (_hotkeys[i]->key == key) {
- delete _hotkeys[i];
- _hotkeys.remove_at(i);
- break;
- }
- }
-}
-
-bool HotkeyList::call(uint32 key) {
- for (uint32 i = 0; i < _hotkeys.size(); i++) {
- if (_hotkeys[i]->key == key) {
- if (_hotkeys[i]->callback)
- (_hotkeys[i]->callback)(_vm, _view, key);
- return true;
- }
- }
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-// View constructor
-
-View::View(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent)
- : M4Surface(viewBounds.width(), viewBounds.height()), _hotkeys(this), _vm(vm) {
- SCREEN_FLAGS_DEFAULT;
- _coords = viewBounds;
- _transparent = transparent;
-}
-
-View::View(MadsM4Engine *vm, int x, int y, bool transparent)
- : M4Surface(), _hotkeys(this), _vm(vm) {
- SCREEN_FLAGS_DEFAULT;
- _coords.left = x;
- _coords.top = y;
- _coords.right = _vm->_screen->width();
- _coords.bottom = _vm->_screen->height();
- _transparent = transparent;
-}
-
-void View::getCoordinates(Common::Rect &rect) {
- rect = _coords;
-}
-
-void View::extract(int *status) {
-}
-
-void View::show() {
- _screenFlags.visible = true;
- _vm->_viewManager->moveToFront(this);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::hide() {
- _screenFlags.visible = false;
- _vm->_viewManager->restore(_coords);
-}
-
-void View::moveToBack() {
- _vm->_viewManager->moveToBack(this);
-}
-
-void View::moveAbsolute(int x, int y) {
- // TODO: Handle clipping and offscreen
- Common::Rect oldCoords = _coords;
- _coords.moveTo(x, y);
- _vm->_viewManager->restore(oldCoords);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::moveRelative(int x, int y) {
- // TODO: Handle clipping and offscreen
- Common::Rect oldCoords = _coords;
- _coords.translate(x, y);
- _vm->_viewManager->restore(oldCoords);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::resize(int newWidth, int newHeight) {
- Common::Rect oldCoords = _coords;
- if (newWidth >= 0)
- _coords.setWidth(newWidth);
- if (newHeight >= 0)
- _coords.setHeight(newHeight);
- _vm->_viewManager->restore(oldCoords);
- _vm->_viewManager->restore(_coords);
-}
-
-void View::restore(int x1, int y1, int x2, int y2) {
- _vm->_viewManager->restore(_coords.left + x1, _coords.top + y1, _coords.left + x2, _coords.top + y2);
-}
-
-void View::onRefresh(RectList *rects, M4Surface *destSurface) {
- assert(destSurface);
-
- if (rects == NULL)
- // No rect list specified, so copy entire surface
- copyTo(destSurface, _coords.left, _coords.top, _transparent ? 0 : -1);
- else {
- // Loop through the set of specified rectangles
- RectList::iterator i;
- for (i = rects->begin(); i != rects->end(); ++i) {
- Common::Rect &destRect = *i;
- Common::Rect srcBounds(destRect.left - _coords.left, destRect.top - _coords.top,
- destRect.right - _coords.left, destRect.bottom - _coords.top);
- copyTo(destSurface, srcBounds, destRect.left, destRect.top, _transparent ? 0 : -1);
- }
- }
-}
-
-//--------------------------------------------------------------------------
-
-ViewManager::ViewManager(MadsM4Engine *vm): _systemHotkeys(HotkeyList(NULL)), _vm(vm) {
- _captureScreen = NULL;
- _captureEvents = false;
-}
-
-ViewManager::~ViewManager() {
- // Delete any remaining active views
- ListIterator i;
- for (i = _views.begin(); i != _views.end(); ++i)
- delete (*i);
-}
-
-void ViewManager::addView(View *view) {
- _views.push_back(view);
- moveToFront(view);
-}
-
-// Warning: After calling this method, the passed view object will no longer be valid
-
-void ViewManager::deleteView(View *view) {
- _views.remove(view);
- delete view;
-}
-
-void ViewManager::handleEvents(const Common::Event &event) {
-}
-
-void ViewManager::handleKeyboardEvents(uint32 keycode) {
- Common::Point mousePos = _vm->_mouse->currentPos();
- View *view;
- bool blockedFlag;
- bool foundFlag;
- bool handledFlag;
-
- // Scan view list for one which accepts or blocks keyboard events. If one is found,
- // then the event is passed to it
-
- view = NULL;
- handledFlag = false;
- foundFlag = false;
- blockedFlag = false;
-
- // Loop from the front to back view
- ListIterator i;
- for (i = _views.reverse_begin(); (i != _views.end()) && !foundFlag; --i) {
- view = *i;
- if (!view->isVisible()) continue;
-
- if (view->screenFlags().blocks & SCREVENT_KEY)
- blockedFlag = true;
- if (view->screenFlags().get & SCREVENT_KEY) {
- foundFlag = true;
- handledFlag = (view->onEvent)(KEVENT_KEY, keycode, mousePos.x, mousePos.y, _captureEvents);
- if (_captureEvents)
- _captureScreen = view;
- }
- }
-
- // Scan view list for one with a hotkey list, aborting if a view is found that either
- // blocks keyboard events, or has a hotkey list that includes the keycode
-
- blockedFlag = false;
- for (i = _views.reverse_begin(); (i != _views.end()) && !foundFlag && !blockedFlag; --i) {
- view = *i;
- if (!view->isVisible()) continue;
-
- if (view->screenFlags().blocks & SCREVENT_KEY)
- blockedFlag = true;
- if (view->screenFlags().get & SCREVENT_KEY) {
- if (view->hotkeys().call(keycode)) {
- handledFlag = true;
- _captureEvents = false;
- //_vm->_dialogs->keyMouseCollision(); // TODO
- }
- }
- }
-
- // Final check: if no view handled or blocked the key, check against the system hotkey list
-
- if (!handledFlag && !blockedFlag) {
- handledFlag = _systemHotkeys.call(keycode);
- if (handledFlag) {
- _captureEvents = false;
- //_vm->_dialogs->keyMouseCollision(); // TODO
- }
- }
-}
-
-void ViewManager::handleMouseEvents(M4EventType event) {
- Common::Point mousePos = _vm->_mouse->currentPos();
- ListIterator i;
- View *view;
- bool blockedFlag;
- bool foundFlag;
-
- // If a window sets the _captureEvents flag to true, it will receive all events until
- // it sets it to false, even if it's not the top window
- if (_captureEvents) {
- assert(_captureScreen);
- if (_captureScreen->screenFlags().get & SCREVENT_MOUSE)
- (_captureScreen->onEvent)(event, 0, mousePos.x, mousePos.y, _captureEvents);
-
- } else {
- blockedFlag = false;
- foundFlag = false;
- view = NULL;
-
- // Loop from the front to back view
- for (i = _views.reverse_begin(); (i != _views.end()) && !foundFlag && !blockedFlag; --i) {
- view = *i;
- if (!view->isVisible()) continue;
-
- if (view->screenFlags().blocks & SCREVENT_MOUSE)
- blockedFlag = true;
- if ((view->screenFlags().get & SCREVENT_MOUSE) && view->isInside(mousePos.x, mousePos.y))
- foundFlag = true;
- }
-
- if (foundFlag)
- view->onEvent(event, 0, mousePos.x, mousePos.y, _captureEvents);
- else
- _captureEvents = false;
- if (_captureEvents)
- _captureScreen = view;
- }
-}
-
-void ViewManager::restore(int x1, int y1, int x2, int y2) {
- RectList *rl = new RectList();
- Common::Rect redrawBounds(x1, y1, x2, y2);
- rl->addRect(x1, y1, x2, y2);
-
- for (ListIterator i = _views.begin(); i != _views.end(); ++i) {
- View *v = *i;
-
- if (v->isVisible() && v->bounds().intersects(redrawBounds))
- v->onRefresh(rl, _vm->_screen);
- }
-
- _vm->_screen->update();
-
-}
-
-void ViewManager::restore(const Common::Rect &rect) {
- restore(rect.left, rect.top, rect.right, rect.bottom);
-}
-
-void ViewManager::moveToFront(View *view) {
- if (_views.size() < 2)
- return;
-
- _views.remove(view);
-
- ListIterator i = _views.begin();
- while ((i != _views.end()) && ((*i)->layer() <= view->layer()))
- ++i;
-
- _views.insert(i, view);
-}
-
-void ViewManager::moveToBack(View *view) {
- if (_views.size() < 2)
- return;
-
- _views.remove(view);
-
- ListIterator i = _views.begin();
- while ((i != _views.end()) && ((*i)->layer() < view->layer()))
- ++i;
-
- _views.insert(i, view);
-}
-
-View *ViewManager::getView(int screenType) {
- ListIterator i = _views.begin();
- while (i != _views.end()) {
- if ((*i)->screenType() == screenType)
- return *i;
- ++i;
- }
-
- return NULL;
-}
-
-void ViewManager::updateState() {
- Common::List<View *> viewList = _views;
-
- for (ListIterator i = viewList.begin(); i != viewList.end(); ++i) {
- if (_vm->_events->quitFlag)
- return;
-
- View *v = *i;
- v->updateState();
- }
-}
-
-void ViewManager::refreshAll() {
- _vm->_screen->clear();
-
- for (ListIterator i = _views.begin(); i != _views.end(); ++i) {
- View *v = *i;
-
- if (v->isVisible())
- v->onRefresh(NULL, _vm->_screen);
- }
-
- _vm->_screen->update();
-}
-
-void ViewManager::showTextView(const char *textViewName, bool returnToMainMenu) {
- // Deactivate the scene if it's currently active
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Deactivate the main menu if it's currently active
- view = _vm->_viewManager->getView(VIEWID_MAINMENU);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Activate the textview view
- _vm->_font->setFont(FONT_CONVERSATION_MADS);
- TextviewView *textView = new TextviewView(_vm);
- _vm->_viewManager->addView(textView);
- if (returnToMainMenu)
- textView->setScript(textViewName, returnToMainMenuFn);
- else
- textView->setScript(textViewName, NULL);
-}
-
-void ViewManager::showAnimView(const char *animViewName, bool returnToMainMenu) {
- // Deactivate the scene if it's currently active
- View *view = _vm->_viewManager->getView(VIEWID_SCENE);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Deactivate the main menu if it's currently active
- view = _vm->_viewManager->getView(VIEWID_MAINMENU);
- if (view != NULL)
- _vm->_viewManager->deleteView(view);
-
- // Activate the animview view
- AnimviewView *animView = new AnimviewView(_vm);
- _vm->_viewManager->addView(animView);
- if (returnToMainMenu)
- animView->setScript(animViewName, returnToMainMenuFn);
- else
- animView->setScript(animViewName, NULL);
-}
-
-} // End of namespace M4
diff --git a/engines/m4/viewmgr.h b/engines/m4/viewmgr.h
deleted file mode 100644
index bb4f76cfaa..0000000000
--- a/engines/m4/viewmgr.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_VIEWMGR_H
-#define M4_VIEWMGR_H
-
-#include "common/algorithm.h"
-#include "common/array.h"
-#include "common/list.h"
-#include "common/events.h"
-#include "common/rect.h"
-
-#include "m4/font.h"
-#include "m4/globals.h"
-#include "m4/events.h"
-#include "m4/graphics.h"
-
-namespace M4 {
-
-class View;
-class ViewManager;
-
-enum SceneTransition {
- kTransitionNone = 0,
- kTransitionFadeIn = 1,
- kTransitionFadeIn2 = 2,
- kTransitionBoxInBottomLeft = 3,
- kTransitionBoxInBottomRight = 4,
- kTransitionBoxInTopLeft = 5,
- kTransitionBoxInTopRight = 6,
- kTransitionPanLeftToRight = 7,
- kTransitionPanRightToLeft = 8,
- kTransitionCircleIn = 9
-};
-
-enum {SCREEN_DIALOG, SCREEN_BUFFER, SCREEN_TEXT, SCREEN_TRANSPARENT};
-enum ScreenEventType {SCREVENT_NONE = 0, SCREVENT_KEY = 1, SCREVENT_MOUSE = 2, SCREVENT_ALL = 3};
-enum ScreenLayers {
- LAYER_BACKGROUND = 0, LAYER_DRIFTER = 1, LAYER_INTERFACE = 1, LAYER_FLOATER = 2,
- LAYER_SURFACE = 3, LAYER_MENU = 9, LAYER_DIALOG = 10, LAYER_MOUSE = 15
-};
-
-enum ViewIds {
- VIEWID_MAINMENU = 1,
- VIEWID_SCENE = 2,
- VIEWID_TEXTVIEW = 3,
- VIEWID_ANIMVIEW = 4,
- VIEWID_MENU = 69,
- VIEWID_CONVERSATION = 48,
- VIEWID_INTERFACE = 49
-};
-
-struct ScreenFlags {
- bool visible:1;
- bool transparent:1;
- bool immovable:1;
-
- enum ScreenEventType blocks:2;
- enum ScreenEventType get:2;
-
- uint layer:4;
-};
-
-#define SCREEN_FLAGS_DEFAULT _screenFlags.layer = LAYER_DRIFTER; \
- _screenFlags.get = SCREVENT_ALL; _screenFlags.blocks = SCREVENT_NONE; \
- _screenFlags.visible = true;
-#define SCREEN_FLAGS_ALERT _screenFlags.layer = LAYER_FLOATER \
- _screenFlags.get = SCREVENT_ALL; _screenFlags.blocks = SCREVENT_ALL; \
- _screenFlags.visible = true;
-
-class RectList : public Common::Array<Common::Rect> {
-public:
- RectList();
- ~RectList();
- void addRect(int x1, int y1, int x2, int y2);
- void addRect(const Common::Rect &rect);
-
-// Common::Rect& operator [](int idx) { return _rects[idx]; }
- int find(const Common::Point &pt);
-};
-
-struct Hotkey {
-public:
- typedef void (*Callback)(MadsM4Engine *vm, View *view, uint32 key);
- Hotkey(uint32 keyVal, Hotkey::Callback callbackFn) : key(keyVal), callback(callbackFn) {}
- uint32 key;
- Hotkey::Callback callback;
-};
-
-class HotkeyList {
-public:
- HotkeyList(View *owner);
- ~HotkeyList();
- void add(uint32 key, Hotkey::Callback callback);
- void remove(uint32 key);
- bool call(uint32 key);
-private:
- Common::Array<Hotkey*> _hotkeys;
- View *_view;
-};
-
-class View : public M4Surface {
-public:
- View(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent = false);
- View(MadsM4Engine *vm, int x = 0, int y = 0, bool transparent = false);
- virtual ~View() {}
-
- void getCoordinates(Common::Rect &rect);
- void extract(int *status);
- virtual void show();
- virtual void hide();
- void moveToFront() {}
- void moveToBack();
- void moveAbsolute(int x, int y);
- void moveRelative(int x, int y);
- void resize(int newWidth, int newHeight);
- void restore(int x1, int y1, int x2, int y2);
-
- Common::Rect bounds() const { return _coords; }
- bool isInside(int x, int y) const { return _coords.contains(x, y); }
- ScreenFlags screenFlags() const { return _screenFlags; }
- int screenType() const { return _screenType; }
- bool isOffscreen() const { return !_screenFlags.visible; }
- bool isTransparent() const { return _screenFlags.transparent; }
- bool isVisible() const { return _screenFlags.visible; }
- uint layer() const { return _screenFlags.layer; }
- HotkeyList &hotkeys() { return _hotkeys; }
-
- virtual void onRefresh(RectList *rects, M4Surface *destSurface);
- virtual bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) { return false; }
- virtual void updateState() {}
-
-protected:
- MadsM4Engine *_vm;
- Common::Rect _coords;
- HotkeyList _hotkeys;
- int _screenType;
- ScreenFlags _screenFlags;
- bool _transparent;
-};
-
-class ViewManager {
-private:
- MadsM4Engine *_vm;
- HotkeyList _systemHotkeys;
- Common::List<View *> _views;
- View *_captureScreen;
- bool _captureEvents;
-public:
- typedef Common::List<View *>::iterator ListIterator;
-
- ViewManager(MadsM4Engine *vm);
- ~ViewManager();
-
- void addView(View *view);
- void deleteView(View *view);
-
- void handleEvents(const Common::Event &event);
- void handleKeyboardEvents(uint32 keycode);
- void handleMouseEvents(M4EventType event);
- void restore(int x1, int y1, int x2, int y2);
- void restore(const Common::Rect &rect);
-
- void moveToFront(View *view);
- void moveToBack(View *view);
-
- Common::List<View *> views() const { return _views; }
- bool contains(View *key) const {
- return Common::find(_views.begin(), _views.end(), key) != _views.end();
- }
- bool contains(int screenType) { return getView(screenType) != NULL; }
- View *getView(int screenType);
- int containsViews() { return !_views.empty(); }
-
- void showTextView(const char *textViewName, bool returnToMainMenu = true);
- void showAnimView(const char *animViewName, bool returnToMainMenu = true);
-
- void updateState();
- void refreshAll();
- HotkeyList &systemHotkeys() { return _systemHotkeys; }
-};
-
-}
-
-#endif
diff --git a/engines/m4/woodscript.cpp b/engines/m4/woodscript.cpp
deleted file mode 100644
index 42f4fbce98..0000000000
--- a/engines/m4/woodscript.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/woodscript.h"
-
-#include "common/memstream.h"
-#include "graphics/palette.h"
-
-namespace M4 {
-
-// FIXME: Put in Engine/WoodScript class
-RGB8 _mainPalette[256];
-
-//Woodscript Assembler/Compiler
-
-int32 Bytecode::_dataFormats[] = {0, 5, 8, 12, 16};
-
-Bytecode::Bytecode(WoodScript *ws, byte *code, int32 codeSize, Sequence *seq) {
- _ws = ws;
- _code = new Common::MemoryReadStream(code, codeSize);
- _sequence = seq;
-}
-
-Bytecode::~Bytecode() {
- delete _code;
-}
-
-int Bytecode::loadInstruction(Instruction &instruction) {
-
- //debugCN(kDebugScript, "Bytecode::loadInstruction() ip = %08X\n", _code->pos());
-
- int32 format, data;
- uint32 code, code2;
-
- code = _code->readUint32LE();
-
- instruction.instr = (code >> 25) & 0xFF;
- instruction.argp[0] = NULL;
- instruction.argp[1] = NULL;
- instruction.argp[2] = NULL;
- instruction.argc = 0;
-
- // Maybe make this a for-loop?
-
- format = (code >> 22) & 7;
- if (format) {
- /* Load argument 1 */
- data = code & 0xFFFF;
- decodeArgument(format, data, instruction.argp[0], instruction.argv[0]);
- instruction.argc++;
- /* Load argument 2 */
- format = (code >> 19) & 7;
- if (format) {
- code2 = _code->readUint32LE();
- data = (code2 >> 16) & 0xFFFF;
- decodeArgument(format, data, instruction.argp[1], instruction.argv[1]);
- instruction.argc++;
- /* Load argument 3 */
- format = (code >> 16) & 7;
- if (format) {
- data = code2 & 0xFFFF;
- decodeArgument(format, data, instruction.argp[2], instruction.argv[2]);
- instruction.argc++;
- }
- }
- }
-
- return 0; //FIXME check if instruction size is needed by caller
-
-}
-
-void Bytecode::jumpAbsolute(int32 ofs) {
- _code->seek(ofs * 4);
- //debugCN(kDebugScript, "Bytecode::jumpAbsolute() ofs = %08X\n", _code->pos());
-}
-
-void Bytecode::jumpRelative(int32 ofs) {
- _code->seek(ofs * 4, SEEK_CUR);
-}
-
-void Bytecode::setSequence(Sequence *seq) {
- _sequence = seq;
-}
-
-void Bytecode::setCode(byte *code, int32 codeSize) {
- delete _code;
- _code = new Common::MemoryReadStream(code, codeSize);
-}
-
-Sequence *Bytecode::sequence() const {
- assert(_sequence);
- return _sequence;
-}
-
-bool Bytecode::decodeArgument(int32 format, int32 data, long *&arg, long &value) {
-
- int32 index;
-
- if (format == 1) {
- if (data & 0x8000)
- index = _sequence->indexReg();
- else
- index = data & 0x0FFF;
- switch (data & 0x7000) {
- case 0x0000:
- arg = sequence()->getParentVarPtr(index);
- value = *arg;
- break;
- case 0x1000:
- arg = sequence()->getVarPtr(index);
- value = *arg;
- break;
- case 0x2000:
- arg = sequence()->getDataPtr(index);
- value = *arg;
- break;
- }
- } else if (format == 2) {
- if (data & 0x8000)
- index = _sequence->indexReg();
- else
- index = data & 0x0FFF;
- arg = _ws->getGlobalPtr(index);
- value = *arg;
- } else {
- if (data & 0x8000) {
- value = -(data & 0x7FFF) << (_dataFormats[format - 3]);
- } else {
- value = (data & 0x7FFF) << (_dataFormats[format - 3]);
- }
- arg = &value;
- }
-
- return true;
-}
-
-WoodScript::WoodScript(MadsM4Engine *vm) {
- _vm = vm;
- _machineId = 0;
- _assets = new AssetManager(vm);
- _globals = new long[256]; //FIXME Find out how many globals there should be
- memset(_globals, 0, sizeof(long));
-
- _backgroundSurface = NULL;
-
- //Common::Rect viewBounds = Common::Rect(0, 0, 640, 480);
- //_surfaceView = new View(viewBounds);
-}
-
-WoodScript::~WoodScript() {
- delete _assets;
- delete[] _globals;
-}
-
-Sequence *WoodScript::createSequence(Machine *machine, int32 sequenceHash) {
- Sequence *sequence = new Sequence(this, machine, sequenceHash);
- _sequences.push_back(sequence);
- _layers.push_back(sequence);
- return sequence;
-}
-
-void WoodScript::runSequencePrograms() {
- // A lot TODO
- for (Common::Array<Sequence*>::iterator it = _sequences.begin(); it != _sequences.end(); ++it) {
- Sequence *sequence = *it;
- if (sequence->isActive()) {
- sequence->runProgram();
- if (sequence->isTerminated() && sequence->hasEndOfSequenceRequestPending()) {
- _endOfSequenceRequestList.push_back(sequence);
- }
- }
- }
-}
-
-void WoodScript::runEndOfSequenceRequests() {
-}
-
-void WoodScript::runTimerSequenceRequests() {
-}
-
-Machine *WoodScript::createMachine(int32 machineHash, Sequence *parentSeq,
- int32 dataHash, int32 dataRowIndex, int callbackHandler, const char *machineName) {
-
- //debugCN(kDebugScript, "WoodScript::createMachine(%d)\n", machineHash);
-
- Machine *machine = new Machine(this, machineHash, parentSeq, dataHash, dataRowIndex, callbackHandler, machineName, _machineId);
- _machineId++;
-
- _machines.push_back(machine);
-
- // goto first state for initialization
- machine->enterState();
-
- return machine;
-}
-
-int32 WoodScript::loadSeries(const char* seriesName, int32 hash, RGB8* palette) {
- return _assets->addSpriteAsset(seriesName, hash, palette);
-}
-
-void WoodScript::unloadSeries(int32 hash) {
- _assets->clearAssets(kAssetTypeCELS, hash, hash);
-}
-
-void WoodScript::setSeriesFramerate(Machine *machine, int32 frameRate) {
-}
-
-Machine *WoodScript::playSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 frameRate, int32 loopCount, int32 s, int32 x, int32 y,
- int32 firstFrame, int32 lastFrame) {
-
- //debugCN(kDebugScript, "WoodScript::playSeries(%s)\n", seriesName);
-
- RGB8 *palette = NULL;
- if (flags & SERIES_LOAD_PALETTE)
- palette = &_mainPalette[0];
-
- int32 spriteHash = _assets->addSpriteAsset(seriesName, -1, palette);
-
- _globals[kGlobTemp1] = (long)spriteHash << 24;
- _globals[kGlobTemp2] = layer << 16;
- _globals[kGlobTemp3] = _vm->_kernel->createTrigger(triggerNum);
- _globals[kGlobTemp4] = frameRate << 16;
- _globals[kGlobTemp5] = loopCount << 16;
- _globals[kGlobTemp6] = (s << 16) / 100;
- _globals[kGlobTemp7] = x << 16;
- _globals[kGlobTemp8] = y << 16;
- _globals[kGlobTemp9] = firstFrame << 16;
- _globals[kGlobTemp10] = lastFrame << 16;
- _globals[kGlobTemp11] = (flags & SERIES_PINGPONG) ? 0x10000 : 0;
- _globals[kGlobTemp12] = (flags & SERIES_BACKWARD) ? 0x10000 : 0;
- _globals[kGlobTemp13] = (flags & SERIES_RANDOM) ? 0x10000 : 0;
- _globals[kGlobTemp14] = (flags & SERIES_STICK) ? 0x10000 : 0;
- _globals[kGlobTemp15] = (flags & SERIES_LOOP_TRIGGER) ? 0x10000 : 0;
- _globals[kGlobTemp16] = (flags & SERIES_HORZ_FLIP) ? 0x10000 : 0;
-
- return createMachine(0, NULL, -1, -1, kCallbackTriggerDispatch, seriesName);
-
-}
-
-Machine *WoodScript::showSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 duration, int32 index, int32 s, int32 x, int32 y) {
-
- RGB8 *palette = NULL;
- if (flags & SERIES_LOAD_PALETTE)
- palette = &_mainPalette[0];
-
- int32 spriteHash = _assets->addSpriteAsset(seriesName, -1, palette);
-
- _globals[kGlobTemp1] = spriteHash << 24;
- _globals[kGlobTemp2] = layer << 16;
- _globals[kGlobTemp3] = _vm->_kernel->createTrigger(triggerNum);
- _globals[kGlobTemp4] = duration << 16;
- _globals[kGlobTemp5] = index << 16;
- _globals[kGlobTemp6] = (s << 16) / 100;
- _globals[kGlobTemp7] = x << 16;
- _globals[kGlobTemp8] = y << 16;
- _globals[kGlobTemp14] = (flags & SERIES_STICK) ? 0x10000 : 0;
- _globals[kGlobTemp16] = (flags & SERIES_HORZ_FLIP) ? 0x10000 : 0;
-
- return createMachine(1, NULL, -1, -1, kCallbackTriggerDispatch, seriesName);
-
-}
-
-Machine *WoodScript::streamSeries(const char *seriesName, int32 frameRate, long layer, int32 triggerNum) {
- //debugCN(kDebugScript, "WoodScript::streamSeries(%s)\n", seriesName);
- _globals[kGlobTemp1] = frameRate << 16;
- /* FIXME: Single frames from a stream series will be decompressed on-the-fly, contrary to
- "normal" sprite series, to save some memory, and since no random access to single
- frames is needed, this is ok.
- */
- _globals[kGlobTemp4] = 0; // The actual stream is opened in the Sequence
- _globals[kGlobTemp5] = 0;//TODO: kernel_trigger_create(triggerNum); // trigger
- _globals[kGlobTemp6] = layer << 16; // layer
- return createMachine(6, NULL, -1, -1, kCallbackTriggerDispatch, seriesName);
-}
-
-void WoodScript::update() {
- // TODO: Don't show hidden sequences etc.
-
- // TODO: For now, prevent any engine action if a menu is being displayed - eventually this should be
- // changed to a proper check of the engine paused variable, which the menus should set while active
- if (_vm->_viewManager->getView(VIEWID_MENU) != NULL)
- return;
-
- //TODO: Include _pauseTime
- uint32 clockTime = g_system->getMillis() / 60; // FIXME: g_system
- _globals[kGlobTimeDelta] = clockTime - _globals[kGlobTime];
- _globals[kGlobTime] += _globals[kGlobTimeDelta];
-
- runSequencePrograms();
-
- if (_backgroundSurface) {
- // FIXME: For now, copy the whole surface. Later, copy only the rectangles that need updating.
- _backgroundSurface->copyTo(_surfaceView);
- } else {
- // "This should never happen."
- _surfaceView->fillRect(Common::Rect(0, 0, 640, 480), 0);
- }
-
- {
- // FIXME: This should be done when a new palette is set
- byte palette[768];
- g_system->getPaletteManager()->grabPalette(palette, 0, 256);
- for (int i = 0; i < 256; i++) {
- _mainPalette[i].r = palette[i * 3 + 0];
- _mainPalette[i].g = palette[i * 3 + 1];
- _mainPalette[i].b = palette[i * 3 + 2];
- }
- }
-
- for (Common::Array<Sequence*>::iterator it = _layers.begin(); it != _layers.end(); ++it) {
- Sequence *sequence = *it;
-
- // TODO: Use correct clipRect etc.
- Common::Rect clipRect = Common::Rect(0, 0, 640, 480);
- Common::Rect updateRect;
-
- sequence->draw(_surfaceView, clipRect, updateRect);
-
- }
-
- // Handle end-of-sequence requests
- if (_endOfSequenceRequestList.size() > 0) {
- for (Common::Array<Sequence*>::iterator it = _endOfSequenceRequestList.begin(); it != _endOfSequenceRequestList.end(); ++it) {
- Sequence *sequence = *it;
-
- EndOfSequenceRequestItem endOfSequenceRequestItem = sequence->getEndOfSequenceRequestItem();
- sequence->getMachine()->execBlock(endOfSequenceRequestItem.codeOffset, endOfSequenceRequestItem.count);
- }
- _endOfSequenceRequestList.clear();
- }
-
-}
-
-void WoodScript::clear() {
-
- for (Common::Array<Sequence*>::iterator it = _sequences.begin(); it != _sequences.end(); ++it)
- delete *it;
- _sequences.clear();
-
- for (Common::Array<Machine*>::iterator it = _machines.begin(); it != _machines.end(); ++it)
- delete *it;
- _machines.clear();
-
- _layers.clear();
- _endOfSequenceRequestList.clear();
-
-}
-
-void WoodScript::setDepthTable(int16 *depthTable) {
- _depthTable = depthTable;
-}
-
-long *WoodScript::getGlobalPtr(int index) {
- return &_globals[index];
-}
-
-long WoodScript::getGlobal(int index) {
- return _globals[index];
-}
-
-void WoodScript::setGlobal(int index, long value) {
- _globals[index] = value;
-}
-
-void WoodScript::setBackgroundSurface(M4Surface *backgroundSurface) {
- _backgroundSurface = backgroundSurface;
-}
-
-void WoodScript::setSurfaceView(View *view) {
- _surfaceView = view;
-}
-
-RGB8 *WoodScript::getMainPalette() const {
- return _mainPalette;
-}
-
-}
diff --git a/engines/m4/woodscript.h b/engines/m4/woodscript.h
deleted file mode 100644
index 95033b9179..0000000000
--- a/engines/m4/woodscript.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef M4_WOODSCRIPT_H
-#define M4_WOODSCRIPT_H
-
-#include "common/scummsys.h"
-#include "common/util.h"
-#include "common/str.h"
-#include "common/array.h"
-#include "common/stream.h"
-#include "graphics/surface.h"
-
-#include "m4/globals.h"
-#include "m4/assets.h"
-#include "m4/resource.h"
-#include "m4/sprite.h"
-#include "m4/m4.h"
-#include "m4/graphics.h"
-#include "m4/viewmgr.h"
-
-namespace M4 {
-
-class MadsM4Engine;
-class WoodScript;
-class Machine;
-class Sequence;
-class AssetManager;
-class View;
-
-struct Instruction {
- int32 instr;
- long *argp[3];
- long argv[3];
- int argc;
- // Helper method; many opcode functions can get either a defined value or a random value
- long getValue() {
- if (argc == 3)
- return _vm->imath_ranged_rand16(argv[1], argv[2]);
- else
- return argv[1];
- }
-};
-
-class Bytecode {
-public:
- Bytecode(WoodScript *ws, byte *code, int32 codeSize, Sequence *seq);
- ~Bytecode();
- int loadInstruction(Instruction &instruction);
- void jumpAbsolute(int32 ofs);
- void jumpRelative(int32 ofs);
- void setSequence(Sequence *sequence);
- void setCode(byte *code, int32 codeSize);
- Sequence *sequence() const;
- uint32 pos() const { return _code->pos() / 4; }
-protected:
- WoodScript *_ws;
- Common::SeekableReadStream *_code;
- Sequence *_sequence;
- static int32 _dataFormats[];
- bool decodeArgument(int32 format, int32 data, long *&arg, long &value);
-};
-
-struct EndOfSequenceRequestItem {
- int32 codeOffset, count;
- EndOfSequenceRequestItem() : codeOffset(-1) {}
- bool isValid() const { return codeOffset >= 0; }
-};
-
-typedef Common::Array<EndOfSequenceRequestItem> EndOfSequenceRequestList;
-
-class Sequence {
-public:
- Sequence(WoodScript *ws, Machine *machine, int32 sequenceHash);
- ~Sequence();
-
- void pause();
- void resume();
- void issueEndOfSequenceRequest(int32 codeOffset, int32 count);
- void cancelEndOfSequenceRequest();
-
- bool runProgram();
-
- bool changeProgram(int32 sequenceHash);
-
- void clearVars();
-
- long *getVarPtr(int index);
- long *getParentVarPtr(int index);
- long *getDataPtr(int index);
-
- void setActive(bool active) { _active = active; }
- bool isActive() const { return _active; }
-
- bool isTerminated() const { return _terminated; }
-
- void draw(M4Surface *surface, const Common::Rect &clipRect, Common::Rect &updateRect);
-
- bool s1_end(Instruction &instruction);
- bool s1_clearVars(Instruction &instruction);
- bool s1_set(Instruction &instruction);
- bool s1_compare(Instruction &instruction);
- bool s1_add(Instruction &instruction);
- bool s1_sub(Instruction &instruction);
- bool s1_mul(Instruction &instruction);
- bool s1_div(Instruction &instruction);
- bool s1_and(Instruction &instruction);
- bool s1_or(Instruction &instruction);
- bool s1_not(Instruction &instruction);
- bool s1_sin(Instruction &instruction);
- bool s1_cos(Instruction &instruction);
- bool s1_abs(Instruction &instruction);
- bool s1_min(Instruction &instruction);
- bool s1_max(Instruction &instruction);
- bool s1_mod(Instruction &instruction);
- bool s1_floor(Instruction &instruction);
- bool s1_round(Instruction &instruction);
- bool s1_ceil(Instruction &instruction);
- bool s1_point(Instruction &instruction);
- bool s1_dist2d(Instruction &instruction);
- bool s1_crunch(Instruction &instruction);
- bool s1_branch(Instruction &instruction);
- bool s1_setFrame(Instruction &instruction);
- bool s1_sendMessage(Instruction &instruction);
- bool s1_push(Instruction &instruction);
- bool s1_pop(Instruction &instruction);
- bool s1_jumpSub(Instruction &instruction);
- bool s1_return(Instruction &instruction);
- bool s1_getFrameCount(Instruction &instruction);
- bool s1_getFrameRate(Instruction &instruction);
- bool s1_getCelsPixSpeed(Instruction &instruction);
- bool s1_setIndex(Instruction &instruction);
- bool s1_setLayer(Instruction &instruction);
- bool s1_setDepth(Instruction &instruction);
- bool s1_setData(Instruction &instruction);
- bool s1_openStream(Instruction &instruction);
- bool s1_streamNextFrame(Instruction &instruction);
- bool s1_closeStream(Instruction &instruction);
-
- int32 indexReg() const { return _indexReg; }
-
- EndOfSequenceRequestItem getEndOfSequenceRequestItem() const { return _endOfSequenceRequest; }
- bool hasEndOfSequenceRequestPending() const { return _endOfSequenceRequest.isValid(); }
- void resetEndOfSequenceRequest() { _endOfSequenceRequest.codeOffset = -1; }
-
- Machine *getMachine() const { return _machine; }
-
-
-protected:
- WoodScript *_ws;
- Bytecode *_code;
-
- long *_vars;
- bool _active, _terminated;
- Machine *_machine;
- Sequence *_parentSequence;
- int32 _layer;
- int32 _startTime, _switchTime;
- long *_dataRow;
- int32 _localVarCount;
- int32 _cmpFlags;
-
- EndOfSequenceRequestItem _endOfSequenceRequest;
-
- int32 _indexReg;
-
- M4Sprite *_curFrame;
-
- int32 _sequenceHash;
-
- int32 _returnHashes[8]; //FIXME: Use constant instead of 8
- uint32 _returnOffsets[8];
- int32 _returnStackIndex;
-
- Common::SeekableReadStream *_stream;
- SpriteAsset *_streamSpriteAsset;
-
- bool streamOpen();
- bool streamNextFrame();
- void streamClose();
-
-};
-
-class Machine {
-public:
- Machine(WoodScript *ws, int32 machineHash, Sequence *parentSeq, int32 dataHash,
- int32 dataRowIndex, int callbackHandler, Common::String machineName, int32 id);
- ~Machine();
-
- void clearMessages();
- void clearPersistentMessages();
- void restorePersistentMessages();
- void sendMessage(uint32 messageHash, long messageValue, Machine *sender);
- void resetSwitchTime();
- bool changeSequenceProgram(int32 sequenceHash);
-
- bool searchMessages(uint32 messageHash, uint32 messageValue, Machine *sender);
- bool searchPersistentMessages(uint32 messageHash, uint32 messageValue, Machine *sender);
-
- void enterState();
- int32 execInstruction();
- void execBlock(int32 offset, int32 count);
- int32 getState() { return _currentState; }
-
- int32 getId() const { return _id; }
-
- bool m1_gotoState(Instruction &instruction);
- bool m1_jump(Instruction &instruction);
- bool m1_terminate(Instruction &instruction);
- bool m1_startSequence(Instruction &instruction);
- bool m1_pauseSequence(Instruction &instruction);
- bool m1_resumeSequence(Instruction &instruction);
- bool m1_storeValue(Instruction &instruction);
- bool m1_sendMessage(Instruction &instruction);
- bool m1_broadcastMessage(Instruction &instruction);
- bool m1_replyMessage(Instruction &instruction);
- bool m1_sendSystemMessage(Instruction &instruction);
- bool m1_createMachine(Instruction &instruction);
- bool m1_createMachineEx(Instruction &instruction);
- bool m1_clearVars(Instruction &instruction);
-
- void m1_onEndSequence(Instruction &instruction);
- void m1_onMessage(Instruction &instruction);
- void m1_switchLt(Instruction &instruction);
- void m1_switchLe(Instruction &instruction);
- void m1_switchEq(Instruction &instruction);
- void m1_switchNe(Instruction &instruction);
- void m1_switchGe(Instruction &instruction);
- void m1_switchGt(Instruction &instruction);
-
- long *dataRow() const { return _dataRow; }
- Sequence *parentSequence() const { return _parentSequence; }
- Common::String name() const { return _name; }
-
-protected:
- WoodScript *_ws;
- Bytecode *_code;
-
- Common::String _name;
- Sequence *_sequence, *_parentSequence;
- byte *_mach;
- int32 _machHash, _machineCodeOffset;
- int32 _stateCount, _stateTableOffset;
- long *_dataRow;
- int32 _id, _recursionLevel, _currentState, _targetCount;
- /* TODO:
- m->msgReplyXM = NULL;
- m->CintrMsg = CintrMsg;
- _walkPath
- _messages
- _persistentMessages
- _usedPersistentMessages
- */
-};
-
-class WoodScript {
-public:
-
- WoodScript(MadsM4Engine *vm);
- ~WoodScript();
-
- Machine *createMachine(int32 machineHash, Sequence *parentSeq, int32 dataHash, int32 dataRowIndex, int callbackHandler, const char *machineName);
- Sequence *createSequence(Machine *machine, int32 sequenceHash);
-
- void runSequencePrograms();
- void runEndOfSequenceRequests();
- void runTimerSequenceRequests();
-
- /* Series */
- // Move to own class, e.g. SeriesPlayer
- int32 loadSeries(const char* seriesName, int32 hash, RGB8* palette);
- void unloadSeries(int32 hash);
- void setSeriesFramerate(Machine *machine, int32 frameRate);
- Machine *playSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 frameRate, int32 loopCount, int32 s, int32 x, int32 y,
- int32 firstFrame, int32 lastFrame);
- Machine *showSeries(const char *seriesName, long layer, uint32 flags, int32 triggerNum,
- int32 duration, int32 index, int32 s, int32 x, int32 y);
- Machine *streamSeries(const char *seriesName, int32 frameRate, long layer, int32 triggerNum);
-
- void update();
- void clear();
-
- /* Misc */
- void setDepthTable(int16 *depthTable);
-
- long *getGlobalPtr(int index);
- long getGlobal(int index);
- void setGlobal(int index, long value);
-
- AssetManager *assets() const { return _assets; }
-
- // Sets the untouched, clean surface which contains the room background
- void setBackgroundSurface(M4Surface *backgroundSurface);
- // Sets the view which is used for drawing
- void setSurfaceView(View *view);
-
- RGB8 *getMainPalette() const;
-
- void setInverseColorTable(byte *inverseColorTable) { _inverseColorTable = inverseColorTable; }
- byte *getInverseColorTable() const { return _inverseColorTable; }
-
-protected:
- MadsM4Engine *_vm;
- AssetManager *_assets;
-
- Common::Array<Sequence*> _sequences, _layers;
- Common::Array<Machine*> _machines;
- int32 _machineId;
-
- long *_globals;
-
- Common::Array<Sequence*> _endOfSequenceRequestList;
-
- int32 _indexReg;
-
- /* Misc */
- int16 *_depthTable;
- byte *_inverseColorTable;
- M4Surface *_backgroundSurface;
- View *_surfaceView;
-
-};
-
-
-} // End of namespace M4
-
-
-#endif
diff --git a/engines/m4/ws_machine.cpp b/engines/m4/ws_machine.cpp
deleted file mode 100644
index 18a8af76a8..0000000000
--- a/engines/m4/ws_machine.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/woodscript.h"
-
-namespace M4 {
-
-bool (Machine::*machineCommandsTable[])(Instruction &instruction) = {
- NULL,
- NULL,//TODO: nop
- &Machine::m1_gotoState,
- &Machine::m1_jump,
- &Machine::m1_terminate,
- &Machine::m1_startSequence,
- &Machine::m1_pauseSequence,
- &Machine::m1_resumeSequence,
- &Machine::m1_storeValue,
- &Machine::m1_sendMessage,
- &Machine::m1_broadcastMessage,
- &Machine::m1_replyMessage,
- &Machine::m1_sendSystemMessage,
- &Machine::m1_createMachine,
- &Machine::m1_createMachineEx,
- &Machine::m1_clearVars
-};
-
-void (Machine::*machineConditionalsTable[])(Instruction &instruction) = {
- NULL,//TODO: after
- &Machine::m1_onEndSequence,
- &Machine::m1_onMessage,
- NULL,//TODO: on_p_msg
- &Machine::m1_switchLt,
- &Machine::m1_switchLe,
- &Machine::m1_switchEq,
- &Machine::m1_switchNe,
- &Machine::m1_switchGe,
- &Machine::m1_switchGt,
-};
-
-Machine::Machine(WoodScript *ws, int32 machineHash, Sequence *parentSeq, int32 dataHash,
- int32 dataRowIndex, int callbackHandler, Common::String machineName, int32 id) {
-
- _ws = ws;
-
- _machHash = machineHash;
- _name = machineName;
- _id = id;
-
- // initialize the machine's bytecode
- MachineAsset *machineAsset = _ws->assets()->getMachine(_machHash);
- byte *code;
- uint32 codeSize;
- machineAsset->getCode(code, codeSize);
- _code = new Bytecode(_ws, code, codeSize, NULL);
-
- // initialize the machine's data
- if (dataHash >= 0) {
- DataAsset *dataAsset = _ws->assets()->getData(dataHash);
- _dataRow = dataAsset->getRow(dataRowIndex);
- } else {
- _dataRow = NULL;
- }
-
- _recursionLevel = 0;
- _currentState = 0;
- _sequence = NULL;
- _parentSequence = parentSeq;
- _targetCount = 0;
-
-}
-
-Machine::~Machine() {
- delete _code;
-}
-
-void Machine::clearMessages() {
-}
-
-void Machine::clearPersistentMessages() {
-}
-
-void Machine::restorePersistentMessages() {
-}
-
-void Machine::sendMessage(uint32 messageHash, long messageValue, Machine *sender) {
-}
-
-void Machine::resetSwitchTime() {
-}
-
-bool Machine::changeSequenceProgram(int32 sequenceHash) {
- return _sequence->changeProgram(sequenceHash);
-}
-
-bool Machine::searchMessages(uint32 messageHash, uint32 messageValue, Machine *sender) {
- return false;
-}
-
-bool Machine::searchPersistentMessages(uint32 messageHash, uint32 messageValue, Machine *sender) {
- return false;
-}
-
-void Machine::enterState() {
-
- MachineAsset *machineAsset = _ws->assets()->getMachine(_machHash);
-
- _code->jumpAbsolute(machineAsset->getStateOffset(_currentState));
-
- int32 instruction = -1;
-
- _recursionLevel++;
-
- int32 oldId = _id;
- int32 oldRecursionLevel = _recursionLevel;
-
- while (instruction && instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel) {
- instruction = execInstruction();
- }
-
- if (instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel) {
- _recursionLevel--;
- }
-
-}
-
-int32 Machine::execInstruction() {
-
- //debugCN(kDebugScript, "Machine::execInstruction()\n");
-
- bool done = false;
- Instruction instruction;
- //Sequence *sequence;
- int32 machID = _id;
-
- _code->loadInstruction(instruction);
-
- if (instruction.instr >= 64) {
- if (machineConditionalsTable[instruction.instr - 64] != 0)
- (this->*machineConditionalsTable[instruction.instr - 64])(instruction);
- /* The next line is to yield on unimplemented opcodes */
- else {
- g_system->delayMillis(5000);
- }
- } else if (instruction.instr > 0) {
- if (machineCommandsTable[instruction.instr] != 0)
- done = !(this->*machineCommandsTable[instruction.instr])(instruction);
- /* The next line is to yield on unimplemented opcodes */
- else {
- g_system->delayMillis(5000);
- }
- if (done) {
- if (_id == machID) {
- //TODO: Cancel all requests
- if (_currentState == -1) {
- // TODO: Set terminated flag and delete machine in WoodScript update
- }
- else {
- // initialize new state
- enterState();
- }
- }
- }
- }
-
- return instruction.instr;
-
-}
-
-void Machine::execBlock(int32 offset, int32 count) {
-
- // MachineAsset *machineAsset = _ws->assets()->getMachine(_machHash);
-
- int32 startOffset = offset, endOffset = offset + count;
-
- _recursionLevel++;
-
- int32 oldId = _id;
- int32 oldRecursionLevel = _recursionLevel;
-
- _code->jumpAbsolute(offset);
-
- int32 instruction = -1;
-
- //debugCN(kDebugScript, "---------------------------------------\n");
-
- while (instruction && instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel &&
- _code->pos() >= (uint32)startOffset && _code->pos() < (uint32)endOffset) {
-
- instruction = execInstruction();
- //g_system->delayMillis(500);
- }
-
- //debugCN(kDebugScript, "---------------------------------------\n");
-
- if (instruction == 3) {
- execInstruction();
- }
-
- if (instruction != 4 && _id == oldId && _recursionLevel == oldRecursionLevel) {
- _recursionLevel--;
- }
-
-}
-
-bool Machine::m1_gotoState(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_gotoState() state = %d\n", (int32)instruction.argv[0] >> 16);
-
- _currentState = (int32)instruction.argv[0] >> 16;
- _recursionLevel = 0;
- return false;
-}
-
-bool Machine::m1_jump(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_jump() ofs = %08X\n", (int32)instruction.argv[0] >> 16);
-
- _code->jumpRelative((int32)instruction.argv[0] >> 16);
- return true;
-}
-
-bool Machine::m1_terminate(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_terminate()\n");
-
- _currentState = -1;
- _recursionLevel = 0;
- return false;
-}
-
-bool Machine::m1_startSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_startSequence() sequence hash = %d\n", (uint32)instruction.argv[0] >> 16);
-
- int32 sequenceHash = instruction.argv[0] >> 16;
- if (_sequence == NULL) {
- //debugCN(kDebugScript, "Machine::m1_startSequence() creating new sequence\n");
- _sequence = _ws->createSequence(this, sequenceHash);
- _code->setSequence(_sequence);
- } else {
- //debugCN(kDebugScript, "Machine::m1_startSequence() using existing sequence\n");
- _sequence->changeProgram(sequenceHash);
- //_code->setSequence(_sequence);
- }
- return true;
-}
-
-bool Machine::m1_pauseSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_pauseSequence()\n");
-
- _sequence->pause();
- return true;
-}
-
-bool Machine::m1_resumeSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_resumeSequence()\n");
-
- _sequence->resume();
- return true;
-}
-
-bool Machine::m1_storeValue(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_storeValue() %p = %d (%08X)\n", (void*)instruction.argp[0], (uint32)instruction.argv[1], (uint32)instruction.argv[1]);
-
- *instruction.argp[0] = instruction.getValue();
- return true;
-}
-
-bool Machine::m1_sendMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_sendMessage() %p = %d (%08X)\n", (void*)instruction.argp[0], (uint32)instruction.argv[1], (uint32)instruction.argv[1]);
-
-#if 0
-//TODO
- long messageValue;
-
- if (instruction.argc == 3) {
- messageValue = instruction.argv[2];
- } else {
- messageValue = 0;
- }
- //_ws->sendMessage((uint32)instruction.argv[1], messageValue, (uint32)instruction.argv[0] >> 16);
- //void SendWSMessage(uint32 msgHash, long msgValue, machine *recvM, uint32 machHash, machine *sendM, int32 msgCount) {
-#endif
- return true;
-
-}
-
-bool Machine::m1_broadcastMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_broadcastMessage() %p = %d (%08X)\n", (void*)instruction.argp[0], (uint32)instruction.argv[1], (uint32)instruction.argv[1]);
-
-#if 0
-//TODO
- long messageValue;
-
- if (instruction.argc == 3) {
- messageValue = instruction.argv[2];
- } else {
- messageValue = 0;
- }
- //_ws->sendMessage((uint32)instruction.argv[1], messageValue, (uint32)instruction.argv[0] >> 16);
-#endif
- return true;
-}
-
-bool Machine::m1_replyMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_replyMessage() messageHash = %d; messageValue = %d\n", (uint32)instruction.argv[0], (uint32)instruction.argv[1]);
-#if 0
- if (myArg2) {
- msgValue = *myArg2;
- }
- else {
- msgValue = 0;
- }
- SendWSMessage(*myArg1, msgValue, m->msgReplyXM, 0, m, 1);
-#endif
- return true;
-}
-
-bool Machine::m1_sendSystemMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_sendSystemMessage() messageValue = %d\n", (uint32)instruction.argv[0]);
-#if 0
-#endif
- return true;
-}
-
-bool Machine::m1_createMachine(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_createMachine()\n");
-#if 0
-#endif
- return true;
-}
-
-bool Machine::m1_createMachineEx(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_createMachineEx()\n");
-#if 0
-#endif
- return true;
-}
-
-bool Machine::m1_clearVars(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_clearVars()\n");
-
- _sequence->clearVars();
- return true;
-}
-
-
-void Machine::m1_onEndSequence(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_onEndSequence() count = %08X\n", (uint32)instruction.argv[0] >> 16);
-
- int32 count = instruction.argv[0] >> 16;
- _sequence->issueEndOfSequenceRequest(_code->pos(), count);
- _code->jumpRelative(count);
-}
-
-void Machine::m1_onMessage(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_onEndSequence() count = %08X\n", (uint32)instruction.argv[0] >> 16);
-
- // TODO: Add message to list
-
- int32 count = instruction.argv[0] >> 16;
- _code->jumpRelative(count);
-
-}
-
-void Machine::m1_switchLt(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchLt() %d < %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] >= instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchLe(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchLe() %d <= %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] > instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchEq(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchEq() %d == %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] != instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchNe(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchNe() %d != %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] == instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchGe(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchGe() %d >= %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] < instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-void Machine::m1_switchGt(Instruction &instruction) {
- //debugCN(kDebugScript, "Machine::m1_switchGt() %d > %d -> %08X\n", (uint32)instruction.argv[1], (uint32)instruction.argv[2], (uint32)instruction.argv[0] >> 16);
-
- if (instruction.argv[1] <= instruction.argv[2])
- _code->jumpRelative(instruction.argv[0] >> 16);
-}
-
-}
diff --git a/engines/m4/ws_sequence.cpp b/engines/m4/ws_sequence.cpp
deleted file mode 100644
index 01776ef6ec..0000000000
--- a/engines/m4/ws_sequence.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "m4/woodscript.h"
-
-namespace M4 {
-
-static const long sinCosTable[320] = {
- 0, 1608, 3215, 4821, 6423, 8022, 9616, 11204,
- 12785, 14359, 15923, 17479, 19024, 20557, 22078, 23586,
- 25079, 26557, 28020, 29465, 30893, 32302, 33692, 35061,
- 36409, 37736, 39039, 40319, 41575, 42806, 44011, 45189,
- 46340, 47464, 48558, 49624, 50660, 51665, 52639, 53581,
- 54491, 55368, 56212, 57022, 57797, 58538, 59243, 59913,
- 60547, 61144, 61705, 62228, 62714, 63162, 63571, 63943,
- 64276, 64571, 64826, 65043, 65220, 65358, 65457, 65516,
- 65536, 65516, 65457, 65358, 65220, 65043, 64826, 64571,
- 64276, 63943, 63571, 63162, 62714, 62228, 61705, 61144,
- 60547, 59913, 59243, 58538, 57797, 57022, 56212, 55368,
- 54491, 53581, 52639, 51665, 50660, 49624, 48558, 47464,
- 46340, 45189, 44011, 42806, 41575, 40319, 39039, 37736,
- 36409, 35061, 33692, 32302, 30893, 29465, 28020, 26557,
- 25079, 23586, 22078, 20557, 19024, 17479, 15923, 14359,
- 12785, 11204, 9616, 8022, 6423, 4821, 3215, 1608,
- 0, -1608, -3215, -4821, -6423, -8022, -9616, -11204,
- -12785, -14359, -15923, -17479, -19024, -20557, -22078, -23586,
- -25079, -26557, -28020, -29465, -30893, -32302, -33692, -35061,
- -36409, -37736, -39039, -40319, -41575, -42806, -44011, -45189,
- -46340, -47464, -48558, -49624, -50660, -51665, -52639, -53581,
- -54491, -55368, -56212, -57022, -57797, -58538, -59243, -59913,
- -60547, -61144, -61705, -62228, -62714, -63162, -63571, -63943,
- -64276, -64571, -64826, -65043, -65220, -65358, -65457, -65516,
- -65536, -65516, -65457, -65358, -65220, -65043, -64826, -64571,
- -64276, -63943, -63571, -63162, -62714, -62228, -61705, -61144,
- -60547, -59913, -59243, -58538, -57797, -57022, -56212, -55368,
- -54491, -53581, -52639, -51665, -50660, -49624, -48558, -47464,
- -46340, -45189, -44011, -42806, -41575, -40319, -39039, -37736,
- -36409, -35061, -33692, -32302, -30893, -29465, -28020, -26557,
- -25079, -23586, -22078, -20557, -19024, -17479, -15923, -14359,
- -12785, -11204, -9616, -8022, -6423, -4821, -3215, -1608,
- 0, 1608, 3215, 4821, 6423, 8022, 9616, 11204,
- 12785, 14359, 15923, 17479, 19024, 20557, 22078, 23586,
- 25079, 26557, 28020, 29465, 30893, 32302, 33692, 35061,
- 36409, 37736, 39039, 40319, 41575, 42806, 44011, 45189,
- 46340, 47464, 48558, 49624, 50660, 51665, 52639, 53581,
- 54491, 55368, 56212, 57022, 57797, 58538, 59243, 59913,
- 60547, 61144, 61705, 62228, 62714, 63162, 63571, 63943,
- 64276, 64571, 64826, 65043, 65220, 65358, 65457, 65516
-};
-
-const long *sinTable = &(sinCosTable[0]);
-const long *cosTable = &(sinCosTable[64]);
-
-// FIXME: Tables
-
-const int sequenceVariableCount = 33;
-
-enum SequenceVariables {
- kSeqVarTimer = 0,
- kSeqVarTag = 1,
- kSeqVarLayer = 2,
- kSeqVarWidth = 3,
- kSeqVarHeight = 4,
- kSeqVarX = 5,
- kSeqVarY = 6,
- kSeqVarScale = 7,
- kSeqVarR = 8,
- kSeqVarSpriteHash = 9,
- kSeqVarSpriteFrameNumber = 10,
- kSeqVarSpriteFrameCount = 11,
- kSeqVarSpriteFrameRate = 12,
- kSeqVarSpriteFramePixelSpeed = 13,
- kSeqVarTargetS = 14,
- kSeqVarTargetR = 15,
- kSeqVarTargetX = 16,
- kSeqVarTargetY = 17,
- kSeqVarDeltaS = 18,
- kSeqVarDeltaR = 19,
- kSeqVarDeltaX = 20,
- kSeqVarDeltaY = 21,
- kSeqVarVelocity = 22,
- kSeqVarTheta = 23,
- kSeqVarTemp1 = 24,
- kSeqVarTemp2 = 25,
- kSeqVarTemp3 = 26,
- kSeqVarTemp4 = 27,
- kSeqVarTemp5 = 28,
- kSeqVarTemp6 = 29,
- kSeqVarTemp7 = 30,
- kSeqVarTemp8 = 31,
- kSeqVarMachineID = 32
-};
-
-bool (Sequence::*sequenceCommandsTable[])(Instruction &instruction) = {
- &Sequence::s1_end,
- &Sequence::s1_clearVars,
- &Sequence::s1_set,
- &Sequence::s1_compare,
- &Sequence::s1_add,
- &Sequence::s1_sub,
- &Sequence::s1_mul,
- &Sequence::s1_div,
- &Sequence::s1_and,
- &Sequence::s1_or,
- &Sequence::s1_not,
- &Sequence::s1_sin,
- &Sequence::s1_cos,
- &Sequence::s1_abs,
- &Sequence::s1_min,
- &Sequence::s1_max,
- &Sequence::s1_mod,
- &Sequence::s1_floor,
- &Sequence::s1_round,
- &Sequence::s1_ceil,
- &Sequence::s1_point,
- &Sequence::s1_dist2d,
- &Sequence::s1_crunch,
- &Sequence::s1_branch,
- &Sequence::s1_setFrame,
- &Sequence::s1_sendMessage,
- &Sequence::s1_push,
- &Sequence::s1_pop,
- &Sequence::s1_jumpSub,
- &Sequence::s1_return,
- &Sequence::s1_getFrameCount,
- &Sequence::s1_getFrameRate,
- &Sequence::s1_getCelsPixSpeed,
- &Sequence::s1_setIndex,
- &Sequence::s1_setLayer,
- &Sequence::s1_setDepth,
- &Sequence::s1_setData,
- &Sequence::s1_openStream,
- &Sequence::s1_streamNextFrame,
- &Sequence::s1_closeStream
-};
-
-Sequence::Sequence(WoodScript *ws, Machine *machine, int32 sequenceHash) {
-
- _ws = ws;
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(sequenceHash);
-
- // initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code = new Bytecode(_ws, code, codeSize, this);
-
- _active = true;
- _sequenceHash = sequenceHash;
- _machine = machine;
- _parentSequence = _machine->parentSequence();
- _dataRow = _machine->dataRow();
- _startTime = 0;
- _switchTime = 0;
- //TODO _flags = 0;
- _localVarCount = sequenceAsset->localVarCount();
- _vars = new long[sequenceVariableCount + _localVarCount];
- _returnStackIndex = 0;
- _layer = 0;
- _terminated = false;
-
- clearVars();
- _vars[kSeqVarMachineID] = _machine->getId();
-
-}
-
-Sequence::~Sequence() {
- delete _code;
-}
-
-void Sequence::pause() {
- _active = false;
-}
-
-void Sequence::resume() {
- _active = true;
-}
-
-void Sequence::issueEndOfSequenceRequest(int32 codeOffset, int32 count) {
-
- //debugCN(kDebugScript, "Sequence::issueEndOfSequenceRequest(%04X, %04X)\n", codeOffset, count);
- //g_system->delayMillis(5000);
-
- _endOfSequenceRequest.codeOffset = codeOffset;
- _endOfSequenceRequest.count = count;
-}
-
-void Sequence::cancelEndOfSequenceRequest() {
- _endOfSequenceRequest.codeOffset = -1;
-}
-
-bool Sequence::runProgram() {
-
- bool done = true;
-
- //debugCN(kDebugScript, "_ws->getGlobal(kGlobTime) = %ld, _switchTime = %d\n", _ws->getGlobal(kGlobTime), _switchTime);
-
- if (_switchTime >= 0 && _ws->getGlobal(kGlobTime) >= _switchTime)
- done = false;
-
- _vars[kSeqVarTimer] -= _ws->getGlobal(kGlobTimeDelta) << 16;
-
- while (!done) {
- Instruction instruction;
- _code->loadInstruction(instruction);
- if (sequenceCommandsTable[instruction.instr] != 0)
- done = !(this->*sequenceCommandsTable[instruction.instr])(instruction);
- else {
- //g_system->delayMillis(1000);
- }
- }
-
- return _terminated;
-}
-
-void Sequence::clearVars() {
- for (int i = 0; i < sequenceVariableCount + _localVarCount; i++)
- _vars[i] = 0;
- // set default scaling to 100%
- _vars[kSeqVarScale] = 0x10000;
-}
-
-bool Sequence::changeProgram(int32 sequenceHash) {
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(sequenceHash);
-
- if (sequenceAsset->localVarCount() > _localVarCount) {
- //debugCN(kDebugScript, "Sequence::changeProgram(%d) sequenceAsset->localVarCount() > _localVarCount\n", sequenceHash);
- return false;
- }
-
- // Initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code->setCode(code, codeSize);
-
- // Reset status variables
- _switchTime = 0;
- _active = true;
- _terminated = false;
- _endOfSequenceRequest.codeOffset = -1;
-
- _sequenceHash = sequenceHash;
- _returnStackIndex = 0;
-
- return true;
-
-}
-
-long *Sequence::getVarPtr(int index) {
- return &_vars[index];
-}
-
-long *Sequence::getParentVarPtr(int index) {
- return _parentSequence->getVarPtr(index);
-}
-
-long *Sequence::getDataPtr(int index) {
- return &_dataRow[index];
-}
-
-void Sequence::draw(M4Surface *surface, const Common::Rect &clipRect, Common::Rect &updateRect) {
-
- SpriteInfo info;
-
- info.sprite = _curFrame;
- info.hotX = _curFrame->xOffset;
- info.hotY = _curFrame->yOffset;
- info.encoding = _curFrame->encoding;
- info.inverseColorTable = _m4Vm->scene()->getInverseColorTable();
- info.palette = _ws->getMainPalette();
- info.width = _curFrame->width();
- info.height = _curFrame->height();
- int32 scaler = FixedMul(_vars[kSeqVarScale], 100 << 16) >> 16;
- info.scaleX = _vars[kSeqVarWidth] < 0 ? -scaler : scaler;
- info.scaleY = scaler;
- surface->drawSprite(_vars[kSeqVarX] >> 16, _vars[kSeqVarY] >> 16, info, clipRect);
-
-}
-
-bool Sequence::s1_end(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_end()\n");
-
- _terminated = true;
- return false;
-}
-
-bool Sequence::s1_clearVars(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_clearVars()\n");
-
- clearVars();
- _vars[kSeqVarMachineID] = _machine->getId();
- return true;
-}
-
-bool Sequence::s1_set(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_set()\n");
-
- *instruction.argp[0] = instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_compare(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_compare()\n");
-
- long value = instruction.getValue();
- if (instruction.argv[0] < value)
- _cmpFlags = -1;
- else if (instruction.argv[0] > value)
- _cmpFlags = 1;
- else
- _cmpFlags = 0;
- return true;
-}
-
-bool Sequence::s1_add(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_add()\n");
-
- *instruction.argp[0] += instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_sub(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_sub()\n");
-
- *instruction.argp[0] -= instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_mul(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_mul()\n");
-
- *instruction.argp[0] = FixedMul(instruction.argv[0], instruction.getValue());
- return true;
-}
-
-bool Sequence::s1_div(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_div()\n");
-
- // TODO: Catch divisor = 0 in FixedDiv
- *instruction.argp[0] = FixedDiv(instruction.argv[0], instruction.getValue());
- return true;
-}
-
-bool Sequence::s1_and(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_and()\n");
-
- *instruction.argp[0] = instruction.argv[0] & instruction.getValue();
- if (*instruction.argp[0])
- _cmpFlags = 0;
- else
- _cmpFlags = 1;
- return true;
-}
-
-bool Sequence::s1_or(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_or()\n");
-
- *instruction.argp[0] = instruction.argv[0] | instruction.getValue();
- if (*instruction.argp[0])
- _cmpFlags = 0;
- else
- _cmpFlags = 1;
- return true;
-}
-
-bool Sequence::s1_not(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_not()\n");
-
- if (instruction.argv[0] == 0) {
- *instruction.argp[0] = 0x10000;
- _cmpFlags = 1;
- } else {
- *instruction.argp[0] = 0;
- _cmpFlags = 0;
- }
- return true;
-}
-
-bool Sequence::s1_sin(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_sin()\n");
-
- int32 tempAngle = *instruction.argp[1] >> 16;
- if (tempAngle < 0)
- tempAngle = 0x0100 - ((-tempAngle) & 0xff);
- else
- tempAngle &= 0xff;
-
- // FIXME: Why use the cosTable in s1_sin() ?
- // Note that sin(0) 0 and sinTable[0] = 0 but cos(0)=1, and indeed
- // cosTable[0] = 65536, which is 1 considered as a fixed point.
- *instruction.argp[0] = -cosTable[tempAngle];
-
- return true;
-}
-
-bool Sequence::s1_cos(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_cos()\n");
-
- int32 tempAngle = *instruction.argp[1] >> 16;
- if (tempAngle < 0)
- tempAngle = 0x0100 - ((-tempAngle) & 0xff);
- else
- tempAngle &= 0xff;
-
- // FIXME: Why use the sinTable in s1_cos() ?
- // Note that sin(0) 0 and sinTable[0] = 0 but cos(0)=1, and indeed
- // cosTable[0] = 65536, which is 1 considered as a fixed point.
- *instruction.argp[0] = sinTable[tempAngle];
-
- return true;
-}
-
-bool Sequence::s1_abs(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_abs()\n");
-
- *instruction.argp[0] = ABS(instruction.argv[1]);
- return true;
-}
-
-bool Sequence::s1_min(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_min()\n");
-
- *instruction.argp[0] = MIN(instruction.argv[1], instruction.argv[2]);
- return true;
-}
-
-bool Sequence::s1_max(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_max()\n");
-
- *instruction.argp[0] = MAX(instruction.argv[1], instruction.argv[2]);
- return true;
-}
-
-bool Sequence::s1_mod(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_mod()\n");
-
- *instruction.argp[0] = instruction.argv[0] % instruction.getValue();
- return true;
-}
-
-bool Sequence::s1_floor(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_floor()\n");
-
- *instruction.argp[0] = instruction.getValue() & 0xffff0000;
- return true;
-}
-
-bool Sequence::s1_round(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_round()\n");
-
- if ((*instruction.argp[1] & 0xffff) >= 0x8000)
- *instruction.argp[0] = (*instruction.argp[1] + 0x10000) & 0xffff0000;
- else
- *instruction.argp[0] = *instruction.argp[1] & 0xffff0000;
- return true;
-}
-
-bool Sequence::s1_ceil(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_ceil()\n");
-
- if ((*instruction.argp[1] & 0xffff) >= 0)
- *instruction.argp[0] = (*instruction.argp[1] + 0x10000) & 0xffff0000;
- else
- *instruction.argp[0] = *instruction.argp[1] & 0xffff0000;
- return true;
-}
-
-bool Sequence::s1_point(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_point()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_dist2d(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_dist2d()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_crunch(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_crunch()\n");
-
- long deltaTime;
-
- if (instruction.argc == 2) {
- deltaTime = _vm->imath_ranged_rand16(instruction.argv[0], instruction.argv[1]);
- } else if (instruction.argc == 1) {
- deltaTime = instruction.argv[0];
- } else {
- deltaTime = 0;
- }
-
- _startTime = _ws->getGlobal(kGlobTime);
-
- //debugCN(kDebugScript, "deltaTime = %ld\n", deltaTime >> 16);
- //g_system->delayMillis(5000);
-
- if (deltaTime >= 0) {
- _switchTime = _ws->getGlobal(kGlobTime) + (deltaTime >> 16);
- //debugCN(kDebugScript, "_ws->getGlobal(kGlobTime) = %ld\n", _ws->getGlobal(kGlobTime));
- //g_system->delayMillis(5000);
- } else {
- _switchTime = -1;
- }
-
- // TODO: Update if walking etc.
-
- return false;
-}
-
-bool Sequence::s1_branch(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_branch()\n");
-
- uint32 ofs = instruction.argv[1] >> 16;
- switch (instruction.argv[0] >> 16) {
- case 0: // jmp
- _code->jumpRelative(ofs);
- break;
- case 1: // <
- if (_cmpFlags < 0)
- _code->jumpRelative(ofs);
- break;
- case 2: // <=
- if (_cmpFlags <= 0)
- _code->jumpRelative(ofs);
- break;
- case 3: // ==
- if (_cmpFlags == 0)
- _code->jumpRelative(ofs);
- break;
- case 4: // !=
- if (_cmpFlags != 0)
- _code->jumpRelative(ofs);
- break;
- case 5: // >=
- if (_cmpFlags >= 0)
- _code->jumpRelative(ofs);
- break;
- case 6: // >
- if (_cmpFlags > 0)
- _code->jumpRelative(ofs);
- break;
- }
-
- return true;
-}
-
-bool Sequence::s1_setFrame(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_setFrame()\n");
-
- int32 frameIndex;
- if (instruction.argc == 3) {
- frameIndex = _vm->imath_ranged_rand(instruction.argv[1] >> 16, instruction.argv[2] >> 16);
- } else if (instruction.argc == 2) {
- frameIndex = instruction.argv[1] >> 16;
- } else {
- frameIndex = (instruction.argv[0] & 0xFF0000) >> 16;
- }
-
- //debugCN(kDebugScript, "Sequence::s1_setFrame() spriteHash = %d\n", (uint32)instruction.argv[0] >> 24);
- //debugCN(kDebugScript, "Sequence::s1_setFrame() frameIndex = %d\n", frameIndex);
-
- SpriteAsset *spriteAsset = _ws->assets()->getSprite((uint32)instruction.argv[0] >> 24);
- _curFrame = spriteAsset->getFrame(frameIndex);
-
- return true;
-}
-
-bool Sequence::s1_sendMessage(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_sendMessage()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_push(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_push()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_pop(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_pop()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_jumpSub(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_jumpSub()\n");
-
- _returnHashes[_returnStackIndex] = _sequenceHash;
- _returnOffsets[_returnStackIndex] = _code->pos();
- _returnStackIndex++;
-
- _sequenceHash = instruction.argv[0] >> 16;
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(_sequenceHash);
-
- // initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code->setCode(code, codeSize);
-
- return true;
-}
-
-bool Sequence::s1_return(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_return()\n");
-
- if (_returnStackIndex <= 0)
- return s1_end(instruction);
-
- _returnStackIndex--;
-
- _sequenceHash = _returnHashes[_returnStackIndex];
- uint32 ofs = _returnOffsets[_returnStackIndex];
-
- SequenceAsset *sequenceAsset = _ws->assets()->getSequence(_sequenceHash);
-
- // initialize the sequence's bytecode
- byte *code;
- uint32 codeSize;
- sequenceAsset->getCode(code, codeSize);
- _code->setCode(code, codeSize);
- _code->jumpAbsolute(ofs);
-
-
- return true;
-}
-
-bool Sequence::s1_getFrameCount(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_getFrameCount()\n");
-
- SpriteAsset *spriteAsset = _ws->assets()->getSprite(instruction.argv[1] >> 24);
- *instruction.argp[0] = spriteAsset->getCount() << 16;
- return true;
-}
-
-bool Sequence::s1_getFrameRate(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_getFrameRate()\n");
-
- SpriteAsset *spriteAsset = _ws->assets()->getSprite(instruction.argv[1] >> 24);
- *instruction.argp[0] = spriteAsset->getFrameRate();
- return true;
-}
-
-bool Sequence::s1_getCelsPixSpeed(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_getCelsPixSpeed()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_setIndex(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setIndex()\n");
- // TODO
- return true;
-}
-
-bool Sequence::s1_setLayer(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setLayer()\n");
- //TODO
- return true;
-}
-
-bool Sequence::s1_setDepth(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setDepth()\n");
- //TODO
- return true;
-}
-
-bool Sequence::s1_setData(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_setData()\n");
- //TODO
- return true;
-}
-
-bool Sequence::s1_openStream(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_openStream()\n");
-
- _stream = _vm->res()->openFile(_machine->name().c_str());
- streamOpen();
- return true;
-}
-
-bool Sequence::s1_streamNextFrame(Instruction &instruction) {
- //debugCN(kDebugScript, "Sequence::s1_streamNextFrame()\n");
-
- streamNextFrame();
- return true;
-}
-
-bool Sequence::s1_closeStream(Instruction &instruction) {
- debugCN(kDebugScript, "Sequence::s1_closeStream()\n");
- //TODO
- return true;
-}
-
-bool Sequence::streamOpen() {
-
- _streamSpriteAsset = new SpriteAsset(_vm, _stream, _stream->size(), "stream", true);
-
- _vars[kSeqVarSpriteFrameNumber] = -0x10000;
- _vars[kSeqVarSpriteFrameCount] = _streamSpriteAsset->getCount() << 16;
- _vars[kSeqVarSpriteFrameRate] = _streamSpriteAsset->getFrameRate() << 16;
-
- //debugCN(kDebugScript, "Sequence::streamOpen() frames = %d; max = %d x %d\n", _streamSpriteAsset->getCount(), _streamSpriteAsset->getMaxFrameWidth(), _streamSpriteAsset->getMaxFrameHeight());
-
- _curFrame = new M4Sprite(_vm, _streamSpriteAsset->getMaxFrameWidth(), _streamSpriteAsset->getMaxFrameHeight());
- streamNextFrame();
-
- // TODO: Just a hack to see the series with the correct palette.
- _vm->_palette->setPalette(_streamSpriteAsset->getPalette(), 0, 256);
-
- return true;
-}
-
-bool Sequence::streamNextFrame() {
-
- _vars[kSeqVarSpriteFrameNumber] += 0x10000;
-
- int32 frameNum = _vars[kSeqVarSpriteFrameNumber] >> 16;
- if (frameNum >= _streamSpriteAsset->getCount()) {
- // End reached
- return false;
- }
-
- _streamSpriteAsset->loadStreamingFrame(_curFrame, frameNum, _vars[kSeqVarX], _vars[kSeqVarY]);
-
- _vars[kSeqVarWidth] = _curFrame->width() << 16;
- _vars[kSeqVarHeight] = _curFrame->height() << 16;
-
- return true;
-}
-
-void Sequence::streamClose() {
- _stream = NULL;
- _vm->res()->toss(_machine->name().c_str());
- //_vm->res()->purge();
- delete _streamSpriteAsset;
- delete _curFrame;
- _stream = NULL;
- _streamSpriteAsset = NULL;
- _curFrame = NULL;
-}
-
-}
diff --git a/gui/credits.h b/gui/credits.h
index 8abd4bba69..08be2e0534 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -138,12 +138,6 @@ static const char *credits[] = {
"C1""Lure",
"C0""Paul Gilbert",
"",
-"C1""M4",
-"C0""Torbj\366rn Andersson",
-"C0""Paul Gilbert",
-"C0""Benjamin Haisch",
-"C0""Filippos Karapetis",
-"",
"C1""MADE",
"C0""Benjamin Haisch",
"C0""Filippos Karapetis",