aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2006-02-11 22:45:04 +0000
committerMax Horn2006-02-11 22:45:04 +0000
commit26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch)
tree26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /scumm
parent2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff)
downloadscummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.gz
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.bz2
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.zip
Moved engines to the new engines/ directory
svn-id: r20582
Diffstat (limited to 'scumm')
-rw-r--r--scumm/actor.cpp2253
-rw-r--r--scumm/actor.h294
-rw-r--r--scumm/akos.cpp1869
-rw-r--r--scumm/akos.h125
-rw-r--r--scumm/base-costume.cpp92
-rw-r--r--scumm/base-costume.h168
-rw-r--r--scumm/bomp.cpp393
-rw-r--r--scumm/bomp.h39
-rw-r--r--scumm/boxes.cpp1271
-rw-r--r--scumm/boxes.h54
-rw-r--r--scumm/camera.cpp367
-rw-r--r--scumm/charset.cpp1827
-rw-r--r--scumm/charset.h202
-rw-r--r--scumm/costume.cpp1160
-rw-r--r--scumm/costume.h141
-rw-r--r--scumm/cursor.cpp520
-rw-r--r--scumm/debugger.cpp915
-rw-r--r--scumm/debugger.h78
-rw-r--r--scumm/dialogs.cpp986
-rw-r--r--scumm/dialogs.h211
-rw-r--r--scumm/floodfill_he.cpp293
-rw-r--r--scumm/floodfill_he.h67
-rw-r--r--scumm/gfx.cpp3307
-rw-r--r--scumm/gfx.h301
-rw-r--r--scumm/help.cpp350
-rw-r--r--scumm/help.h45
-rw-r--r--scumm/imuse.cpp2043
-rw-r--r--scumm/imuse.h85
-rw-r--r--scumm/imuse_digi/dimuse.cpp412
-rw-r--r--scumm/imuse_digi/dimuse.h239
-rw-r--r--scumm/imuse_digi/dimuse_bndmgr.cpp344
-rw-r--r--scumm/imuse_digi/dimuse_bndmgr.h115
-rw-r--r--scumm/imuse_digi/dimuse_codecs.cpp655
-rw-r--r--scumm/imuse_digi/dimuse_music.cpp444
-rw-r--r--scumm/imuse_digi/dimuse_script.cpp409
-rw-r--r--scumm/imuse_digi/dimuse_sndmgr.cpp625
-rw-r--r--scumm/imuse_digi/dimuse_sndmgr.h139
-rw-r--r--scumm/imuse_digi/dimuse_tables.cpp881
-rw-r--r--scumm/imuse_digi/dimuse_track.cpp368
-rw-r--r--scumm/imuse_internal.h472
-rw-r--r--scumm/imuse_player.cpp1241
-rw-r--r--scumm/input.cpp467
-rw-r--r--scumm/insane/insane.cpp1466
-rw-r--r--scumm/insane/insane.h456
-rw-r--r--scumm/insane/insane_ben.cpp2009
-rw-r--r--scumm/insane/insane_enemy.cpp2813
-rw-r--r--scumm/insane/insane_iact.cpp558
-rw-r--r--scumm/insane/insane_scenes.cpp1499
-rw-r--r--scumm/instrument.cpp462
-rw-r--r--scumm/instrument.h79
-rw-r--r--scumm/intern.h912
-rw-r--r--scumm/intern_he.h606
-rw-r--r--scumm/logic_he.cpp772
-rw-r--r--scumm/logic_he.h111
-rw-r--r--scumm/midiparser_eup.cpp219
-rw-r--r--scumm/midiparser_ro.cpp143
-rw-r--r--scumm/module.mk110
-rw-r--r--scumm/music.h91
-rw-r--r--scumm/nut_renderer.cpp303
-rw-r--r--scumm/nut_renderer.h64
-rw-r--r--scumm/object.cpp1779
-rw-r--r--scumm/object.h182
-rw-r--r--scumm/palette.cpp969
-rw-r--r--scumm/palette_he.cpp317
-rw-r--r--scumm/player_mod.cpp181
-rw-r--r--scumm/player_mod.h97
-rw-r--r--scumm/player_nes.cpp1085
-rw-r--r--scumm/player_nes.h115
-rw-r--r--scumm/player_v1.cpp608
-rw-r--r--scumm/player_v1.h99
-rw-r--r--scumm/player_v2.cpp1005
-rw-r--r--scumm/player_v2.h167
-rw-r--r--scumm/player_v2a.cpp1420
-rw-r--r--scumm/player_v2a.h74
-rw-r--r--scumm/player_v3a.cpp347
-rw-r--r--scumm/player_v3a.h101
-rw-r--r--scumm/resource.cpp1616
-rw-r--r--scumm/resource.h46
-rw-r--r--scumm/resource_v2.cpp208
-rw-r--r--scumm/resource_v3.cpp121
-rw-r--r--scumm/resource_v4.cpp193
-rw-r--r--scumm/resource_v7he.cpp1912
-rw-r--r--scumm/resource_v7he.h556
-rw-r--r--scumm/room.cpp751
-rw-r--r--scumm/saveload.cpp1648
-rw-r--r--scumm/saveload.h169
-rw-r--r--scumm/script.cpp1355
-rw-r--r--scumm/script.h84
-rw-r--r--scumm/script_c64.cpp849
-rw-r--r--scumm/script_v100he.cpp2958
-rw-r--r--scumm/script_v2.cpp1629
-rw-r--r--scumm/script_v5.cpp2898
-rw-r--r--scumm/script_v6.cpp3183
-rw-r--r--scumm/script_v6he.cpp1315
-rw-r--r--scumm/script_v72he.cpp2352
-rw-r--r--scumm/script_v7he.cpp1133
-rw-r--r--scumm/script_v8.cpp1496
-rw-r--r--scumm/script_v80he.cpp811
-rw-r--r--scumm/script_v90he.cpp2636
-rw-r--r--scumm/scumm-md5.h467
-rw-r--r--scumm/scumm.cpp3472
-rw-r--r--scumm/scumm.h1369
-rw-r--r--scumm/smush/channel.h148
-rw-r--r--scumm/smush/chunk.cpp242
-rw-r--r--scumm/smush/chunk.h110
-rw-r--r--scumm/smush/chunk_type.h60
-rw-r--r--scumm/smush/codec1.cpp62
-rw-r--r--scumm/smush/codec37.cpp588
-rw-r--r--scumm/smush/codec37.h62
-rw-r--r--scumm/smush/codec47.cpp630
-rw-r--r--scumm/smush/codec47.h65
-rw-r--r--scumm/smush/imuse_channel.cpp347
-rw-r--r--scumm/smush/saud_channel.cpp268
-rw-r--r--scumm/smush/smush_font.cpp269
-rw-r--r--scumm/smush/smush_font.h54
-rw-r--r--scumm/smush/smush_mixer.cpp163
-rw-r--r--scumm/smush/smush_mixer.h64
-rw-r--r--scumm/smush/smush_player.cpp1359
-rw-r--r--scumm/smush/smush_player.h148
-rw-r--r--scumm/sound.cpp2364
-rw-r--r--scumm/sound.h185
-rw-r--r--scumm/sound_he.cpp516
-rw-r--r--scumm/sprite_he.cpp1440
-rw-r--r--scumm/sprite_he.h222
-rw-r--r--scumm/string.cpp1247
-rw-r--r--scumm/thumbnail.cpp140
-rw-r--r--scumm/usage_bits.cpp95
-rw-r--r--scumm/usage_bits.h35
-rw-r--r--scumm/util.cpp1818
-rw-r--r--scumm/util.h175
-rw-r--r--scumm/vars.cpp736
-rw-r--r--scumm/verbs.cpp855
-rw-r--r--scumm/verbs.h50
-rw-r--r--scumm/wiz_he.cpp2088
-rw-r--r--scumm/wiz_he.h211
135 files changed, 0 insertions, 99529 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp
deleted file mode 100644
index 7e6696680f..0000000000
--- a/scumm/actor.cpp
+++ /dev/null
@@ -1,2253 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/akos.h"
-#include "scumm/boxes.h"
-#include "scumm/charset.h"
-#include "scumm/costume.h"
-#include "scumm/intern.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/saveload.h"
-#include "scumm/sound.h"
-#include "scumm/sprite_he.h"
-#include "scumm/usage_bits.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-byte Actor::kInvalidBox = 0;
-ScummEngine *Actor::_vm = 0;
-
-void Actor::initActorClass(ScummEngine *scumm) {
- _vm = scumm;
- if (_vm->_features & GF_SMALL_HEADER) {
- kInvalidBox = 255;
- }
-}
-
-Actor::Actor() {
- assert(_vm != 0);
- _number = 0;
-
- initActor(-1);
-}
-
-void Actor::initActor(int mode) {
- if (mode == -1) {
- _offsX = _offsY = 0;
- _top = _bottom = 0;
- _needRedraw = _needBgReset = _costumeNeedsInit = _visible = false;
- _flip = false;
- _speedx = 8;
- _speedy = 2;
- _frame = 0;
- _walkbox = 0;
- _animProgress = 0;
- _heSkipLimbs = false;
- _drawToBackBuf = false;
- memset(_animVariable, 0, sizeof(_animVariable));
- memset(_palette, 0, sizeof(_palette));
- memset(_sound, 0, sizeof(_sound));
- memset(&_cost, 0, sizeof(CostumeData));
- memset(&_walkdata, 0, sizeof(ActorWalkData));
- _walkdata.point3.x = 32000;
- _walkScript = 0;
- memset(_heTalkQueue, 0, sizeof(_heTalkQueue));
-
- mode = 1;
- }
-
- if (mode == 1) {
- _costume = 0;
- _room = 0;
- _pos.x = 0;
- _pos.y = 0;
- _facing = 180;
- _heCondMask = 1;
- _heNoTalkAnimation = 0;
- if (_vm->_version >= 7)
- _visible = false;
- _heSkipLimbs = false;
- } else if (mode == 2) {
- _facing = 180;
- _heCondMask = 1;
- _heSkipLimbs = false;
- }
- _elevation = 0;
- _width = 24;
- _talkColor = 15;
- _talkPosX = 0;
- _talkPosY = -80;
- _boxscale = _scaley = _scalex = 0xFF;
- _charset = 0;
- memset(_sound, 0, sizeof(_sound));
- _targetFacing = _facing;
-
- stopActorMoving();
-
- _heXmapNum = 0;
- _shadowMode = 0;
- _layer = 0;
-
- setActorWalkSpeed(8, 2);
- _animSpeed = 0;
- if (_vm->_version >= 6)
- _animProgress = 0;
-
- _ignoreBoxes = false;
- _forceClip = (_vm->_version >= 7) ? 100 : 0;
- _ignoreTurns = false;
-
- if (_vm->_heversion >= 61)
- _flip = 0;
-
- _talkFrequency = 256;
- _talkPan = 64;
- _talkVolume = 127;
-
- if (_vm->_version <= 2) {
- _initFrame = 2;
- _walkFrame = 0;
- _standFrame = 1;
- _talkStartFrame = 5;
- _talkStopFrame = 4;
- } else {
- _initFrame = 1;
- _walkFrame = 2;
- _standFrame = 3;
- _talkStartFrame = 4;
- _talkStopFrame = 5;
- }
-
- _heTalking = false;
- _walkScript = 0;
- _talkScript = 0;
-
- _clipOverride = _vm->_actorClipOverride;
-
- _auxBlock.reset();
- _hePaletteNum = 0;
-
- _vm->_classData[_number] = (_vm->_version >= 7) ? _vm->_classData[0] : 0;
-}
-
-void Actor::stopActorMoving() {
- if (_walkScript)
- _vm->stopScript(_walkScript);
- _moving = 0;
-}
-
-void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) {
- if (newSpeedX == _speedx && newSpeedY == _speedy)
- return;
-
- _speedx = newSpeedX;
- _speedy = newSpeedY;
-
- if (_moving) {
- calcMovementFactor(_walkdata.next);
- }
-}
-
-int ScummEngine::getAngleFromPos(int x, int y) const {
- if (_gameId == GID_DIG || _gameId == GID_CMI) {
- double temp = atan2((double)x, (double)-y);
- return normalizeAngle((int)(temp * 180 / PI));
- } else {
- if (ABS(y) * 2 < ABS(x)) {
- if (x > 0)
- return 90;
- return 270;
- } else {
- if (y > 0)
- return 180;
- return 0;
- }
- }
-}
-
-int Actor::calcMovementFactor(const Common::Point& next) {
- Common::Point _actorPos(_pos);
- int diffX, diffY;
- int32 deltaXFactor, deltaYFactor;
-
- if (_actorPos == next)
- return 0;
-
- diffX = next.x - _actorPos.x;
- diffY = next.y - _actorPos.y;
- deltaYFactor = _speedy << 16;
-
- if (diffY < 0)
- deltaYFactor = -deltaYFactor;
-
- deltaXFactor = deltaYFactor * diffX;
- if (diffY != 0) {
- deltaXFactor /= diffY;
- } else {
- deltaYFactor = 0;
- }
-
- if ((uint) ABS((int)(deltaXFactor >> 16)) > _speedx) {
- deltaXFactor = _speedx << 16;
- if (diffX < 0)
- deltaXFactor = -deltaXFactor;
-
- deltaYFactor = deltaXFactor * diffY;
- if (diffX != 0) {
- deltaYFactor /= diffX;
- } else {
- deltaXFactor = 0;
- }
- }
-
- _walkdata.cur = _actorPos;
- _walkdata.next = next;
- _walkdata.deltaXFactor = deltaXFactor;
- _walkdata.deltaYFactor = deltaYFactor;
- _walkdata.xfrac = 0;
- _walkdata.yfrac = 0;
-
- _targetFacing = _vm->getAngleFromPos(deltaXFactor, deltaYFactor);
-
- return actorWalkStep();
-}
-
-int Actor::remapDirection(int dir, bool is_walking) {
- int specdir;
- byte flags;
- bool flipX;
- bool flipY;
-
- // FIXME - It seems that at least in The Dig the original code does
- // check _ignoreBoxes here. However, it breaks some animations in Loom,
- // causing Bobbin to face towards the camera instead of away from it
- // in some places: After the tree has been destroyed by lightning, and
- // when entering the dark tunnels beyond the dragon's lair at the very
- // least. Possibly other places as well.
- //
- // The Dig also checks if the actor is in the current room, but that's
- // not necessary here because we never call the function unless the
- // actor is in the current room anyway.
-
- if (!_ignoreBoxes || _vm->_gameId == GID_LOOM) {
- specdir = _vm->_extraBoxFlags[_walkbox];
- if (specdir) {
- if (specdir & 0x8000) {
- dir = specdir & 0x3FFF;
- } else {
- specdir = specdir & 0x3FFF;
- if (specdir - 90 < dir && dir < specdir + 90)
- dir = specdir;
- else
- dir = specdir + 180;
- }
- }
-
- flags = _vm->getBoxFlags(_walkbox);
-
- flipX = (_walkdata.deltaXFactor > 0);
- flipY = (_walkdata.deltaYFactor > 0);
-
- // Check for X-Flip
- if ((flags & kBoxXFlip) || isInClass(kObjectClassXFlip)) {
- dir = 360 - dir;
- flipX = !flipX;
- }
- // Check for Y-Flip
- if ((flags & kBoxYFlip) || isInClass(kObjectClassYFlip)) {
- dir = 180 - dir;
- flipY = !flipY;
- }
-
- switch (flags & 7) {
- case 1:
- if (_vm->_version >= 7) {
- if (dir < 180)
- return 90;
- else
- return 270;
- } else {
- if (is_walking) // Actor is walking
- return flipX ? 90 : 270;
- else // Actor is standing/turning
- return (dir == 90) ? 90 : 270;
- }
- case 2:
- if (_vm->_version >= 7) {
- if (dir > 90 && dir < 270)
- return 180;
- else
- return 0;
- } else {
- if (is_walking) // Actor is walking
- return flipY ? 180 : 0;
- else // Actor is standing/turning
- return (dir == 0) ? 0 : 180;
- }
- case 3:
- return 270;
- case 4:
- return 90;
- case 5:
- return 0;
- case 6:
- return 180;
- }
- }
- // OR 1024 in to signal direction interpolation should be done
- return normalizeAngle(dir) | 1024;
-}
-
-int Actor::updateActorDirection(bool is_walking) {
- int from;
- bool dirType = false;
- int dir;
- bool shouldInterpolate;
-
- if ((_vm->_version == 6) && _ignoreTurns)
- return _facing;
-
- dirType = (_vm->_version >= 7) ? _vm->_costumeLoader->hasManyDirections(_costume) : false;
-
- from = toSimpleDir(dirType, _facing);
- dir = remapDirection(_targetFacing, is_walking);
-
- if (_vm->_version >= 7)
- // Direction interpolation interfers with walk scripts in Dig; they perform
- // (much better) interpolation themselves.
- shouldInterpolate = false;
- else
- shouldInterpolate = (dir & 1024) ? true : false;
- dir &= 1023;
-
- if (shouldInterpolate) {
- int to = toSimpleDir(dirType, dir);
- int num = dirType ? 8 : 4;
-
- // Turn left or right, depending on which is shorter.
- int diff = to - from;
- if (ABS(diff) > (num >> 1))
- diff = -diff;
-
- if (diff > 0) {
- to = from + 1;
- } else if (diff < 0){
- to = from - 1;
- }
-
- dir = fromSimpleDir(dirType, (to + num) % num);
- }
-
- return dir;
-}
-
-void Actor::setBox(int box) {
- _walkbox = box;
- setupActorScale();
-}
-
-int Actor::actorWalkStep() {
- int tmpX, tmpY;
- Common::Point _actorPos;
- int distX, distY;
- int nextFacing;
-
- _needRedraw = true;
-
- nextFacing = updateActorDirection(true);
- if (!(_moving & MF_IN_LEG) || _facing != nextFacing) {
- if (_walkFrame != _frame || _facing != nextFacing) {
- startWalkAnim(1, nextFacing);
- }
- _moving |= MF_IN_LEG;
- }
-
- _actorPos = _pos;
-
- if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _actorPos.x, _actorPos.y)) {
- setBox(_walkdata.curbox);
- }
-
- distX = ABS(_walkdata.next.x - _walkdata.cur.x);
- distY = ABS(_walkdata.next.y - _walkdata.cur.y);
-
- if (ABS(_actorPos.x - _walkdata.cur.x) >= distX && ABS(_actorPos.y - _walkdata.cur.y) >= distY) {
- _moving &= ~MF_IN_LEG;
- return 0;
- }
-
- tmpX = (_actorPos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex;
- _walkdata.xfrac = (uint16)tmpX;
- _actorPos.x = (tmpX >> 16);
-
- tmpY = (_actorPos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley;
- _walkdata.yfrac = (uint16)tmpY;
- _actorPos.y = (tmpY >> 16);
-
- if (ABS(_actorPos.x - _walkdata.cur.x) > distX) {
- _actorPos.x = _walkdata.next.x;
- }
-
- if (ABS(_actorPos.y - _walkdata.cur.y) > distY) {
- _actorPos.y = _walkdata.next.y;
- }
-
- _pos = _actorPos;
- return 1;
-}
-
-
-void Actor::setupActorScale() {
-
- if (_vm->_features & GF_NO_SCALING) {
- _scalex = 0xFF;
- _scaley = 0xFF;
- return;
- }
-
- if (_ignoreBoxes)
- return;
-
- // For some boxes, we ignore the scaling and use whatever values the
- // scripts set. This is used e.g. in the Mystery Vortex in Sam&Max.
- // Older games used the flag 0x20 differently, though.
- if (_vm->_gameId == GID_SAMNMAX && (_vm->getBoxFlags(_walkbox) & kBoxIgnoreScale))
- return;
-
- _boxscale = _vm->getBoxScale(_walkbox);
-
- uint16 scale = _vm->getScale(_walkbox, _pos.x, _pos.y);
- assert(scale <= 0xFF);
-
- _scalex = _scaley = (byte)scale;
-}
-
-void Actor::startAnimActor(int f) {
- if (_vm->_version >= 7 && !((_vm->_gameId == GID_FT) && (_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
- switch (f) {
- case 1001:
- f = _initFrame;
- break;
- case 1002:
- f = _walkFrame;
- break;
- case 1003:
- f = _standFrame;
- break;
- case 1004:
- f = _talkStartFrame;
- break;
- case 1005:
- f = _talkStopFrame;
- break;
- }
-
- if (_costume != 0) {
- _animProgress = 0;
- _needRedraw = true;
- if (f == _initFrame)
- _cost.reset();
- _vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
- _frame = f;
- }
- } else {
- switch (f) {
- case 0x38:
- f = _initFrame;
- break;
- case 0x39:
- f = _walkFrame;
- break;
- case 0x3A:
- f = _standFrame;
- break;
- case 0x3B:
- f = _talkStartFrame;
- break;
- case 0x3C:
- f = _talkStopFrame;
- break;
- }
-
- assert(f != 0x3E);
-
- if (isInCurrentRoom() && _costume != 0) {
- _animProgress = 0;
- _cost.animCounter = 0;
- _needRedraw = true;
- // V1 - V2 games don't seem to need a _cost.reset() at this point.
- // Causes Zak to lose his body in several scenes, see bug #771508
- if (_vm->_version >= 3 && f == _initFrame) {
- _cost.reset();
- _auxBlock.reset();
- }
- _vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
- _frame = f;
- }
- }
-}
-
-void Actor::animateActor(int anim) {
- int cmd, dir;
-
- if (_vm->_version >= 7 && !((_vm->_gameId == GID_FT) && (_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
-
- if (anim == 0xFF)
- anim = 2000;
-
- cmd = anim / 1000;
- dir = anim % 1000;
-
- } else {
-
- cmd = anim / 4;
- dir = oldDirToNewDir(anim % 4);
-
- // Convert into old cmd code
- cmd = 0x3F - cmd + 2;
-
- }
-
- switch (cmd) {
- case 2: // stop walking
- startAnimActor(_standFrame);
- stopActorMoving();
- break;
- case 3: // change direction immediatly
- _moving &= ~MF_TURN;
- setDirection(dir);
- break;
- case 4: // turn to new direction
- turnToDirection(dir);
- break;
- default:
- if (_vm->_version <= 2)
- startAnimActor(anim / 4);
- else
- startAnimActor(anim);
- }
-}
-
-void Actor::setDirection(int direction) {
- uint aMask;
- int i;
- uint16 vald;
-
- // Do nothing if actor is already facing in the given direction
- if (_facing == direction)
- return;
-
- // Normalize the angle
- _facing = normalizeAngle(direction);
-
- // If there is no costume set for this actor, we are finished
- if (_costume == 0)
- return;
-
- // Update the costume for the new direction (and mark the actor for redraw)
- aMask = 0x8000;
- for (i = 0; i < 16; i++, aMask >>= 1) {
- vald = _cost.frame[i];
- if (vald == 0xFFFF)
- continue;
- _vm->_costumeLoader->costumeDecodeData(this, vald, (_vm->_version <= 2) ? 0xFFFF : aMask);
- }
-
- _needRedraw = true;
-}
-
-void Actor::drawActorToBackBuf(int x, int y) {
- int curTop = _top;
- int curBottom = _bottom;
-
- _pos.x = x;
- _pos.y = y;
-
- _drawToBackBuf = true;
- _needRedraw = true;
- drawActorCostume();
-
- _drawToBackBuf = false;
- _needRedraw = true;
- drawActorCostume();
- _needRedraw = false;
-
- if (_top > curTop)
- _top = curTop;
- if (_bottom < curBottom)
- _bottom = curBottom;
-}
-
-
-void Actor::putActor(int dstX, int dstY, byte newRoom) {
- if (_visible && _vm->_currentRoom != newRoom && _vm->getTalkingActor() == _number) {
- _vm->stopTalk();
- }
-
- // WORKAROUND: The green transparency of the tank in the Hall of Oddities is
- // is positioned one pixel too far to the left. This appears to be a
- // bug in the original game as well.
- if (_vm->_gameId == GID_SAMNMAX && newRoom == 16 && _number == 5 && dstX == 235 && dstY == 236)
- dstX++;
-
- _pos.x = dstX;
- _pos.y = dstY;
- _room = newRoom;
- _needRedraw = true;
-
- if (_vm->VAR(_vm->VAR_EGO) == _number) {
- _vm->_egoPositioned = true;
- }
-
- if (_visible) {
- if (isInCurrentRoom()) {
- if (_moving) {
- stopActorMoving();
- startAnimActor(_standFrame);
- }
- adjustActorPos();
- } else {
-#ifndef DISABLE_HE
- if (_vm->_heversion >= 71)
- ((ScummEngine_v71he *)_vm)->queueAuxBlock(this);
-#endif
- hideActor();
- }
- } else {
- if (isInCurrentRoom())
- showActor();
- }
-}
-
-int Actor::getActorXYPos(int &xPos, int &yPos) const {
- if (!isInCurrentRoom())
- return -1;
-
- xPos = _pos.x;
- yPos = _pos.y;
- return 0;
-}
-
-AdjustBoxResult Actor::adjustXYToBeInBox(int dstX, int dstY) {
- const uint thresholdTable[] = { 30, 80, 0 };
- AdjustBoxResult abr;
- int16 tmpX, tmpY;
- int tmpDist, bestDist, threshold, numBoxes;
- byte flags, bestBox;
- int box;
- const int firstValidBox = (_vm->_features & GF_SMALL_HEADER) ? 0 : 1;
-
- abr.x = dstX;
- abr.y = dstY;
- abr.box = kInvalidBox;
-
- if (_ignoreBoxes)
- return abr;
-
- for (int tIdx = 0; tIdx < ARRAYSIZE(thresholdTable); tIdx++) {
- threshold = thresholdTable[tIdx];
-
- numBoxes = _vm->getNumBoxes() - 1;
- if (numBoxes < firstValidBox)
- return abr;
-
- bestDist = (_vm->_version >= 7) ? 0x7FFFFFFF : 0xFFFF;
- if (_vm->_version <= 2)
- bestDist *= 8*2; // Adjust for the fact that we multiply x by 8 and y by 2
- bestBox = kInvalidBox;
-
- // We iterate (backwards) over all boxes, searching the one closest
- // to the desired coordinates.
- for (box = numBoxes; box >= firstValidBox; box--) {
- flags = _vm->getBoxFlags(box);
-
- // Skip over invisible boxes
- if (flags & kBoxInvisible && !(flags & kBoxPlayerOnly && !isPlayer()))
- continue;
-
- // For increased performance, we perform a quick test if
- // the coordinates can even be within a distance of 'threshold'
- // pixels of the box.
- if (threshold > 0 && _vm->inBoxQuickReject(box, dstX, dstY, threshold))
- continue;
-
- // Check if the point is contained in the box. If it is,
- // we don't have to search anymore.
- if (_vm->checkXYInBoxBounds(box, dstX, dstY)) {
- abr.x = dstX;
- abr.y = dstY;
- abr.box = box;
- return abr;
- }
-
- // Find the point in the box which is closest to our point.
- tmpDist = _vm->getClosestPtOnBox(box, dstX, dstY, tmpX, tmpY);
-
- // Check if the box is closer than the previous boxes.
- if (tmpDist < bestDist) {
- abr.x = tmpX;
- abr.y = tmpY;
-
- if (tmpDist == 0) {
- abr.box = box;
- return abr;
- }
- bestDist = tmpDist;
- bestBox = box;
- }
- }
-
- // If the closest ('best') box we found is within the threshold, or if
- // we are on the last run (i.e. threshold == 0), return that box.
- if (threshold == 0 || threshold * threshold >= bestDist) {
- abr.box = bestBox;
- return abr;
- }
- }
-
- return abr;
-}
-
-void Actor::adjustActorPos() {
- AdjustBoxResult abr;
-
- abr = adjustXYToBeInBox(_pos.x, _pos.y);
-
- _pos.x = abr.x;
- _pos.y = abr.y;
- _walkdata.destbox = abr.box;
-
- setBox(abr.box);
-
- _walkdata.dest.x = -1;
-
- stopActorMoving();
- _cost.soundCounter = 0;
-
- if (_walkbox != kInvalidBox) {
- byte flags = _vm->getBoxFlags(_walkbox);
- if (flags & 7) {
- turnToDirection(_facing);
- }
- }
-}
-
-void Actor::faceToObject(int obj) {
- int x2, y2, dir;
-
- if (!isInCurrentRoom())
- return;
-
- if (_vm->getObjectOrActorXY(obj, x2, y2) == -1)
- return;
-
- dir = (x2 > _pos.x) ? 90 : 270;
- turnToDirection(dir);
-}
-
-void Actor::turnToDirection(int newdir) {
- if (newdir == -1 || _ignoreTurns)
- return;
-
- _moving &= ~MF_TURN;
-
- if (newdir != _facing) {
- if (_vm->_version <= 3)
- _moving = MF_TURN;
- else
- _moving |= MF_TURN;
- _targetFacing = newdir;
- }
-}
-
-void Actor::hideActor() {
- if (!_visible)
- return;
-
- if (_moving) {
- stopActorMoving();
- startAnimActor(_standFrame);
- }
- _visible = false;
- _cost.soundCounter = 0;
- _needRedraw = false;
- _needBgReset = true;
- _auxBlock.reset();
-}
-
-void Actor::showActor() {
- if (_vm->_currentRoom == 0 || _visible)
- return;
-
- adjustActorPos();
-
- _vm->ensureResourceLoaded(rtCostume, _costume);
-
- if (_costumeNeedsInit) {
- startAnimActor(_initFrame);
- if (_vm->_version <= 2) {
- startAnimActor(_standFrame);
- startAnimActor(_talkStopFrame);
- }
- _costumeNeedsInit = false;
- }
-
- // FIXME: Evil hack to work around bug #770717
- if (!_moving && _vm->_version <= 2)
- startAnimActor(_standFrame);
-
- stopActorMoving();
- _visible = true;
- _needRedraw = true;
-}
-
-// V1 Maniac doesn't have a ScummVar for VAR_TALK_ACTOR, and just uses
-// an internal variable. Emulate this to prevent overwriting script vars...
-// Maniac NES (V1), however, DOES have a ScummVar for VAR_TALK_ACTOR
-int ScummEngine::getTalkingActor() {
- if (_gameId == GID_MANIAC && _version == 1 && !(_platform == Common::kPlatformNES))
- return _V1TalkingActor;
- else
- return VAR(VAR_TALK_ACTOR);
-}
-
-void ScummEngine::setTalkingActor(int value) {
- if (_gameId == GID_MANIAC && _version == 1 && !(_platform == Common::kPlatformNES))
- _V1TalkingActor = value;
- else
- VAR(VAR_TALK_ACTOR) = value;
-}
-
-void ScummEngine::putActors() {
- Actor *a;
- int i;
-
- for (i = 1; i < _numActors; i++) {
- a = &_actors[i];
- if (a && a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- }
-}
-
-static const int c64MMActorTalkColor[25] = {
- 1, 7, 2, 14, 8, 15, 3, 7, 7, 15, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 1, 7
-};
-static const int v1MMActorTalkColor[25] = {
- 1, 7, 2, 14, 8, 1, 3, 7, 7, 12, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 7, 7
-};
-
-void ScummEngine::setupV1ActorTalkColor() {
- int i;
-
- for (i = 1; i < _numActors; i++) {
- if (_platform == Common::kPlatformC64) {
- _actors[i]._talkColor = c64MMActorTalkColor[i];
- } else {
- _actors[i]._talkColor = v1MMActorTalkColor[i];
- }
- }
-}
-
-void ScummEngine::showActors() {
- int i;
-
- for (i = 1; i < _numActors; i++) {
- if (_actors[i].isInCurrentRoom())
- _actors[i].showActor();
- }
-}
-
-void ScummEngine::walkActors() {
- int i;
-
- for (i = 1; i < _numActors; i++) {
- if (_actors[i].isInCurrentRoom())
- if (_version <= 3)
- _actors[i].walkActorOld();
- else
- _actors[i].walkActor();
- }
-}
-
-/* Used in Scumm v5 only. Play sounds associated with actors */
-void ScummEngine::playActorSounds() {
- int i;
-
- for (i = 1; i < _numActors; i++) {
- if (_actors[i]._cost.soundCounter && _actors[i].isInCurrentRoom() && _actors[i]._sound) {
- _currentScript = 0xFF;
- _sound->addSoundToQueue(_actors[i]._sound[0]);
- for (i = 1; i < _numActors; i++) {
- _actors[i]._cost.soundCounter = 0;
- }
- return;
- }
- }
-}
-
-bool ScummEngine::isValidActor(int id) const {
- return id >= 0 && id < _numActors && _actors[id]._number == id;
-}
-
-Actor *ScummEngine::derefActor(int id, const char *errmsg) const {
- if (id == 0)
- debugC(DEBUG_ACTORS, "derefActor(0, \"%s\") in script %d, opcode 0x%x",
- errmsg, vm.slot[_currentScript].number, _opcode);
-
- if (!isValidActor(id)) {
- if (errmsg)
- error("Invalid actor %d in %s", id, errmsg);
- else
- error("Invalid actor %d", id);
- }
- return &_actors[id];
-}
-
-Actor *ScummEngine::derefActorSafe(int id, const char *errmsg) const {
- if (id == 0)
- debugC(DEBUG_ACTORS, "derefActorSafe(0, \"%s\") in script %d, opcode 0x%x",
- errmsg, vm.slot[_currentScript].number, _opcode);
-
- if (!isValidActor(id)) {
- debugC(DEBUG_ACTORS, "Invalid actor %d in %s (script %d, opcode 0x%x)",
- id, errmsg, vm.slot[_currentScript].number, _opcode);
- return NULL;
- }
- return &_actors[id];
-}
-
-void ScummEngine::processActors() {
- int numactors = 0;
-
- // Make a list of all actors in this room
- for (int i = 1; i < _numActors; i++) {
- if (_version == 8 && _actors[i]._layer < 0)
- continue;
- if (_actors[i].isInCurrentRoom()) {
- _sortedActors[numactors++] = &_actors[i];
- }
- }
- if (!numactors) {
- return;
- }
-
- // Sort actors by position before drawing them (to ensure that actors
- // in front are drawn after those "behind" them).
- //
- // Note: This algorithm works exactly the way the original engine did.
- // Please resist any urge to 'optimize' this. Many of the games rely on
- // the quirks of this particular sorting algorithm, and since we are
- // dealing with far less than 100 objects being sorted here, any
- // 'optimization' wouldn't yield a useful gain anyway.
- //
- // In particular, changing this loop caused a number of bugs in the
- // past, including bugs #758167, #775097, and #1093867.
- //
- // Note that Sam & Max uses a stable sorting method. Older games don't
- // and, according to cyx, neither do newer ones. At least not FT and
- // COMI. See bug #1220168 for more details.
-
- if (_gameId == GID_SAMNMAX) {
- for (int j = 0; j < numactors; ++j) {
- for (int i = 0; i < numactors; ++i) {
- int sc_actor1 = _sortedActors[j]->_pos.y;
- int sc_actor2 = _sortedActors[i]->_pos.y;
- if (sc_actor1 == sc_actor2) {
- sc_actor1 += _sortedActors[j]->_number;
- sc_actor2 += _sortedActors[i]->_number;
- }
- if (sc_actor1 < sc_actor2) {
- SWAP(_sortedActors[i], _sortedActors[j]);
- }
- }
- }
- } else {
- for (int j = 0; j < numactors; ++j) {
- for (int i = 0; i < numactors; ++i) {
- int sc_actor1 = _sortedActors[j]->_pos.y - _sortedActors[j]->_layer * 2000;
- int sc_actor2 = _sortedActors[i]->_pos.y - _sortedActors[i]->_layer * 2000;
- if (sc_actor1 < sc_actor2) {
- SWAP(_sortedActors[i], _sortedActors[j]);
- }
- }
- }
- }
-
- // Finally draw the now sorted actors
- Actor** end = _sortedActors + numactors;
- for (Actor** ac = _sortedActors; ac != end; ++ac) {
- Actor* a = *ac;
- // Draw and animate the actors, except those w/o a costume.
- // Note: We could 'optimize' this a little bit by only putting
- // actors with a costume into the _sortedActors array in the
- // first place. However, that would mess up the sorting, and
- // would hence cause regressions. See also the other big
- // comment further up in this method for some details.
- if (a->_costume) {
- a->drawActorCostume();
- a->animateCostume();
- }
- }
-
- if (_features & GF_NEW_COSTUMES)
- akos_processQueue();
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v71he::processActors() {
- preProcessAuxQueue();
-
- if (!_skipProcessActors)
- ScummEngine::processActors();
-
- _fullRedraw = false;
-
- postProcessAuxQueue();
-}
-
-void ScummEngine_v90he::processActors() {
- preProcessAuxQueue();
-
- _sprite->setRedrawFlags(false);
- _sprite->processImages(true);
-
- if (!_skipProcessActors)
- ScummEngine::processActors();
-
- _fullRedraw = false;
-
- postProcessAuxQueue();
-
- _sprite->setRedrawFlags(true);
- _sprite->processImages(false);
-}
-#endif
-
-// Used in Scumm v8, to allow the verb coin to be drawn over the inventory
-// chest. I'm assuming that draw order won't matter here.
-void ScummEngine::processUpperActors() {
- int i;
-
- for (i = 1; i < _numActors; i++) {
- if (_actors[i].isInCurrentRoom() && _actors[i]._costume && _actors[i]._layer < 0) {
- CHECK_HEAP
- _actors[i].drawActorCostume();
- CHECK_HEAP
- _actors[i].animateCostume();
- }
- }
-}
-
-void Actor::drawActorCostume(bool hitTestMode) {
- if (_costume == 0)
- return;
-
- if (!hitTestMode) {
- if (!_needRedraw)
- return;
-
- _needRedraw = false;
- }
-
- setupActorScale();
-
- BaseCostumeRenderer* bcr = _vm->_costumeRenderer;
-
- bcr->_actorID = _number;
-
- bcr->_actorX = _pos.x + _offsX - _vm->virtscr[0].xstart;
- bcr->_actorY = _pos.y + _offsY - _elevation;
-
- if (_vm->_platform == Common::kPlatformNES) {
- // In the NES version, when the actor is facing right,
- // we need to shift it 8 pixels to the left
- if (_facing == 90)
- bcr->_actorX -= 8;
- } else if (_vm->_version <= 2) {
- // HACK: We have to adjust the x position by one strip (8 pixels) in
- // V2 games. However, it is not quite clear to me why. And to fully
- // match the original, it seems we have to offset by 2 strips if the
- // actor is facing left (270 degree).
- // V1 games are once again slightly different, here we only have
- // to adjust the 270 degree case...
- if (_facing == 270)
- bcr->_actorX += 16;
- else if (_vm->_version == 2)
- bcr->_actorX += 8;
- }
-
- bcr->_clipOverride = _clipOverride;
-
- if (_vm->_version == 4 && _boxscale & 0x8000) {
- bcr->_scaleX = bcr->_scaleY = _vm->getScaleFromSlot((_boxscale & 0x7fff) + 1, _pos.x, _pos.y);
- } else {
- bcr->_scaleX = _scalex;
- bcr->_scaleY = _scaley;
- }
-
- bcr->_shadow_mode = _shadowMode;
- if (_vm->_version >= 5 && _vm->_heversion == 0) {
- bcr->_shadow_table = _vm->_shadowPalette;
- } else if (_vm->_heversion == 70) {
- bcr->_shadow_table = _vm->_HEV7ActorPalette;
- }
-
- bcr->setCostume(_costume, _heXmapNum);
- bcr->setPalette(_palette);
- bcr->setFacing(this);
-
- if (_vm->_version >= 7) {
-
- bcr->_zbuf = _forceClip;
- if (bcr->_zbuf == 100) {
- bcr->_zbuf = _vm->getMaskFromBox(_walkbox);
- if (bcr->_zbuf > _vm->gdi._numZBuffer-1)
- bcr->_zbuf = _vm->gdi._numZBuffer-1;
- }
-
- } else {
- if (_forceClip)
- bcr->_zbuf = _forceClip;
- else if (isInClass(kObjectClassNeverClip))
- bcr->_zbuf = 0;
- else {
- bcr->_zbuf = _vm->getMaskFromBox(_walkbox);
- if (bcr->_zbuf > _vm->gdi._numZBuffer-1)
- bcr->_zbuf = _vm->gdi._numZBuffer-1;
- }
-
- }
-
- bcr->_draw_top = 0x7fffffff;
- bcr->_draw_bottom = 0;
-
- bcr->_skipLimbs = (_heSkipLimbs != 0);
- bcr->_paletteNum = _hePaletteNum;
-
- if (_vm->_heversion >= 80 && _heNoTalkAnimation == 0 && _animProgress == 0) {
- if (_vm->getTalkingActor() == _number && !_vm->_string[0].no_talk_anim) {
- int talkState = 0;
-
- if (_vm->_sound->isSoundCodeUsed(1))
- talkState = _vm->_sound->getSoundVar(1, 19);
- if (talkState == 0)
- talkState = _vm->_rnd.getRandomNumberRng(1, 10);
-
- checkRange(13, 1, talkState, "Talk state %d out of range");
- setTalkCondition(talkState);
- } else {
- setTalkCondition(1);
- }
- }
- _heNoTalkAnimation = 0;
-
- // If the actor is partially hidden, redraw it next frame.
- // Only done for pre-AKOS, though.
- if (bcr->drawCostume(_vm->virtscr[0], _vm->gdi._numStrips, this, _drawToBackBuf) & 1) {
- _needRedraw = (_vm->_version <= 6);
- }
-
- if (!hitTestMode) {
- // Record the vertical extent of the drawn actor
- _top = bcr->_draw_top;
- _bottom = bcr->_draw_bottom;
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-bool Actor::actorHitTest(int x, int y) {
- AkosRenderer *ar = (AkosRenderer *)_vm->_costumeRenderer;
-
- ar->_actorHitX = x;
- ar->_actorHitY = y;
- ar->_actorHitMode = true;
- ar->_actorHitResult = false;
-
- drawActorCostume(true);
-
- ar->_actorHitMode = false;
-
- return ar->_actorHitResult;
-}
-#endif
-
-void Actor::animateCostume() {
- if (_costume == 0)
- return;
-
- _animProgress++;
- if (_animProgress >= _animSpeed) {
- _animProgress = 0;
-
- _vm->_costumeLoader->loadCostume(_costume);
- if (_vm->_costumeLoader->increaseAnims(this)) {
- _needRedraw = true;
- }
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void Actor::animateLimb(int limb, int f) {
- // This methods is very similiar to animateCostume().
- // However, instead of animating *all* the limbs, it only animates
- // the specified limb to be at the frame specified by "f".
-
- if (!f)
- return;
-
- _animProgress++;
- if (_animProgress >= _animSpeed) {
- _animProgress = 0;
-
- if (_costume == 0)
- return;
-
- const byte *aksq, *akfo;
- uint size;
- byte *akos = _vm->getResourceAddress(rtCostume, _costume);
- assert(akos);
-
- aksq = _vm->findResourceData(MKID('AKSQ'), akos);
- akfo = _vm->findResourceData(MKID('AKFO'), akos);
-
- size = _vm->getResourceDataSize(akfo) / 2;
-
- while (f--) {
- if (_cost.active[limb] != 0)
- _vm->akos_increaseAnim(this, limb, aksq, (const uint16 *)akfo, size);
- }
-
-// _needRedraw = true;
-// _needBgReset = true;
- }
-}
-#endif
-
-void ScummEngine::redrawAllActors() {
- int j;
-
- for (j = 1; j < _numActors; j++) {
- _actors[j]._needRedraw = true;
- _actors[j]._needBgReset = true;
- }
-}
-
-void ScummEngine::setActorRedrawFlags() {
- int i, j;
-
- // Redraw all actors if a full redraw was requested.
- // Also redraw all actors in COMI (see bug #1066329 for details).
- if (_fullRedraw || _version == 8 || (VAR_REDRAW_ALL_ACTORS != 0xFF && VAR(VAR_REDRAW_ALL_ACTORS) != 0)) {
- for (j = 1; j < _numActors; j++) {
- _actors[j]._needRedraw = true;
- }
- } else {
- for (i = 0; i < gdi._numStrips; i++) {
- int strip = _screenStartStrip + i;
- if (testGfxAnyUsageBits(strip)) {
- for (j = 1; j < _numActors; j++) {
- if (testGfxUsageBit(strip, j) && testGfxOtherUsageBits(strip, j)) {
- _actors[j]._needRedraw = true;
- }
- }
- }
- }
- }
-}
-
-void ScummEngine::resetActorBgs() {
- int i, j;
-
- for (i = 0; i < gdi._numStrips; i++) {
- int strip = _screenStartStrip + i;
- clearGfxUsageBit(strip, USAGE_BIT_DIRTY);
- clearGfxUsageBit(strip, USAGE_BIT_RESTORED);
- for (j = 1; j < _numActors; j++) {
- if (testGfxUsageBit(strip, j) &&
- ((_actors[j]._top != 0x7fffffff && _actors[j]._needRedraw) || _actors[j]._needBgReset)) {
- clearGfxUsageBit(strip, j);
- if ((_actors[j]._bottom - _actors[j]._top) >= 0)
- gdi.resetBackground(_actors[j]._top, _actors[j]._bottom, i);
- }
- }
- }
-
- for (i = 1; i < _numActors; i++) {
- _actors[i]._needBgReset = false;
- }
-}
-
-int ScummEngine::getActorFromPos(int x, int y) {
- int i;
-
- if (!testGfxAnyUsageBits(x / 8))
- return 0;
-
- for (i = 1; i < _numActors; i++) {
- if (testGfxUsageBit(x / 8, i) && !getClass(i, kObjectClassUntouchable)
- && y >= _actors[i]._top && y <= _actors[i]._bottom) {
- if (_version > 2 || i != VAR(VAR_EGO))
- return i;
- }
- }
-
- return 0;
-}
-
-#ifndef DISABLE_HE
-int ScummEngine_v70he::getActorFromPos(int x, int y) {
- int curActor, i;
-
- if (!testGfxAnyUsageBits(x / 8))
- return 0;
-
- curActor = 0;
- for (i = 1; i < _numActors; i++) {
- if (testGfxUsageBit(x / 8, i) && !getClass(i, kObjectClassUntouchable)
- && y >= _actors[i]._top && y <= _actors[i]._bottom
- && (_actors[i]._pos.y > _actors[curActor]._pos.y || curActor == 0))
- curActor = i;
- }
-
- return curActor;
-}
-#endif
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::actorTalk(const byte *msg) {
- Actor *a;
-
- convertMessageToString(msg, _charsetBuffer, sizeof(_charsetBuffer));
-
- // Play associated speech, if any
- playSpeech((byte *)_lastStringTag);
-
- if ((_version == 7 && !_keepText) || (_version == 8 && VAR(VAR_HAVE_MSG))) {
- stopTalk();
- }
- if (_actorToPrintStrFor == 0xFF) {
- setTalkingActor(0xFF);
- } else {
- a = derefActor(_actorToPrintStrFor, "actorTalk");
- setTalkingActor(a->_number);
- if (!_string[0].no_talk_anim) {
- a->runActorTalkScript(a->_talkStartFrame);
- _useTalkAnims = true;
- }
- }
-
- if (getTalkingActor() > 0x7F) {
- _charsetColor = (byte)_string[0].color;
- } else {
- a = derefActor(getTalkingActor(), "actorTalk(2)");
- _charsetColor = a->_talkColor;
- }
- _charsetBufPos = 0;
- _talkDelay = 0;
- _haveMsg = 1;
- if (_version == 7)
- VAR(VAR_HAVE_MSG) = 0xFF;
- _haveActorSpeechMsg = true;
- CHARSET_1();
- if (_version == 8)
- VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
-}
-#endif
-
-void ScummEngine::actorTalk(const byte *msg) {
- Actor *a;
-
- convertMessageToString(msg, _charsetBuffer, sizeof(_charsetBuffer));
-
- // FIXME: Workaround for bugs #770039 and #770049
- if (_gameId == GID_LOOM) {
- if (!*_charsetBuffer)
- return;
- }
-
- if (_actorToPrintStrFor == 0xFF) {
- if (!_keepText) {
- stopTalk();
- }
- setTalkingActor(0xFF);
- } else {
- int oldact;
-
- // WORKAROUND bug #770724
- if (_gameId == GID_LOOM && _roomResource == 23 &&
- vm.slot[_currentScript].number == 232 && _actorToPrintStrFor == 0) {
- _actorToPrintStrFor = 2; // Could be anything from 2 to 5. Maybe compare to original?
- }
-
- a = derefActor(_actorToPrintStrFor, "actorTalk");
- if (!a->isInCurrentRoom()) {
- oldact = 0xFF;
- } else {
- if (!_keepText) {
- stopTalk();
- }
- setTalkingActor(a->_number);
- a->_heTalking = true;
- if (!_string[0].no_talk_anim) {
- a->runActorTalkScript(a->_talkStartFrame);
- _useTalkAnims = true;
- }
- oldact = getTalkingActor();
- }
- if (oldact >= 0x80)
- return;
- }
-
- if (_heversion >= 72 || getTalkingActor() > 0x7F) {
- _charsetColor = (byte)_string[0].color;
- } else if (_platform == Common::kPlatformNES) {
- if (_NES_lastTalkingActor != getTalkingActor())
- _NES_talkColor ^= 1;
- _NES_lastTalkingActor = getTalkingActor();
- _charsetColor = _NES_talkColor;
- } else {
- a = derefActor(getTalkingActor(), "actorTalk(2)");
- _charsetColor = a->_talkColor;
- }
- _charsetBufPos = 0;
- _talkDelay = 0;
- _haveMsg = 0xFF;
- VAR(VAR_HAVE_MSG) = 0xFF;
- if (VAR_CHARCOUNT != 0xFF)
- VAR(VAR_CHARCOUNT) = 0;
- _haveActorSpeechMsg = true;
- CHARSET_1();
-}
-
-void Actor::runActorTalkScript(int f) {
- if (_vm->_version == 8 && _vm->VAR(_vm->VAR_HAVE_MSG) == 2)
- return;
-
- if (_talkScript) {
- int script = _talkScript;
- int args[16];
- memset(args, 0, sizeof(args));
- args[1] = f;
- args[0] = _number;
-
- _vm->runScript(script, 1, 0, args);
- } else {
- if (_frame != f)
- startAnimActor(f);
- }
-}
-
-void ScummEngine::stopTalk() {
- int act;
-
- _sound->stopTalkSound();
-
- _haveMsg = 0;
- _talkDelay = 0;
-
- act = getTalkingActor();
- if (act && act < 0x80) {
- Actor *a = derefActor(act, "stopTalk");
- if ((_version >= 7 && !_string[0].no_talk_anim) ||
- (_version <= 6 && a->isInCurrentRoom() && _useTalkAnims)) {
- a->runActorTalkScript(a->_talkStopFrame);
- _useTalkAnims = false;
- }
- if (_version <= 7 && _heversion == 0)
- setTalkingActor(0xFF);
- a->_heTalking = false;
- }
- if (_version == 8 || _heversion >= 60)
- setTalkingActor(0);
- if (_version == 8)
- VAR(VAR_HAVE_MSG) = 0;
- _keepText = false;
- if (_version >= 7) {
-#ifndef DISABLE_SCUMM_7_8
- ((ScummEngine_v7 *)this)->clearSubtitleQueue();
-#endif
- } else {
- _charset->restoreCharsetBg();
- }
-}
-
-void Actor::setActorCostume(int c) {
- int i;
-
- if (_vm->_heversion >= 61 && (c == -1 || c == -2)) {
- _heSkipLimbs = (c == -1);
- _needRedraw = true;
- return;
- }
-
- // Based on disassembly. It seems that high byte is not used at all, though
- // it is attached to all horizontally flipped object, like left eye.
- if (_vm->_heversion == 61)
- c &= 0xff;
-
- _costumeNeedsInit = true;
-
- if (_vm->_features & GF_NEW_COSTUMES) {
- memset(_animVariable, 0, sizeof(_animVariable));
-
-#ifndef DISABLE_HE
- if (_vm->_heversion >= 71)
- ((ScummEngine_v71he *)_vm)->queueAuxBlock(this);
-#endif
-
- _costume = c;
- _cost.reset();
- _auxBlock.reset();
-
- if (_visible) {
- if (_costume) {
- _vm->ensureResourceLoaded(rtCostume, _costume);
- }
- startAnimActor(_initFrame);
- }
- } else {
- if (_visible) {
- hideActor();
- _cost.reset();
- _costume = c;
- showActor();
- } else {
- _costume = c;
- _cost.reset();
- }
- }
-
-
- // V1 zak uses palette[] as a dynamic costume color array.
- if (_vm->_version == 1)
- return;
-
- if (_vm->_features & GF_NEW_COSTUMES) {
- for (i = 0; i < 256; i++)
- _palette[i] = 0xFF;
- } else if (_vm->_features & GF_OLD_BUNDLE) {
- for (i = 0; i < 16; i++)
- _palette[i] = i;
-
- // Make stuff more visible on CGA. Based on disassembly
- if (_vm->_renderMode == Common::kRenderCGA && _vm->_version > 2) {
- _palette[6] = 5;
- _palette[7] = 15;
- }
- } else {
- for (i = 0; i < 32; i++)
- _palette[i] = 0xFF;
- }
-
- if (_vm->_heversion >= 71 && _vm->getTalkingActor() == _number) {
- if (_vm->_heversion <= 95 || (_vm->_heversion >= 98 && _vm->VAR(_vm->VAR_SKIP_RESET_TALK_ACTOR) == 0)) {
- //_vm->setTalkingActor(0);
- }
- }
-}
-
-void Actor::startWalkActor(int destX, int destY, int dir) {
- AdjustBoxResult abr;
-
- if (_vm->_version <= 3) {
- abr.x = destX;
- abr.y = destY;
- } else {
- abr = adjustXYToBeInBox(destX, destY);
- }
-
- if (!isInCurrentRoom()) {
- _pos.x = abr.x;
- _pos.y = abr.y;
- if (!(_vm->_version == 6 && _ignoreTurns) && dir != -1)
- setDirection(dir);
- return;
- }
-
- if (_ignoreBoxes) {
- abr.box = kInvalidBox;
- _walkbox = kInvalidBox;
- } else {
- if (_vm->checkXYInBoxBounds(_walkdata.destbox, abr.x, abr.y)) {
- abr.box = _walkdata.destbox;
- } else {
- abr = adjustXYToBeInBox(abr.x, abr.y);
- }
- if (_moving && _walkdata.destdir == dir && _walkdata.dest.x == abr.x && _walkdata.dest.y == abr.y)
- return;
- }
-
- if (_pos.x == abr.x && _pos.y == abr.y) {
- turnToDirection(dir);
- return;
- }
-
- _walkdata.dest.x = abr.x;
- _walkdata.dest.y = abr.y;
- _walkdata.destbox = abr.box;
- _walkdata.destdir = dir;
- _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
- _walkdata.point3.x = 32000;
-
- _walkdata.curbox = _walkbox;
-}
-
-void Actor::startWalkAnim(int cmd, int angle) {
- if (angle == -1)
- angle = _facing;
-
- /* Note: walk scripts aren't required to make the Dig
- * work as usual
- */
- if (_walkScript) {
- int args[16];
- memset(args, 0, sizeof(args));
- args[0] = _number;
- args[1] = cmd;
- args[2] = angle;
- _vm->runScript(_walkScript, 1, 0, args);
- } else {
- switch (cmd) {
- case 1: /* start walk */
- setDirection(angle);
- startAnimActor(_walkFrame);
- break;
- case 2: /* change dir only */
- setDirection(angle);
- break;
- case 3: /* stop walk */
- turnToDirection(angle);
- startAnimActor(_standFrame);
- break;
- }
- }
-}
-
-void Actor::walkActor() {
- int new_dir, next_box;
- Common::Point foundPath;
-
- if (_vm->_version >= 7) {
- if (_moving & MF_FROZEN) {
- if (_moving & MF_TURN) {
- new_dir = updateActorDirection(false);
- if (_facing != new_dir)
- setDirection(new_dir);
- else
- _moving &= ~MF_TURN;
- }
- return;
- }
- }
-
- if (!_moving)
- return;
-
- if (!(_moving & MF_NEW_LEG)) {
- if (_moving & MF_IN_LEG && actorWalkStep())
- return;
-
- if (_moving & MF_LAST_LEG) {
- _moving = 0;
- setBox(_walkdata.destbox);
- startWalkAnim(3, _walkdata.destdir);
- return;
- }
-
- if (_moving & MF_TURN) {
- new_dir = updateActorDirection(false);
- if (_facing != new_dir)
- setDirection(new_dir);
- else
- _moving = 0;
- return;
- }
-
- setBox(_walkdata.curbox);
- _moving &= MF_IN_LEG;
- }
-
- _moving &= ~MF_NEW_LEG;
- do {
-
- if (_walkbox == kInvalidBox) {
- setBox(_walkdata.destbox);
- _walkdata.curbox = _walkdata.destbox;
- break;
- }
-
- if (_walkbox == _walkdata.destbox)
- break;
-
- next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
- if (next_box < 0) {
- _walkdata.destbox = _walkbox;
- _moving |= MF_LAST_LEG;
- return;
- }
-
- _walkdata.curbox = next_box;
-
- if (findPathTowards(_walkbox, next_box, _walkdata.destbox, foundPath))
- break;
-
- if (calcMovementFactor(foundPath))
- return;
-
- setBox(_walkdata.curbox);
- } while (1);
-
- _moving |= MF_LAST_LEG;
- calcMovementFactor(_walkdata.dest);
-}
-
-/*
-void Actor::walkActorV12() {
- Common::Point foundPath, tmp;
- int new_dir, next_box;
-
- if (_moving & MF_TURN) {
- new_dir = updateActorDirection(false);
- if (_facing != new_dir)
- setDirection(new_dir);
- else
- _moving = 0;
- return;
- }
-
- if (!_moving)
- return;
-
- if (_moving & MF_IN_LEG) {
- actorWalkStep();
- } else {
- if (_moving & MF_LAST_LEG) {
- _moving = 0;
- startWalkAnim(3, _walkdata.destdir);
- } else {
- setBox(_walkdata.curbox);
- if (_walkbox == _walkdata.destbox) {
- foundPath = _walkdata.dest;
- _moving |= MF_LAST_LEG;
- } else {
- next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
- if (next_box < 0) {
- _moving |= MF_LAST_LEG;
- return;
- }
-
- // Can't walk through locked boxes
- int flags = _vm->getBoxFlags(next_box);
- if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isPlayer())) {
- _moving |= MF_LAST_LEG;
- }
-
- _walkdata.curbox = next_box;
-
- _vm->getClosestPtOnBox(_walkdata.curbox, x, y, tmp.x, tmp.y);
- _vm->getClosestPtOnBox(_walkbox, tmp.x, tmp.y, foundPath.x, foundPath.y);
- }
- calcMovementFactor(foundPath);
- }
- }
-}
-*/
-
-void Actor::walkActorOld() {
- Common::Point p2, p3; // Gate locations
- int new_dir, next_box;
-
- if (!_moving)
- return;
-
- if (!(_moving & MF_NEW_LEG)) {
- if (_moving & MF_IN_LEG && actorWalkStep())
- return;
-
- if (_moving & MF_LAST_LEG) {
- _moving = 0;
- startWalkAnim(3, _walkdata.destdir);
- return;
- }
-
- if (_moving & MF_TURN) {
- new_dir = updateActorDirection(false);
- if (_facing != new_dir)
- setDirection(new_dir);
- else
- _moving = 0;
- return;
- }
-
- if (_walkdata.point3.x != 32000) {
- if (calcMovementFactor(_walkdata.point3)) {
- _walkdata.point3.x = 32000;
- return;
- }
- _walkdata.point3.x = 32000;
- }
-
- setBox(_walkdata.curbox);
- _moving &= MF_IN_LEG;
- }
-
- _moving &= ~MF_NEW_LEG;
- do {
- if (_walkbox == kInvalidBox) {
- setBox(_walkdata.destbox);
- _walkdata.curbox = _walkdata.destbox;
- break;
- }
-
- if (_walkbox == _walkdata.destbox)
- break;
-
- next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
-
- // WORKAROUND: To fully fix bug #774783, we add a special case
- // here, resulting in a different next_box value for Hitler.
- if ((_vm->_gameId == GID_INDY3) && _vm->_roomResource == 46 && _walkbox == 1 && _walkdata.destbox == 0 && _number == 9)
- next_box = 1;
-
- if (next_box < 0) {
- _moving |= MF_LAST_LEG;
- return;
- }
-
- // Can't walk through locked boxes
- int flags = _vm->getBoxFlags(next_box);
- if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isPlayer())) {
- _moving |= MF_LAST_LEG;
-// FIXME: Work in progress
-// _walkdata.destdir = _facing;
- return;
- }
-
- _walkdata.curbox = next_box;
-
- if (_vm->_version <= 2) {
- _vm->getClosestPtOnBox(_walkdata.curbox, _pos.x, _pos.y, p2.x, p2.y);
- _vm->getClosestPtOnBox(_walkbox, p2.x, p2.y, p3.x, p3.y);
-// FIXME: Work in progress
-// calcMovementFactor(p3);
-// return;
- } else {
- findPathTowardsOld(_walkbox, next_box, _walkdata.destbox, p2, p3);
- if (p2.x == 32000 && p3.x == 32000) {
- break;
- }
-
- if (p2.x != 32000) {
- if (calcMovementFactor(p2)) {
- _walkdata.point3 = p3;
- return;
- }
- }
- }
- if (calcMovementFactor(p3))
- return;
-
- setBox(_walkdata.destbox);
- } while (1);
-
- _moving |= MF_LAST_LEG;
- calcMovementFactor(_walkdata.dest);
-}
-
-byte *Actor::getActorName() {
- byte *ptr = _vm->getResourceAddress(rtActorName, _number);
- if (ptr == NULL) {
- debug(0, "Failed to find name of actor %d", _number);
- }
- return ptr;
-}
-
-int Actor::getAnimVar(byte var) const {
- checkRange(26, 0, var, "getAnimVar %d out of range(r)");
- return _animVariable[var];
-}
-
-void Actor::setAnimVar(byte var, int value) {
- checkRange(26, 0, var, "setAnimVar %d out of range(r)");
- _animVariable[var] = value;
-}
-
-void Actor::remapActorPaletteColor(int color, int new_color) {
- const byte *akos, *akpl;
- int akpl_size, i;
- byte akpl_color;
-
- akos = _vm->getResourceAddress(rtCostume, _costume);
- if (!akos) {
- debug(0, "Can't remap actor %d, costume %d not found", _number, _costume);
- return;
- }
-
- akpl = _vm->findResourceData(MKID('AKPL'), akos);
- if (!akpl) {
- debug(0, "Can't remap actor %d, costume %d doesn't contain an AKPL block", _number, _costume);
- return;
- }
-
- // Get the number palette entries
- akpl_size = _vm->getResourceDataSize(akpl);
-
- for (i = 0; i < akpl_size; i++) {
- akpl_color = *akpl++;
- if (akpl_color == color) {
- _palette[i] = new_color;
- return;
- }
- }
-}
-
-void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold) {
- const byte *akos, *rgbs, *akpl;
- int akpl_size, i;
- int r, g, b;
- byte akpl_color;
-
- if (!isInCurrentRoom()) {
- debugC(DEBUG_ACTORS, "Remap actor %d not in current room", _number);
- return;
- } else if (_costume < 1 || _costume >= _vm->_numCostumes - 1) {
- debugC(DEBUG_ACTORS, "Remap actor %d invalid costume %d", _number, _costume);
- return;
- }
-
- akos = _vm->getResourceAddress(rtCostume, _costume);
- if (!akos) {
- debug(0, "Can't remap actor %d, costume %d not found", _number, _costume);
- return;
- }
-
- akpl = _vm->findResourceData(MKID('AKPL'), akos);
- if (!akpl) {
- debug(0, "Can't remap actor %d, costume %d doesn't contain an AKPL block", _number, _costume);
- return;
- }
-
- // Get the number palette entries
- akpl_size = _vm->getResourceDataSize(akpl);
-
- rgbs = _vm->findResourceData(MKID('RGBS'), akos);
-
- if (!rgbs) {
- debugC(DEBUG_ACTORS, "Can't remap actor %d costume %d doesn't contain an RGB block", _number, _costume);
- return;
- }
-
- for (i = 0; i < akpl_size; i++) {
- r = *rgbs++;
- g = *rgbs++;
- b = *rgbs++;
-
- akpl_color = *akpl++;
-
- // allow remap of generic palette entry?
- if (!_shadowMode || akpl_color >= 16) {
- r = (r * r_fact) >> 8;
- g = (g * g_fact) >> 8;
- b = (b * b_fact) >> 8;
- _palette[i] = _vm->remapPaletteColor(r, g, b, threshold);
- }
- }
-}
-
-void Actor::classChanged(int cls, bool value) {
- if (cls == kObjectClassAlwaysClip)
- _forceClip = value;
- if (cls == kObjectClassIgnoreBoxes)
- _ignoreBoxes = value;
-}
-
-bool Actor::isInClass(int cls) {
- return _vm->getClass(_number, cls);
-}
-
-bool Actor::isPlayer() {
- if (_vm->_version <= 2)
- return _vm->VAR(42) <= _number && _number <= _vm->VAR(43);
- else
- return isInClass(kObjectClassPlayer);
-}
-
-void Actor::setUserCondition(int slot, int set) {
- const int condMaskCode = (_vm->_heversion >= 90) ? 0x1FFF : 0x3FF;
- checkRange(32, 1, slot, "Condition %d out of range");
- if (set == 0) {
- _heCondMask &= ~(1 << (slot + 0xF));
- } else {
- _heCondMask |= 1 << (slot + 0xF);
- }
- if (_heCondMask & condMaskCode) {
- _heCondMask &= ~1;
- } else {
- _heCondMask |= 1;
- }
-}
-
-bool Actor::isUserConditionSet(int slot) const {
- checkRange(32, 1, slot, "Condition %d out of range");
- return (_heCondMask & (1 << (slot + 0xF))) != 0;
-}
-
-void Actor::setTalkCondition(int slot) {
- const int condMaskCode = (_vm->_heversion >= 90) ? 0x1FFF : 0x3FF;
- checkRange(32, 1, slot, "Condition %d out of range");
- _heCondMask = (_heCondMask & ~condMaskCode) | 1;
- if (slot != 1) {
- _heCondMask |= 1 << (slot - 1);
- if (_heCondMask & condMaskCode) {
- _heCondMask &= ~1;
- } else {
- _heCondMask |= 1;
- }
- }
-}
-
-bool Actor::isTalkConditionSet(int slot) const {
- checkRange(32, 1, slot, "Condition %d out of range");
- return (_heCondMask & (1 << (slot - 1))) != 0;
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v71he::preProcessAuxQueue() {
- if (!_skipProcessActors) {
- for (int i = 0; i < _auxBlocksNum; ++i) {
- AuxBlock *ab = &_auxBlocks[i];
- if (ab->r.top <= ab->r.bottom) {
- gdi.copyVirtScreenBuffers(ab->r);
- }
- }
- }
- _auxBlocksNum = 0;
-}
-
-void ScummEngine_v71he::postProcessAuxQueue() {
- if (!_skipProcessActors) {
- for (int i = 0; i < _auxEntriesNum; ++i) {
- AuxEntry *ae = &_auxEntries[i];
- if (ae->actorNum != -1) {
- Actor *a = derefActor(ae->actorNum, "postProcessAuxQueue");
- const uint8 *cost = getResourceAddress(rtCostume, a->_costume);
- int dy = a->_offsY + a->_pos.y - a->getElevation();
- int dx = a->_offsX + a->_pos.x;
-
- const uint8 *akax = findResource(MKID('AKAX'), cost);
- assert(akax);
- const uint8 *auxd = findPalInPals(akax, ae->subIndex) - _resourceHeaderSize;
- assert(auxd);
- const uint8 *frel = findResourceData(MKID('FREL'), auxd);
- if (frel) {
- error("unhandled FREL block");
- }
- const uint8 *disp = findResourceData(MKID('DISP'), auxd);
- if (disp) {
- error("unhandled DISP block");
- }
- const uint8 *axfd = findResourceData(MKID('AXFD'), auxd);
- assert(axfd);
-
- uint16 comp = READ_LE_UINT16(axfd);
- if (comp != 0) {
- int x = (int16)READ_LE_UINT16(axfd + 2) + dx;
- int y = (int16)READ_LE_UINT16(axfd + 4) + dy;
- int w = (int16)READ_LE_UINT16(axfd + 6);
- int h = (int16)READ_LE_UINT16(axfd + 8);
- VirtScreen *pvs = &virtscr[kMainVirtScreen];
- uint8 *dst1 = pvs->getPixels(0, pvs->topline);
- uint8 *dst2 = pvs->getBackPixels(0, pvs->topline);
- switch (comp) {
- case 1:
- Wiz::copyAuxImage(dst1, dst2, axfd + 10, pvs->w, pvs->h, x, y, w, h);
- break;
- default:
- error("unimplemented compression type %d", comp);
- }
- }
- const uint8 *axur = findResourceData(MKID('AXUR'), auxd);
- if (axur) {
- uint16 n = READ_LE_UINT16(axur); axur += 2;
- while (n--) {
- int x1 = (int16)READ_LE_UINT16(axur + 0) + dx;
- int y1 = (int16)READ_LE_UINT16(axur + 2) + dy;
- int x2 = (int16)READ_LE_UINT16(axur + 4) + dx;
- int y2 = (int16)READ_LE_UINT16(axur + 6) + dy;
- markRectAsDirty(kMainVirtScreen, x1, x2, y1, y2 + 1);
- axur += 8;
- }
- }
- const uint8 *axer = findResourceData(MKID('AXER'), auxd);
- if (axer) {
- a->_auxBlock.visible = true;
- a->_auxBlock.r.left = (int16)READ_LE_UINT16(axer + 0) + dx;
- a->_auxBlock.r.top = (int16)READ_LE_UINT16(axer + 2) + dy;
- a->_auxBlock.r.right = (int16)READ_LE_UINT16(axer + 4) + dx;
- a->_auxBlock.r.bottom = (int16)READ_LE_UINT16(axer + 6) + dy;
- }
- }
- }
- }
- _auxEntriesNum = 0;
-}
-
-void ScummEngine_v71he::queueAuxBlock(Actor *a) {
- if (!a->_auxBlock.visible)
- return;
-
- assert(_auxBlocksNum < ARRAYSIZE(_auxBlocks));
- _auxBlocks[_auxBlocksNum] = a->_auxBlock;
- ++_auxBlocksNum;
-}
-
-void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) {
- assert(_auxEntriesNum < ARRAYSIZE(_auxEntries));
- AuxEntry *ae = &_auxEntries[_auxEntriesNum];
- ae->actorNum = actorNum;
- ae->subIndex = subIndex;
- ++_auxEntriesNum;
-}
-#endif
-
-
-void Actor::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry actorEntries[] = {
- MKLINE(Actor, _pos.x, sleInt16, VER(8)),
- MKLINE(Actor, _pos.y, sleInt16, VER(8)),
- MKLINE(Actor, _offsX, sleInt16, VER(32)),
- MKLINE(Actor, _offsY, sleInt16, VER(32)),
- MKLINE(Actor, _top, sleInt16, VER(8)),
- MKLINE(Actor, _bottom, sleInt16, VER(8)),
- MKLINE(Actor, _elevation, sleInt16, VER(8)),
- MKLINE(Actor, _width, sleUint16, VER(8)),
- MKLINE(Actor, _facing, sleUint16, VER(8)),
- MKLINE(Actor, _costume, sleUint16, VER(8)),
- MKLINE(Actor, _room, sleByte, VER(8)),
- MKLINE(Actor, _talkColor, sleByte, VER(8)),
- MKLINE(Actor, _talkFrequency, sleInt16, VER(16)),
- MKLINE(Actor, _talkPan, sleInt16, VER(24)),
- MKLINE(Actor, _talkVolume, sleInt16, VER(29)),
- MKLINE(Actor, _boxscale, sleUint16, VER(34)),
- MKLINE(Actor, _scalex, sleByte, VER(8)),
- MKLINE(Actor, _scaley, sleByte, VER(8)),
- MKLINE(Actor, _charset, sleByte, VER(8)),
-
- // Actor sound grew from 8 to 32 bytes and switched to uint16 in HE games
- MKARRAY_OLD(Actor, _sound[0], sleByte, 8, VER(8), VER(36)),
- MKARRAY_OLD(Actor, _sound[0], sleByte, 32, VER(37), VER(61)),
- MKARRAY(Actor, _sound[0], sleUint16, 32, VER(62)),
-
- // Actor animVariable grew from 8 to 27
- MKARRAY_OLD(Actor, _animVariable[0], sleUint16, 8, VER(8), VER(40)),
- MKARRAY(Actor, _animVariable[0], sleUint16, 27, VER(41)),
-
- MKLINE(Actor, _targetFacing, sleUint16, VER(8)),
- MKLINE(Actor, _moving, sleByte, VER(8)),
- MKLINE(Actor, _ignoreBoxes, sleByte, VER(8)),
- MKLINE(Actor, _forceClip, sleByte, VER(8)),
- MKLINE(Actor, _initFrame, sleByte, VER(8)),
- MKLINE(Actor, _walkFrame, sleByte, VER(8)),
- MKLINE(Actor, _standFrame, sleByte, VER(8)),
- MKLINE(Actor, _talkStartFrame, sleByte, VER(8)),
- MKLINE(Actor, _talkStopFrame, sleByte, VER(8)),
- MKLINE(Actor, _speedx, sleUint16, VER(8)),
- MKLINE(Actor, _speedy, sleUint16, VER(8)),
- MKLINE(Actor, _cost.animCounter, sleUint16, VER(8)),
- MKLINE(Actor, _cost.soundCounter, sleByte, VER(8)),
- MKLINE(Actor, _drawToBackBuf, sleByte, VER(32)),
- MKLINE(Actor, _flip, sleByte, VER(32)),
- MKLINE(Actor, _heSkipLimbs, sleByte, VER(32)),
-
- // Actor palette grew from 64 to 256 bytes
- MKARRAY_OLD(Actor, _palette[0], sleByte, 64, VER(8), VER(9)),
- MKARRAY(Actor, _palette[0], sleByte, 256, VER(10)),
-
- MK_OBSOLETE(Actor, _mask, sleByte, VER(8), VER(9)),
- MKLINE(Actor, _shadowMode, sleByte, VER(8)),
- MKLINE(Actor, _visible, sleByte, VER(8)),
- MKLINE(Actor, _frame, sleByte, VER(8)),
- MKLINE(Actor, _animSpeed, sleByte, VER(8)),
- MKLINE(Actor, _animProgress, sleByte, VER(8)),
- MKLINE(Actor, _walkbox, sleByte, VER(8)),
- MKLINE(Actor, _needRedraw, sleByte, VER(8)),
- MKLINE(Actor, _needBgReset, sleByte, VER(8)),
- MKLINE(Actor, _costumeNeedsInit, sleByte, VER(8)),
- MKLINE(Actor, _heCondMask, sleUint32, VER(38)),
- MKLINE(Actor, _hePaletteNum, sleUint32, VER(59)),
- MKLINE(Actor, _heXmapNum, sleUint32, VER(59)),
-
- MKLINE(Actor, _talkPosY, sleInt16, VER(8)),
- MKLINE(Actor, _talkPosX, sleInt16, VER(8)),
- MKLINE(Actor, _ignoreTurns, sleByte, VER(8)),
-
- // Actor layer switched to int32 in HE games
- MKLINE_OLD(Actor, _layer, sleByte, VER(8), VER(57)),
- MKLINE(Actor, _layer, sleInt32, VER(58)),
-
- MKLINE(Actor, _talkScript, sleUint16, VER(8)),
- MKLINE(Actor, _walkScript, sleUint16, VER(8)),
-
- MKLINE(Actor, _walkdata.dest.x, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.dest.y, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.destbox, sleByte, VER(8)),
- MKLINE(Actor, _walkdata.destdir, sleUint16, VER(8)),
- MKLINE(Actor, _walkdata.curbox, sleByte, VER(8)),
- MKLINE(Actor, _walkdata.cur.x, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.cur.y, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.next.x, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.next.y, sleInt16, VER(8)),
- MKLINE(Actor, _walkdata.deltaXFactor, sleInt32, VER(8)),
- MKLINE(Actor, _walkdata.deltaYFactor, sleInt32, VER(8)),
- MKLINE(Actor, _walkdata.xfrac, sleUint16, VER(8)),
- MKLINE(Actor, _walkdata.yfrac, sleUint16, VER(8)),
-
- MKLINE(Actor, _walkdata.point3.x, sleUint16, VER(42)),
- MKLINE(Actor, _walkdata.point3.y, sleUint16, VER(42)),
-
- MKARRAY(Actor, _cost.active[0], sleByte, 16, VER(8)),
- MKLINE(Actor, _cost.stopped, sleUint16, VER(8)),
- MKARRAY(Actor, _cost.curpos[0], sleUint16, 16, VER(8)),
- MKARRAY(Actor, _cost.start[0], sleUint16, 16, VER(8)),
- MKARRAY(Actor, _cost.end[0], sleUint16, 16, VER(8)),
- MKARRAY(Actor, _cost.frame[0], sleUint16, 16, VER(8)),
- MKEND()
- };
-
- if (ser->isLoading()) {
- // Not all actor data is saved; so when loading, we first reset
- // the actor, to ensure completely reproducible behaviour (else,
- // some not saved value in the actor class can cause odd things)
- initActor(-1);
- }
-
- ser->saveLoadEntries(this, actorEntries);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/actor.h b/scumm/actor.h
deleted file mode 100644
index 2a6e49ed15..0000000000
--- a/scumm/actor.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-
-#ifndef ACTOR_H
-#define ACTOR_H
-
-#include "common/scummsys.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-
-
-namespace Scumm {
-
-enum MoveFlags {
- MF_NEW_LEG = 1,
- MF_IN_LEG = 2,
- MF_TURN = 4,
- MF_LAST_LEG = 8,
- MF_FROZEN = 0x80
-};
-
-struct ActorWalkData {
- Common::Point dest; // Final destination point
- byte destbox; // Final destination box
- int16 destdir; // Final destination, direction to face at
-
- Common::Point cur; // Last position
- byte curbox; // Last box
-
- Common::Point next; // Next position on our way to the destination, i.e. our intermediate destination
-
- Common::Point point3;
- int32 deltaXFactor, deltaYFactor;
- uint16 xfrac, yfrac;
-};
-
-struct CostumeData {
- byte active[16];
- uint16 animCounter;
- byte soundCounter;
- uint16 stopped;
- uint16 curpos[16];
- uint16 start[16];
- uint16 end[16];
- uint16 frame[16];
-
- uint16 heJumpOffsetTable[16];
- uint16 heJumpCountTable[16];
- uint32 heCondMaskTable[16];
-
- void reset() {
- stopped = 0;
- for (int i = 0; i < 16; i++) {
- active[i] = 0;
- curpos[i] = start[i] = end[i] = frame[i] = 0xFFFF;
- }
- }
-};
-
-struct AdjustBoxResult { /* Result type of AdjustBox functions */
- int16 x, y;
- byte box;
-};
-
-class Actor : public Serializable {
-
-public:
- static byte kInvalidBox;
-
- static void initActorClass(ScummEngine *scumm);
-
-public:
- /** The position of the actor inside the virtual screen. */
- Common::Point _pos;
-
- /** HE specific: This rect is used to clip actor drawing. */
- Common::Rect _clipOverride;
-
- int _offsX, _offsY;
- int _top, _bottom;
- uint _width;
- byte _number;
- uint16 _costume;
- byte _room;
- byte _talkColor;
- int _talkFrequency;
- byte _talkPan;
- byte _talkVolume;
- uint16 _boxscale;
- byte _scalex, _scaley;
- byte _charset;
- byte _moving;
- bool _ignoreBoxes;
- byte _forceClip;
-
- byte _initFrame;
- byte _walkFrame;
- byte _standFrame;
- byte _talkStartFrame;
- byte _talkStopFrame;
-
- bool _needRedraw, _needBgReset, _visible;
- byte _shadowMode;
- bool _flip;
- byte _frame;
- byte _walkbox;
- int16 _talkPosX, _talkPosY;
- uint16 _talkScript, _walkScript;
- bool _ignoreTurns;
- bool _drawToBackBuf;
- int32 _layer;
- uint16 _sound[32];
- CostumeData _cost;
-
- /* HE specific */
- bool _heNoTalkAnimation;
- bool _heSkipLimbs;
- bool _heTalking;
- uint32 _heCondMask;
- uint32 _hePaletteNum;
- uint32 _heXmapNum;
-
- AuxBlock _auxBlock;
-
- struct {
- int16 posX;
- int16 posY;
- int16 color;
- byte sentence[128];
- } _heTalkQueue[16];
-
-protected:
- byte _palette[256];
- int _elevation;
- uint16 _facing;
- uint16 _targetFacing;
- uint _speedx, _speedy;
- byte _animProgress, _animSpeed;
- bool _costumeNeedsInit;
- ActorWalkData _walkdata;
- int16 _animVariable[27];
-
- static ScummEngine *_vm;
-
-public:
-
- Actor();
-
-//protected:
- void hideActor();
- void showActor();
-
- void initActor(int mode);
- void putActor(int x, int y, byte room);
- void setActorWalkSpeed(uint newSpeedX, uint newSpeedY);
-protected:
- int calcMovementFactor(const Common::Point& next);
- int actorWalkStep();
- int remapDirection(int dir, bool is_walking);
- void setupActorScale();
-
- void setBox(int box);
- int updateActorDirection(bool is_walking);
-
-public:
- void adjustActorPos();
- AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
-
- void setDirection(int direction);
- void faceToObject(int obj);
- void turnToDirection(int newdir);
- void walkActor();
- void walkActorOld();
- void drawActorToBackBuf(int x, int y);
- void drawActorCostume(bool hitTestMode = false);
- void animateCostume();
- void setActorCostume(int c);
-
- void animateLimb(int limb, int f);
-
- bool actorHitTest(int x, int y);
-
- byte *getActorName();
- void startWalkActor(int x, int y, int dir);
- void stopActorMoving();
-protected:
- void startWalkAnim(int cmd, int angle);
-public:
- void runActorTalkScript(int f);
- void startAnimActor(int frame);
-
- void remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold);
- void remapActorPaletteColor(int slot, int color);
-
- void animateActor(int anim);
-
- bool isInCurrentRoom() const {
- return _room == _vm->_currentRoom;
- }
-
- int getActorXYPos(int &x, int &y) const;
-
- int getRoom() const {
- return _room;
- }
-
- int getFacing() const {
- return _facing;
- }
-
- int getAnimVar(byte var) const;
- void setAnimVar(byte var, int value);
-
- void setAnimSpeed(byte newAnimSpeed) {
- _animSpeed = newAnimSpeed;
- _animProgress = 0;
- }
-
- int getAnimSpeed() const {
- return _animSpeed;
- }
-
- int getAnimProgress() const {
- return _animProgress;
- }
-
- int getElevation() const {
- return _elevation;
- }
-
- void setElevation(int newElevation) {
- if (_elevation != newElevation) {
- _elevation = newElevation;
- _needRedraw = true;
- }
- }
-
- void setPalette(int idx, int val) {
- _palette[idx] = val;
- _needRedraw = true;
- }
-
- void setScale(int sx, int sy) {
- if (sx != -1)
- _scalex = sx;
- if (sy != -1)
- _scaley = sy;
- _needRedraw = true;
- }
-
- void classChanged(int cls, bool value);
-
- void setUserCondition(int slot, int set);
- bool isUserConditionSet(int slot) const;
-
- void setTalkCondition(int slot);
- bool isTalkConditionSet(int slot) const;
-
- // Used by the save/load system:
- void saveLoadWithSerializer(Serializer *ser);
-
-protected:
- bool isInClass(int cls);
-
- bool isPlayer();
-
- bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath);
- void findPathTowardsOld(byte box, byte box2, byte box3, Common::Point &p2, Common::Point &p3);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/akos.cpp b/scumm/akos.cpp
deleted file mode 100644
index d8f484f1d3..0000000000
--- a/scumm/akos.cpp
+++ /dev/null
@@ -1,1869 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/akos.h"
-#include "scumm/bomp.h"
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/intern.h"
-#include "scumm/intern_he.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/wiz_he.h"
-
-namespace Scumm {
-
-#if !defined(__GNUC__)
-#pragma START_PACK_STRUCTS
-#endif
-
-struct AkosHeader {
- byte unk_1[2];
- byte flags;
- byte unk_2;
- uint16 num_anims;
- uint16 unk_3;
- uint16 codec;
-} GCC_PACK;
-
-struct AkosOffset {
- uint32 akcd;
- uint16 akci;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
-#pragma END_PACK_STRUCTS
-#endif
-
-
-enum AkosOpcodes {
- AKC_Return = 0xC001,
- AKC_SetVar = 0xC010,
- AKC_CmdQue3 = 0xC015,
- AKC_C016 = 0xC016,
- AKC_C017 = 0xC017,
- AKC_C018 = 0xC018,
- AKC_C019 = 0xC019,
- AKC_ComplexChan = 0xC020,
- AKC_C021 = 0xC021,
- AKC_C022 = 0xC022,
- AKC_ComplexChan2 = 0xC025,
- AKC_Jump = 0xC030,
- AKC_JumpIfSet = 0xC031,
- AKC_AddVar = 0xC040,
- AKC_C042 = 0xC042,
- AKC_C044 = 0xC044,
- AKC_C045 = 0xC045,
- AKC_C046 = 0xC046,
- AKC_C047 = 0xC047,
- AKC_C048 = 0xC048,
- AKC_Ignore = 0xC050,
- AKC_IncVar = 0xC060,
- AKC_CmdQue3Quick = 0xC061,
- AKC_JumpStart = 0xC070,
- AKC_JumpE = 0xC070,
- AKC_JumpNE = 0xC071,
- AKC_JumpL = 0xC072,
- AKC_JumpLE = 0xC073,
- AKC_JumpG = 0xC074,
- AKC_JumpGE = 0xC075,
- AKC_StartAnim = 0xC080,
- AKC_StartVarAnim = 0xC081,
- AKC_Random = 0xC082,
- AKC_SetActorClip = 0xC083,
- AKC_StartAnimInActor = 0xC084,
- AKC_SetVarInActor = 0xC085,
- AKC_HideActor = 0xC086,
- AKC_SetDrawOffs = 0xC087,
- AKC_JumpTable = 0xC088,
- AKC_SoundStuff = 0xC089,
- AKC_Flip = 0xC08A,
- AKC_Cmd3 = 0xC08B,
- AKC_Ignore3 = 0xC08C,
- AKC_Ignore2 = 0xC08D,
- AKC_C08E = 0xC08E,
- AKC_SkipStart = 0xC090,
- AKC_SkipE = 0xC090,
- AKC_SkipNE = 0xC091,
- AKC_SkipL = 0xC092,
- AKC_SkipLE = 0xC093,
- AKC_SkipG = 0xC094,
- AKC_SkipGE = 0xC095,
- AKC_ClearFlag = 0xC09F,
- AKC_C0A0 = 0xC0A0,
- AKC_C0A1 = 0xC0A1,
- AKC_C0A2 = 0xC0A2,
- AKC_C0A3 = 0xC0A3,
- AKC_C0A4 = 0xC0A4,
- AKC_C0A5 = 0xC0A5,
- AKC_C0A6 = 0xC0A6,
- AKC_C0A7 = 0xC0A7,
- AKC_EndSeq = 0xC0FF
-};
-
-static bool akos_compare(int a, int b, byte cmd) {
- switch (cmd) {
- case 0:
- return a == b;
- case 1:
- return a != b;
- case 2:
- return a < b;
- case 3:
- return a <= b;
- case 4:
- return a > b;
- default:
- return a >= b;
- }
-}
-
-void AkosCostumeLoader::loadCostume(int id) {
- _akos = _vm->getResourceAddress(rtCostume, id);
- assert(_akos);
-}
-
-bool AkosCostumeLoader::hasManyDirections() {
- const AkosHeader *akhd;
-
- akhd = (const AkosHeader *)_vm->findResourceData(MKID('AKHD'), _akos);
- return (akhd->flags & 2) != 0;
-}
-
-void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
- uint anim;
- const byte *r;
- const AkosHeader *akhd;
- uint offs;
- int i;
- byte code;
- uint16 start, len;
- uint16 mask;
-
- if (a->_costume == 0)
- return;
-
- loadCostume(a->_costume);
-
- if (_vm->_version >= 7 && hasManyDirections())
- anim = toSimpleDir(1, a->getFacing()) + frame * 8;
- else
- anim = newDirToOldDir(a->getFacing()) + frame * 4;
-
- akhd = (const AkosHeader *)_vm->findResourceData(MKID('AKHD'), _akos);
-
- if (anim >= READ_LE_UINT16(&akhd->num_anims))
- return;
-
- r = _vm->findResourceData(MKID('AKCH'), _akos);
- assert(r);
-
- offs = READ_LE_UINT16(r + anim * sizeof(uint16));
- if (offs == 0)
- return;
- r += offs;
-
- const uint8 *akstPtr = _vm->findResourceData(MKID('AKST'), _akos);
- const uint8 *aksfPtr = _vm->findResourceData(MKID('AKSF'), _akos);
-
- i = 0;
- mask = READ_LE_UINT16(r); r += 2;
- do {
- if (mask & 0x8000) {
- const uint8 *akst = akstPtr;
- const uint8 *aksf = aksfPtr;
-
- code = *r++;
- if (usemask & 0x8000) {
- switch (code) {
- case 1:
- a->_cost.active[i] = 0;
- a->_cost.frame[i] = frame;
- a->_cost.end[i] = 0;
- a->_cost.start[i] = 0;
- a->_cost.curpos[i] = 0;
- a->_cost.heCondMaskTable[i] = 0;
-
- if (akst) {
- int size = _vm->getResourceDataSize(akst) / 8;
- if (size > 0) {
- bool found = false;
- while (size--) {
- if (READ_LE_UINT32(akst) == 0) {
- a->_cost.heCondMaskTable[i] = READ_LE_UINT32(akst + 4);
- found = true;
- break;
- }
- akst += 8;
- }
- if (!found) {
- error("Sequence not found in actor 0x%X costume %d", a, a->_costume);
- }
- }
- }
- break;
- case 4:
- a->_cost.stopped |= 1 << i;
- break;
- case 5:
- a->_cost.stopped &= ~(1 << i);
- break;
- default:
- start = READ_LE_UINT16(r); r += 2;
- len = READ_LE_UINT16(r); r += 2;
-
- a->_cost.heJumpOffsetTable[i] = 0;
- a->_cost.heJumpCountTable[i] = 0;
- if (aksf) {
- int size = _vm->getResourceDataSize(aksf) / 6;
- if (size > 0) {
- bool found = false;
- while (size--) {
- if (READ_LE_UINT16(aksf) == start) {
- a->_cost.heJumpOffsetTable[i] = READ_LE_UINT16(aksf + 2);
- a->_cost.heJumpCountTable[i] = READ_LE_UINT16(aksf + 4);
- found = true;
- break;
- }
- aksf += 6;
- }
- if (!found) {
- error("Sequence not found in actor 0x%X costume %d", a, a->_costume);
- }
- }
- }
-
- a->_cost.active[i] = code;
- a->_cost.frame[i] = frame;
- a->_cost.end[i] = start + len;
- a->_cost.start[i] = start;
- a->_cost.curpos[i] = start;
- a->_cost.heCondMaskTable[i] = 0;
- if (akst) {
- int size = _vm->getResourceDataSize(akst) / 8;
- if (size > 0) {
- bool found = false;
- while (size--) {
- if (READ_LE_UINT32(akst) == start) {
- a->_cost.heCondMaskTable[i] = READ_LE_UINT32(akst + 4);
- found = true;
- break;
- }
- akst += 8;
- }
- if (!found) {
- error("Sequence not found in actor 0x%X costume %d", a, a->_costume);
- }
- }
- }
- break;
- }
- } else {
- if (code != 1 && code != 4 && code != 5)
- r += sizeof(uint16) * 2;
- }
- }
- i++;
- mask <<= 1;
- usemask <<= 1;
- } while ((uint16)mask);
-}
-
-void AkosRenderer::setPalette(byte *new_palette) {
- uint size, i;
-
- size = _vm->getResourceDataSize(akpl);
- if (size == 0)
- return;
-
- if (size > 256)
- error("akos_setPalette: %d is too many colors", size);
-
- if (_vm->_heversion >= 99 && _paletteNum) {
- for (i = 0; i < size; i++)
- palette[i] = (byte)_vm->_hePalettes[_paletteNum * 1024 + 768 + akpl[i]];
- } else {
- for (i = 0; i < size; i++) {
- palette[i] = new_palette[i] != 0xFF ? new_palette[i] : akpl[i];
- }
- }
-
- if (_vm->_heversion == 70) {
- for (i = 0; i < size; i++)
- palette[i] = _vm->_HEV7ActorPalette[palette[i]];
- }
-
- if (size == 256) {
- byte color = new_palette[0];
- if (color == 255) {
- palette[0] = color;
- } else {
- _vm->_bompActorPalettePtr = palette;
- }
- }
-}
-
-void AkosRenderer::setCostume(int costume, int shadow) {
- akos = _vm->getResourceAddress(rtCostume, costume);
- assert(akos);
-
- akhd = (const AkosHeader *) _vm->findResourceData(MKID('AKHD'), akos);
- akof = (const AkosOffset *) _vm->findResourceData(MKID('AKOF'), akos);
- akci = _vm->findResourceData(MKID('AKCI'), akos);
- aksq = _vm->findResourceData(MKID('AKSQ'), akos);
- akcd = _vm->findResourceData(MKID('AKCD'), akos);
- akpl = _vm->findResourceData(MKID('AKPL'), akos);
- codec = READ_LE_UINT16(&akhd->codec);
- akct = _vm->findResourceData(MKID('AKCT'), akos);
-
- xmap = 0;
- if (shadow) {
- const uint8 *xmapPtr = _vm->getResourceAddress(rtImage, shadow);
- assert(xmapPtr);
- xmap = _vm->findResourceData(MKID('XMAP'), xmapPtr);
- assert(xmap);
- }
-}
-
-void AkosRenderer::setFacing(const Actor *a) {
- _mirror = (newDirToOldDir(a->getFacing()) != 0 || akhd->flags & 1);
- if (a->_flip)
- _mirror = !_mirror;
-}
-
-byte AkosRenderer::drawLimb(const Actor *a, int limb) {
- uint code;
- const byte *p;
- const AkosOffset *off;
- const CostumeData &cost = a->_cost;
- const CostumeInfo *costumeInfo;
- uint i, extra;
- byte result = 0;
- int xmoveCur, ymoveCur;
- uint32 heCondMaskIndex[32];
- bool useCondMask;
- int lastDx, lastDy;
-
- lastDx = lastDy = 0;
- for (i = 0; i < 32; ++i) {
- heCondMaskIndex[i] = i;
- }
-
- if (_skipLimbs)
- return 0;
-
- if (_vm->_heversion >= 70 && cost.active[limb] == 8)
- return 0;
-
- if (!cost.active[limb] || cost.stopped & (1 << limb))
- return 0;
-
- useCondMask = false;
- p = aksq + cost.curpos[limb];
-
- code = p[0];
- if (code & 0x80)
- code = (code << 8) | p[1];
-
- if (code == AKC_C021 || code == AKC_C022) {
- uint16 s = cost.curpos[limb] + 4;
- uint j = 0;
- extra = p[3];
- uint8 n = extra;
- assert(n < ARRAYSIZE(heCondMaskIndex));
- while (n--) {
- heCondMaskIndex[j++] = aksq[s++];
- }
- useCondMask = true;
- p += extra + 2;
- code = (code == AKC_C021) ? AKC_ComplexChan : AKC_ComplexChan2;
- }
-
- if (code == AKC_Return || code == AKC_EndSeq)
- return 0;
-
- if (code != AKC_ComplexChan && code != AKC_ComplexChan2) {
- off = akof + (code & 0xFFF);
-
- assert((code & 0xFFF) * 6 < READ_BE_UINT32((const byte *)akof - 4) - 8);
- assert((code & 0x7000) == 0);
-
- _srcptr = akcd + READ_LE_UINT32(&off->akcd);
- costumeInfo = (const CostumeInfo *) (akci + READ_LE_UINT16(&off->akci));
-
- _width = READ_LE_UINT16(&costumeInfo->width);
- _height = READ_LE_UINT16(&costumeInfo->height);
- xmoveCur = _xmove + (int16)READ_LE_UINT16(&costumeInfo->rel_x);
- ymoveCur = _ymove + (int16)READ_LE_UINT16(&costumeInfo->rel_y);
- _xmove += (int16)READ_LE_UINT16(&costumeInfo->move_x);
- _ymove -= (int16)READ_LE_UINT16(&costumeInfo->move_y);
-
- switch (codec) {
- case 1:
- result |= codec1(xmoveCur, ymoveCur);
- break;
- case 5:
- result |= codec5(xmoveCur, ymoveCur);
- break;
- case 16:
- result |= codec16(xmoveCur, ymoveCur);
- break;
- default:
- error("akos_drawLimb: invalid codec %d", codec);
- }
- } else {
- if (code == AKC_ComplexChan2) {
- lastDx = (int16)READ_LE_UINT16(p + 2);
- lastDy = (int16)READ_LE_UINT16(p + 4);
- p += 4;
- }
-
- extra = p[2];
- p += 3;
- uint32 decflag = heCondMaskIndex[0];
-
- for (i = 0; i != extra; i++) {
- code = p[4];
- if (code & 0x80)
- code = ((code & 0xF) << 8) | (p[5] & 0xFFF);
- off = akof + code;
-
- _srcptr = akcd + READ_LE_UINT32(&off->akcd);
- costumeInfo = (const CostumeInfo *) (akci + READ_LE_UINT16(&off->akci));
-
- _width = READ_LE_UINT16(&costumeInfo->width);
- _height = READ_LE_UINT16(&costumeInfo->height);
-
- xmoveCur = _xmove + (int16)READ_LE_UINT16(p + 0);
- ymoveCur = _ymove + (int16)READ_LE_UINT16(p + 2);
-
- if (i == extra - 1) {
- _xmove += lastDx;
- _ymove -= lastDy;
- }
-
- uint16 shadowMask = 0;
-
- if (!useCondMask || !akct) {
- decflag = 1;
- } else {
- uint32 cond = READ_LE_UINT32(akct + cost.heCondMaskTable[limb] + heCondMaskIndex[i] * 4);
- if (cond == 0) {
- decflag = 1;
- } else {
- uint32 type = cond & ~0x3FFFFFFF;
- cond &= 0x3FFFFFFF;
- if (_vm->_heversion >= 90) {
- shadowMask = cond & 0xE000;
- cond &= ~0xE000;
- }
- if (_vm->_heversion >= 90 && cond == 0) {
- decflag = 1;
- } else if (type == 0x40000000) { // restored_bit
- decflag = (a->_heCondMask & cond) ? 1 : 0;
- } else if (type == 0x80000000) { // dirty_bit
- decflag = (a->_heCondMask & cond) ? 0 : 1;
- } else {
- decflag = (a->_heCondMask & cond) ? 1 : 0;
- }
- }
- }
-
- p += (p[4] & 0x80) ? 6 : 5;
-
- if (decflag == 0)
- continue;
-
- if (_vm->_heversion >= 90) {
- _shadow_mode = ((shadowMask & 0x8000) && xmap) ? 3 : 0;
- }
-
- switch (codec) {
- case 1:
- result |= codec1(xmoveCur, ymoveCur);
- break;
- case 5:
- result |= codec5(xmoveCur, ymoveCur);
- break;
- case 16:
- result |= codec16(xmoveCur, ymoveCur);
- break;
- case 32:
- result |= codec32(xmoveCur, ymoveCur);
- break;
- default:
- error("akos_drawLimb: invalid codec %d", codec);
- }
- }
- }
-
- return result;
-}
-
-void AkosRenderer::codec1_genericDecode(Codec1 &v1) {
- const byte *mask, *src;
- byte *dst;
- byte len, maskbit;
- int y;
- uint color, height, pcolor;
- const byte *scaleytab;
- bool masked;
- bool skip_column = false;
-
- y = v1.y;
- src = _srcptr;
- dst = v1.destptr;
- len = v1.replen;
- color = v1.repcolor;
- height = _height;
-
- scaleytab = &v1.scaletable[v1.scaleYindex];
- maskbit = revBitMask(v1.x & 7);
- mask = _vm->getMaskBuffer(v1.x - (_vm->virtscr[0].xstart & 7), v1.y, _zbuf);
-
- if (len)
- goto StartPos;
-
- do {
- len = *src++;
- color = len >> v1.shr;
- len &= v1.mask;
- if (!len)
- len = *src++;
-
- do {
- if (*scaleytab++ < _scaleY) {
- if (_actorHitMode) {
- if (color && y == _actorHitY && v1.x == _actorHitX) {
- _actorHitResult = true;
- return;
- }
- } else {
- masked = (y < 0 || y >= _out.h) || (*mask & maskbit);
-
- if (color && !masked && !skip_column) {
- pcolor = palette[color];
- if (_shadow_mode == 1) {
- if (pcolor == 13)
- pcolor = _shadow_table[*dst];
- } else if (_shadow_mode == 2) {
- error("codec1_spec2"); // TODO
- } else if (_shadow_mode == 3) {
- if (_vm->_heversion >= 90) {
- pcolor = (pcolor << 8) + *dst;
- pcolor = xmap[pcolor];
- } else if (pcolor < 8) {
- pcolor = (pcolor << 8) + *dst;
- pcolor = _shadow_table[pcolor];
- }
- }
- *dst = pcolor;
- }
- }
- dst += _out.pitch;
- mask += _numStrips;
- y++;
- }
- if (!--height) {
- if (!--v1.skip_width)
- return;
- height = _height;
- y = v1.y;
-
- scaleytab = &v1.scaletable[v1.scaleYindex];
-
- if (_scaleX == 255 || v1.scaletable[v1.scaleXindex] < _scaleX) {
- v1.x += v1.scaleXstep;
- if (v1.x < 0 || v1.x >= _out.w)
- return;
- maskbit = revBitMask(v1.x & 7);
- v1.destptr += v1.scaleXstep;
- skip_column = false;
- } else
- skip_column = true;
- v1.scaleXindex += v1.scaleXstep;
- dst = v1.destptr;
- mask = _vm->getMaskBuffer(v1.x - (_vm->virtscr[0].xstart & 7), v1.y, _zbuf);
- }
- StartPos:;
- } while (--len);
- } while (1);
-}
-
-#ifdef PALMOS_68K
-const byte *bigCostumeScaleTable;
-const byte *smallCostumeScaleTableAKOS;
-#else
-// This is exact duplicate of smallCostumeScaleTable[] in costume.cpp
-// See FIXME below for explanation
-const byte smallCostumeScaleTableAKOS[256] = {
- 0xFF, 0xFD, 0x7D, 0xBD, 0x3D, 0xDD, 0x5D, 0x9D,
- 0x1D, 0xED, 0x6D, 0xAD, 0x2D, 0xCD, 0x4D, 0x8D,
- 0x0D, 0xF5, 0x75, 0xB5, 0x35, 0xD5, 0x55, 0x95,
- 0x15, 0xE5, 0x65, 0xA5, 0x25, 0xC5, 0x45, 0x85,
- 0x05, 0xF9, 0x79, 0xB9, 0x39, 0xD9, 0x59, 0x99,
- 0x19, 0xE9, 0x69, 0xA9, 0x29, 0xC9, 0x49, 0x89,
- 0x09, 0xF1, 0x71, 0xB1, 0x31, 0xD1, 0x51, 0x91,
- 0x11, 0xE1, 0x61, 0xA1, 0x21, 0xC1, 0x41, 0x81,
- 0x01, 0xFB, 0x7B, 0xBB, 0x3B, 0xDB, 0x5B, 0x9B,
- 0x1B, 0xEB, 0x6B, 0xAB, 0x2B, 0xCB, 0x4B, 0x8B,
- 0x0B, 0xF3, 0x73, 0xB3, 0x33, 0xD3, 0x53, 0x93,
- 0x13, 0xE3, 0x63, 0xA3, 0x23, 0xC3, 0x43, 0x83,
- 0x03, 0xF7, 0x77, 0xB7, 0x37, 0xD7, 0x57, 0x97,
- 0x17, 0xE7, 0x67, 0xA7, 0x27, 0xC7, 0x47, 0x87,
- 0x07, 0xEF, 0x6F, 0xAF, 0x2F, 0xCF, 0x4F, 0x8F,
- 0x0F, 0xDF, 0x5F, 0x9F, 0x1F, 0xBF, 0x3F, 0x7F,
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE
-};
-const byte bigCostumeScaleTable[768] = {
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFE,
-
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFE,
-
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF,
-};
-#endif
-
-byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {
- int num_colors;
- bool use_scaling;
- int i, j;
- int skip = 0, startScaleIndexX, startScaleIndexY;
- Common::Rect rect;
- int step;
- byte drawFlag = 1;
- Codec1 v1;
-
- const int scaletableSize = (_vm->_heversion >= 61) ? 128 : 384;
-
- /* implement custom scale table */
-
- // FIXME. HACK
- // For some illogical reason gcc 3.4.x produces wrong code if
- // smallCostumeScaleTable from costume.cpp is used here
- // So I had to put copy of it back here as it was before 1.227 revision
- // of this file.
- v1.scaletable = (_vm->_heversion >= 61) ? smallCostumeScaleTableAKOS : bigCostumeScaleTable;
- if (_vm->VAR_CUSTOMSCALETABLE != 0xFF && _vm->res.isResourceLoaded(rtString, _vm->VAR(_vm->VAR_CUSTOMSCALETABLE))) {
- v1.scaletable = _vm->getStringAddressVar(_vm->VAR_CUSTOMSCALETABLE);
- }
-
- // Setup color decoding variables
- num_colors = _vm->getResourceDataSize(akpl);
- if (num_colors == 32) {
- v1.mask = 7;
- v1.shr = 3;
- } else if (num_colors == 64) {
- v1.mask = 3;
- v1.shr = 2;
- } else {
- v1.mask = 15;
- v1.shr = 4;
- }
-
- use_scaling = (_scaleX != 0xFF) || (_scaleY != 0xFF);
-
- v1.x = _actorX;
- v1.y = _actorY;
-
- if (use_scaling) {
-
- /* Scale direction */
- v1.scaleXstep = -1;
- if (xmoveCur < 0) {
- xmoveCur = -xmoveCur;
- v1.scaleXstep = 1;
- }
-
- if (_mirror) {
- /* Adjust X position */
- startScaleIndexX = j = scaletableSize - xmoveCur;
- for (i = 0; i < xmoveCur; i++) {
- if (v1.scaletable[j++] < _scaleX)
- v1.x -= v1.scaleXstep;
- }
-
- rect.left = rect.right = v1.x;
-
- j = startScaleIndexX;
- for (i = 0, skip = 0; i < _width; i++) {
- if (rect.right < 0) {
- skip++;
- startScaleIndexX = j;
- }
- if (v1.scaletable[j++] < _scaleX)
- rect.right++;
- }
- } else {
- /* No mirror */
- /* Adjust X position */
- startScaleIndexX = j = scaletableSize + xmoveCur;
- for (i = 0; i < xmoveCur; i++) {
- if (v1.scaletable[j--] < _scaleX)
- v1.x += v1.scaleXstep;
- }
-
- rect.left = rect.right = v1.x;
-
- j = startScaleIndexX;
- for (i = 0; i < _width; i++) {
- if (rect.left >= _out.w) {
- startScaleIndexX = j;
- skip++;
- }
- if (v1.scaletable[j--] < _scaleX)
- rect.left--;
- }
- }
-
- if (skip)
- skip--;
-
- step = -1;
- if (ymoveCur < 0) {
- ymoveCur = -ymoveCur;
- step = -step;
- }
-
- startScaleIndexY = scaletableSize - ymoveCur;
- for (i = 0; i < ymoveCur; i++) {
- if (v1.scaletable[startScaleIndexY++] < _scaleY)
- v1.y -= step;
- }
-
- rect.top = rect.bottom = v1.y;
- startScaleIndexY = scaletableSize - ymoveCur;
- for (i = 0; i < _height; i++) {
- if (v1.scaletable[startScaleIndexY++] < _scaleY)
- rect.bottom++;
- }
-
- startScaleIndexY = scaletableSize - ymoveCur;
- } else {
- if (!_mirror)
- xmoveCur = -xmoveCur;
-
- v1.x += xmoveCur;
- v1.y += ymoveCur;
-
- if (_mirror) {
- rect.left = v1.x;
- rect.right = v1.x + _width;
- } else {
- rect.left = v1.x - _width;
- rect.right = v1.x;
- }
-
- rect.top = v1.y;
- rect.bottom = rect.top + _height;
-
- startScaleIndexX = scaletableSize;
- startScaleIndexY = scaletableSize;
- }
-
- v1.scaleXindex = startScaleIndexX;
- v1.scaleYindex = startScaleIndexY;
- v1.skip_width = _width;
- v1.scaleXstep = _mirror ? 1 : -1;
-
- if (_vm->_heversion >= 71) {
- if (_clipOverride.right > _clipOverride.left && _clipOverride.bottom > _clipOverride.top) {
- if (rect.left < _clipOverride.left)
- rect.left = _clipOverride.left;
-
- if (rect.right > _clipOverride.right)
- rect.right = _clipOverride.right;
-
- if (rect.top < _clipOverride.top)
- rect.top = _clipOverride.top;
-
- if (rect.bottom > _clipOverride.bottom)
- rect.bottom = _clipOverride.bottom;
- }
-
- if (rect.isValidRect() == false)
- return 1;
- }
-
- if (_actorHitMode) {
- if (_actorHitX < rect.left || _actorHitX >= rect.right || _actorHitY < rect.top || _actorHitY >= rect.bottom)
- return 0;
- } else
- markRectAsDirty(rect);
-
- if (rect.top >= _out.h || rect.bottom <= 0)
- return 0;
-
- if (rect.left >= _out.w || rect.right <= 0)
- return 0;
-
- v1.replen = 0;
-
- if (_mirror) {
- if (!use_scaling)
- skip = -v1.x;
- if (skip > 0) {
- v1.skip_width -= skip;
- codec1_ignorePakCols(v1, skip);
- v1.x = 0;
- } else {
- skip = rect.right - _out.w;
- if (skip <= 0) {
- drawFlag = 2;
- } else {
- v1.skip_width -= skip;
- }
- }
- } else {
- if (!use_scaling)
- skip = rect.right - _out.w + 1;
- if (skip > 0) {
- v1.skip_width -= skip;
- codec1_ignorePakCols(v1, skip) ;
- v1.x = _out.w - 1;
- } else {
- skip = -1 - rect.left;
- if (skip <= 0)
- drawFlag = 2;
- else
- v1.skip_width -= skip;
- }
- }
-
- if (v1.skip_width <= 0 || _height <= 0)
- return 0;
-
- if (rect.left < 0)
- rect.left = 0;
-
- if (rect.top < 0)
- rect.top = 0;
-
- if (rect.top > _out.h)
- rect.top = _out.h;
-
- if (rect.bottom > _out.h)
- rect.bottom = _out.h;
-
- if (_draw_top > rect.top)
- _draw_top = rect.top;
- if (_draw_bottom < rect.bottom)
- _draw_bottom = rect.bottom;
-
- v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x;
-
- codec1_genericDecode(v1);
-
- return drawFlag;
-}
-
-void AkosRenderer::markRectAsDirty(Common::Rect rect) {
- rect.left -= _vm->virtscr[0].xstart & 7;
- rect.right -= _vm->virtscr[0].xstart & 7;
- _vm->markRectAsDirty(kMainVirtScreen, rect, _actorID);
-}
-
-byte AkosRenderer::codec5(int xmoveCur, int ymoveCur) {
- Common::Rect clip;
- int32 maxw, maxh;
-
- if (_actorHitMode) {
- error("codec5: _actorHitMode not yet implemented");
- return 0;
- }
-
- if (!_mirror) {
- clip.left = (_actorX - xmoveCur - _width) + 1;
- } else {
- clip.left = _actorX + xmoveCur - 1;
- }
-
- clip.top = _actorY + ymoveCur;
- clip.right = clip.left + _width;
- clip.bottom = clip.top + _height;
- maxw = _out.w;
- maxh = _out.h;
-
- markRectAsDirty(clip);
-
- clip.clip(maxw, maxh);
-
- if ((clip.left >= clip.right) || (clip.top >= clip.bottom))
- return 0;
-
- if (_draw_top > clip.top)
- _draw_top = clip.top;
- if (_draw_bottom < clip.bottom)
- _draw_bottom = clip.bottom;
-
- BompDrawData bdd;
-
- bdd.srcwidth = _width;
- bdd.srcheight = _height;
- bdd.dst = _out;
- bdd.dataptr = _srcptr;
- bdd.scale_x = 255;
- bdd.scale_y = 255;
- bdd.shadowMode = _shadow_mode;
-
- if (!_mirror) {
- bdd.x = (_actorX - xmoveCur - _width) + 1;
- } else {
- bdd.x = _actorX + xmoveCur;
- }
- bdd.y = _actorY + ymoveCur;
-
- bdd.maskPtr = _vm->getMaskBuffer(0, 0, _zbuf);
- _vm->drawBomp(bdd, !_mirror);
-
- _vm->_bompActorPalettePtr = NULL;
-
- return 0;
-}
-
-void AkosRenderer::akos16SetupBitReader(const byte *src) {
- akos16.unk5 = 0;
- akos16.numbits = 16;
- akos16.mask = (1 << *src) - 1;
- akos16.shift = *(src);
- akos16.color = *(src + 1);
- akos16.bits = (*(src + 2) | *(src + 3) << 8);
- akos16.dataptr = src + 4;
-}
-
-#define AKOS16_FILL_BITS() \
- if (akos16.numbits <= 8) { \
- akos16.bits |= (*akos16.dataptr++) << akos16.numbits; \
- akos16.numbits += 8; \
- }
-
-#define AKOS16_EAT_BITS(n) \
- akos16.numbits -= (n); \
- akos16.bits >>= (n);
-
-
-void AkosRenderer::akos16SkipData(int32 numbytes) {
- akos16DecodeLine(0, numbytes, 0);
-}
-
-void AkosRenderer::akos16DecodeLine(byte *buf, int32 numbytes, int32 dir) {
- uint16 bits, tmp_bits;
-
- while (numbytes != 0) {
- if (buf) {
- *buf = akos16.color;
- buf += dir;
- }
-
- if (akos16.unk5 == 0) {
- AKOS16_FILL_BITS()
- bits = akos16.bits & 3;
- if (bits & 1) {
- AKOS16_EAT_BITS(2)
- if (bits & 2) {
- tmp_bits = akos16.bits & 7;
- AKOS16_EAT_BITS(3)
- if (tmp_bits != 4) {
- akos16.color += (tmp_bits - 4);
- } else {
- akos16.unk5 = 1;
- AKOS16_FILL_BITS()
- akos16.unk6 = (akos16.bits & 0xff) - 1;
- AKOS16_EAT_BITS(8)
- AKOS16_FILL_BITS()
- }
- } else {
- AKOS16_FILL_BITS()
- akos16.color = ((byte)akos16.bits) & akos16.mask;
- AKOS16_EAT_BITS(akos16.shift)
- AKOS16_FILL_BITS()
- }
- } else {
- AKOS16_EAT_BITS(1);
- }
- } else {
- if (--akos16.unk6 == 0) {
- akos16.unk5 = 0;
- }
- }
- numbytes--;
- }
-}
-
-void AkosRenderer::akos16Decompress(byte *dest, int32 pitch, const byte *src, int32 t_width, int32 t_height, int32 dir,
- int32 numskip_before, int32 numskip_after, byte transparency, int maskLeft, int maskTop, int zBuf) {
- byte *tmp_buf = akos16.buffer;
- int maskpitch;
- byte *maskptr;
- const byte maskbit = revBitMask(maskLeft & 7);
-
- if (dir < 0) {
- dest -= (t_width - 1);
- tmp_buf += (t_width - 1);
- }
-
- akos16SetupBitReader(src);
-
- if (numskip_before != 0) {
- akos16SkipData(numskip_before);
- }
-
- maskpitch = _numStrips;
-
- maskptr = _vm->getMaskBuffer(maskLeft, maskTop, zBuf);
-
- assert(t_height > 0);
- assert(t_width > 0);
- while (t_height--) {
- akos16DecodeLine(tmp_buf, t_width, dir);
- bompApplyMask(akos16.buffer, maskptr, maskbit, t_width, transparency);
- bool HE7Check = (_vm->_heversion == 70);
- bompApplyShadow(_shadow_mode, _shadow_table, akos16.buffer, dest, t_width, transparency, HE7Check);
-
- if (numskip_after != 0) {
- akos16SkipData(numskip_after);
- }
- dest += pitch;
- maskptr += maskpitch;
- }
-}
-
-byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
- Common::Rect clip;
- int32 minx, miny, maxw, maxh;
- int32 skip_x, skip_y, cur_x, cur_y;
- byte transparency = (_vm->_heversion >= 61) ? palette[0] : 255;
-
- if (_actorHitMode) {
- error("codec16: _actorHitMode not yet implemented");
- return 0;
- }
-
- if (!_mirror) {
- clip.left = (_actorX - xmoveCur - _width) + 1;
- } else {
- clip.left = _actorX + xmoveCur;
- }
-
- clip.top = _actorY + ymoveCur;
- clip.right = clip.left + _width;
- clip.bottom = clip.top + _height;
-
- minx = miny = 0;
- maxw = _out.w;
- maxh = _out.h;
-
- if (_vm->_heversion >= 71) {
- if (_clipOverride.right > _clipOverride.left && _clipOverride.bottom > _clipOverride.top) {
- minx = _clipOverride.left;
- miny = _clipOverride.top;
- maxw = _clipOverride.right;
- maxh = _clipOverride.bottom;
- }
- }
-
- markRectAsDirty(clip);
-
- skip_x = 0;
- skip_y = 0;
- cur_x = _width - 1;
- cur_y = _height - 1;
-
- if (clip.left < minx) {
- skip_x = -clip.left;
- clip.left = 0;
- }
-
- if (clip.right > maxw) {
- cur_x -= clip.right - maxw;
- clip.right = maxw;
- }
-
- if (clip.top < miny) {
- skip_y -= clip.top;
- clip.top = 0;
- }
-
- if (clip.bottom > maxh) {
- cur_y -= clip.bottom - maxh;
- clip.bottom = maxh;
- }
-
- if ((clip.left >= clip.right) || (clip.top >= clip.bottom))
- return 0;
-
- if (_draw_top > clip.top)
- _draw_top = clip.top;
- if (_draw_bottom < clip.bottom)
- _draw_bottom = clip.bottom;
-
- int32 width_unk, height_unk;
-
- height_unk = clip.top;
- int32 dir;
-
- if (!_mirror) {
- dir = -1;
-
- int tmp_skip_x = skip_x;
- skip_x = _width - 1 - cur_x;
- cur_x = _width - 1 - tmp_skip_x;
- width_unk = clip.right - 1;
- } else {
- dir = 1;
- width_unk = clip.left;
- }
-
- int32 out_height;
-
- out_height = cur_y - skip_y;
- if (out_height < 0) {
- out_height = -out_height;
- }
- out_height++;
-
- cur_x -= skip_x;
- if (cur_x < 0) {
- cur_x = -cur_x;
- }
- cur_x++;
-
- int32 numskip_before = skip_x + (skip_y * _width);
- int32 numskip_after = _width - cur_x;
-
- byte *dst = (byte *)_out.pixels + width_unk + height_unk * _out.pitch;
-
- akos16Decompress(dst, _out.pitch, _srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency, clip.left, clip.top, _zbuf);
- return 0;
-}
-
-byte AkosRenderer::codec32(int xmoveCur, int ymoveCur) {
-#ifndef DISABLE_HE
- Common::Rect src, dst;
-
- if (!_mirror) {
- dst.left = (_actorX - xmoveCur - _width) + 1;
- } else {
- dst.left = _actorX + xmoveCur;
- }
-
- src.top = src.left = 0;
- src.right = _width;
- src.bottom = _height;
-
- dst.top = _actorY + ymoveCur;
- dst.right = dst.left + _width;
- dst.bottom = dst.top + _height;
-
- int diff;
- diff = dst.left - _clipOverride.left;
- if (diff < 0) {
- src.left -= diff;
- dst.left -= diff;
- }
- diff = dst.right - _clipOverride.right;
- if (diff > 0) {
- src.right -= diff;
- dst.right -= diff;
- }
- diff = dst.top - _clipOverride.top;
- if (diff < 0) {
- src.top -= diff;
- dst.top -= diff;
- }
- diff = dst.bottom - _clipOverride.bottom;
- if (diff > 0) {
- src.bottom -= diff;
- dst.bottom -= diff;
- }
-
- if (dst.isValidRect() == false)
- return 0;
-
- markRectAsDirty(dst);
-
- if (_draw_top > dst.top)
- _draw_top = dst.top;
- if (_draw_bottom < dst.bottom)
- _draw_bottom = dst.bottom;
-
- const uint8 *palPtr = NULL;
- if (_vm->_heversion >= 99) {
- palPtr = _vm->_hePalettes + 1792;
- }
-
- byte *dstPtr = (byte *)_out.pixels + dst.left + dst.top * _out.pitch;
- if (_shadow_mode == 3) {
- Wiz::decompressWizImage(dstPtr, _out.pitch, dst, _srcptr, src, 0, palPtr, xmap);
- } else {
- Wiz::decompressWizImage(dstPtr, _out.pitch, dst, _srcptr, src, 0, palPtr);
- }
-#endif
- return 0;
-}
-
-byte AkosCostumeLoader::increaseAnims(Actor *a) {
- return _vm->akos_increaseAnims(_akos, a);
-}
-
-bool ScummEngine::akos_increaseAnims(const byte *akos, Actor *a) {
- const byte *aksq, *akfo;
- int i;
- uint size;
- bool result;
-
- aksq = findResourceData(MKID('AKSQ'), akos);
- akfo = findResourceData(MKID('AKFO'), akos);
-
- size = getResourceDataSize(akfo) / 2;
-
- result = false;
- for (i = 0; i < 16; i++) {
- if (a->_cost.active[i] != 0)
- result |= akos_increaseAnim(a, i, aksq, (const uint16 *)akfo, size);
- }
- return result;
-}
-
-#define GW(o) ((int16)READ_LE_UINT16(aksq+curpos+(o)))
-#define GUW(o) READ_LE_UINT16(aksq+curpos+(o))
-#define GB(o) aksq[curpos+(o)]
-
-bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const uint16 *akfo, int numakfo) {
- byte active;
- uint old_curpos, curpos, end;
- uint code;
- bool flag_value, needRedraw;
- int tmp, tmp2;
-
- active = a->_cost.active[chan];
- end = a->_cost.end[chan];
- old_curpos = curpos = a->_cost.curpos[chan];
- flag_value = false;
- needRedraw = false;
-
- do {
-
- code = aksq[curpos];
- if (code & 0x80)
- code = (code << 8) | aksq[curpos + 1];
-
- switch (active) {
- case 6:
- case 8:
- switch (code) {
- case AKC_JumpIfSet:
- case AKC_AddVar:
- case AKC_SetVar:
- case AKC_SkipGE:
- case AKC_SkipG:
- case AKC_SkipLE:
- case AKC_SkipL:
-
- case AKC_SkipNE:
- case AKC_SkipE:
- case AKC_C016:
- case AKC_C017:
- case AKC_C018:
- case AKC_C019:
- curpos += 5;
- break;
- case AKC_JumpTable:
- case AKC_SetActorClip:
- case AKC_Ignore3:
- case AKC_Ignore2:
- case AKC_Ignore:
- case AKC_StartAnim:
- case AKC_StartVarAnim:
- case AKC_CmdQue3:
- case AKC_C042:
- case AKC_C044:
- case AKC_C0A3:
- curpos += 3;
- break;
- case AKC_SoundStuff:
- if (_heversion >= 61)
- curpos += 6;
- else
- curpos += 8;
- break;
- case AKC_Cmd3:
- case AKC_SetVarInActor:
- case AKC_SetDrawOffs:
- curpos += 6;
- break;
- case AKC_ClearFlag:
- case AKC_HideActor:
- case AKC_IncVar:
- case AKC_CmdQue3Quick:
- case AKC_Return:
- case AKC_EndSeq:
- curpos += 2;
- break;
- case AKC_JumpGE:
- case AKC_JumpG:
- case AKC_JumpLE:
- case AKC_JumpL:
- case AKC_JumpNE:
- case AKC_JumpE:
- case AKC_Random:
- curpos += 7;
- break;
- case AKC_Flip:
- case AKC_Jump:
- case AKC_StartAnimInActor:
- case AKC_C0A0:
- case AKC_C0A1:
- case AKC_C0A2:
- curpos += 4;
- break;
- case AKC_ComplexChan2:
- curpos += 4;
- // Fall through
- case AKC_ComplexChan:
- curpos += 3;
- tmp = aksq[curpos - 1];
- while (--tmp >= 0) {
- curpos += 4;
- curpos += (aksq[curpos] & 0x80) ? 2 : 1;
- }
- break;
- case AKC_C021:
- case AKC_C022:
- case AKC_C045:
- case AKC_C046:
- case AKC_C047:
- case AKC_C048:
- needRedraw = 1;
- curpos += aksq[curpos + 2];
- break;
- case AKC_C08E:
- akos_queCommand(7, a, GW(2), 0);
- curpos += 4;
- break;
- default:
- if ((code & 0xC000) == 0xC000)
- error("akos_increaseAnim: invalid code %x", code);
- curpos += (code & 0x8000) ? 2 : 1;
- break;
- }
- break;
- case 2:
- curpos += (code & 0x8000) ? 2 : 1;
- if (curpos > end)
- curpos = a->_cost.start[chan];
- break;
- case 3:
- if (curpos != end)
- curpos += (code & 0x8000) ? 2 : 1;
- break;
- }
-
- code = aksq[curpos];
- if (code & 0x80)
- code = (code << 8) | aksq[curpos + 1];
-
- if (flag_value && code != AKC_ClearFlag)
- continue;
-
- switch (code) {
- case AKC_StartAnimInActor:
- akos_queCommand(4, derefActor(a->getAnimVar(GB(2)), "akos_increaseAnim:29"), a->getAnimVar(GB(3)), 0);
- continue;
-
- case AKC_Random:
- a->setAnimVar(GB(6), _rnd.getRandomNumberRng(GW(2), GW(4)));
- continue;
- case AKC_JumpGE:
- case AKC_JumpG:
- case AKC_JumpLE:
- case AKC_JumpL:
- case AKC_JumpNE:
- case AKC_JumpE:
- if (akos_compare(a->getAnimVar(GB(4)), GW(5), code - AKC_JumpStart) != 0) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_IncVar:
- a->setAnimVar(0, a->getAnimVar(0) + 1);
- continue;
- case AKC_SetVar:
- a->setAnimVar(GB(4), GW(2));
- continue;
- case AKC_AddVar:
- a->setAnimVar(GB(4), a->getAnimVar(GB(4)) + GW(2));
- continue;
- case AKC_Flip:
- a->_flip = GW(2) != 0;
- continue;
- case AKC_CmdQue3:
- if (_heversion >= 61)
- tmp = GB(2);
- else
- tmp = GB(2) - 1;
- if ((uint) tmp < 24)
- akos_queCommand(3, a, a->_sound[tmp], 0);
- continue;
- case AKC_CmdQue3Quick:
- akos_queCommand(3, a, a->_sound[0], 0);
- continue;
- case AKC_StartAnim:
- akos_queCommand(4, a, GB(2), 0);
- continue;
- case AKC_StartVarAnim:
- akos_queCommand(4, a, a->getAnimVar(GB(2)), 0);
- continue;
- case AKC_SetVarInActor:
- derefActor(a->getAnimVar(GB(2)), "akos_increaseAnim:9")->setAnimVar(GB(3), GW(4));
- continue;
- case AKC_HideActor:
- akos_queCommand(1, a, 0, 0);
- continue;
- case AKC_SetActorClip:
- akos_queCommand(5, a, GB(2), 0);
- continue;
- case AKC_SoundStuff:
- if (_heversion >= 61)
- continue;
- tmp = GB(2) - 1;
- if (tmp >= 8)
- continue;
- tmp2 = GB(4);
- if (tmp2 < 1 || tmp2 > 3)
- error("akos_increaseAnim:8 invalid code %d", tmp2);
- akos_queCommand(tmp2 + 6, a, a->_sound[tmp], GB(6));
- continue;
- case AKC_SetDrawOffs:
- akos_queCommand(6, a, GW(2), GW(4));
- continue;
- case AKC_JumpTable:
- if (akfo == NULL)
- error("akos_increaseAnim: no AKFO table");
- tmp = a->getAnimVar(GB(2)) - 1;
- if (_heversion >= 80) {
- if (tmp < 0 || tmp > a->_cost.heJumpCountTable[chan] - 1)
- error("akos_increaseAnim: invalid jump value %d", tmp);
- curpos = READ_LE_UINT16(akfo + a->_cost.heJumpOffsetTable[chan] + tmp * 2);
- } else {
- if (tmp < 0 || tmp > numakfo - 1)
- error("akos_increaseAnim: invalid jump value %d", tmp);
- curpos = READ_LE_UINT16(&akfo[tmp]);
- }
- break;
- case AKC_JumpIfSet:
- if (!a->getAnimVar(GB(4)))
- continue;
- a->setAnimVar(GB(4), 0);
- curpos = GUW(2);
- break;
-
- case AKC_ClearFlag:
- flag_value = false;
- continue;
-
- case AKC_Jump:
- curpos = GUW(2);
- break;
-
- case AKC_Return:
- case AKC_EndSeq:
- case AKC_ComplexChan:
- case AKC_C08E:
- case AKC_ComplexChan2:
- break;
-
- case AKC_C021:
- case AKC_C022:
- needRedraw = 1;
- break;
-
- case AKC_Cmd3:
- case AKC_Ignore:
- case AKC_Ignore3:
- continue;
-
- case AKC_Ignore2:
- if (_heversion >= 71)
- akos_queCommand(3, a, a->_sound[a->getAnimVar(GB(2))], 0);
- continue;
-
- case AKC_SkipE:
- case AKC_SkipNE:
- case AKC_SkipL:
- case AKC_SkipLE:
- case AKC_SkipG:
- case AKC_SkipGE:
- if (akos_compare(a->getAnimVar(GB(4)), GW(2), code - AKC_SkipStart) == 0)
- flag_value = true;
- continue;
- case AKC_C016:
- if (_sound->isSoundRunning( a->_sound[a->getAnimVar(GB(4))])) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C017:
- if (!_sound->isSoundRunning(a->_sound[a->getAnimVar(GB(4))])) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C018:
- if (_sound->isSoundRunning(a->_sound[GB(4)])) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C019:
- if (!_sound->isSoundRunning(a->_sound[GB(4)])) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C042:
- akos_queCommand(9, a, a->_sound[GB(2)], 0);
- continue;
- case AKC_C044:
- akos_queCommand(9, a, a->_sound[a->getAnimVar(GB(2))], 0);
- continue;
- case AKC_C045:
- a->setUserCondition(GB(3), a->getAnimVar(GB(4)));
- continue;
- case AKC_C046:
- a->setAnimVar(GB(4), a->isUserConditionSet(GB(3)));
- continue;
- case AKC_C047:
- a->setTalkCondition(GB(3));
- continue;
- case AKC_C048:
- a->setAnimVar(GB(4), a->isTalkConditionSet(GB(3)));
- continue;
- case AKC_C0A0:
- akos_queCommand(8, a, GB(2), 0);
- continue;
- case AKC_C0A1:
- if (a->_heTalking != 0) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C0A2:
- if (a->_heTalking == 0) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C0A3:
- akos_queCommand(8, a, a->getAnimVar(GB(2)), 0);
- continue;
- case AKC_C0A4:
- if (VAR(VAR_TALK_ACTOR) != 0) {
- curpos = GUW(2);
- break;
- }
- continue;
- case AKC_C0A5:
- if (VAR(VAR_TALK_ACTOR) == 0) {
- curpos = GUW(2);
- break;
- }
- continue;
- default:
- if ((code & 0xC000) == 0xC000)
- error("Undefined uSweat token %X", code);
- }
- break;
- } while (1);
-
- int code2 = aksq[curpos];
- if (code2 & 0x80)
- code2 = (code2 << 8) | aksq[curpos + 1];
-
- assert((code2 & 0xC000) != 0xC000 || code2 == AKC_ComplexChan || code2 == AKC_Return || code2 == AKC_EndSeq || code2 == AKC_C08E || code2 == AKC_ComplexChan2 || code2 == AKC_C021 || code2 == AKC_C022);
-
- a->_cost.curpos[chan] = curpos;
-
- if (needRedraw)
- return 1;
- else
- return curpos != old_curpos;
-}
-
-void ScummEngine::akos_queCommand(byte cmd, Actor *a, int param_1, int param_2) {
- _akosQueuePos++;
- checkRange(31, 0, _akosQueuePos, "akos_queCommand overflow");
-
- _akosQueue[_akosQueuePos].cmd = cmd;
- _akosQueue[_akosQueuePos].actor = a->_number;
- _akosQueue[_akosQueuePos].param1 = param_1;
- _akosQueue[_akosQueuePos].param2 = param_2;
-}
-
-void ScummEngine::akos_processQueue() {
- byte cmd;
- int actor, param_1, param_2;
-
- while (_akosQueuePos) {
- cmd = _akosQueue[_akosQueuePos].cmd;
- actor = _akosQueue[_akosQueuePos].actor;
- param_1 = _akosQueue[_akosQueuePos].param1;
- param_2 = _akosQueue[_akosQueuePos].param2;
- _akosQueuePos--;
-
- Actor *a = derefActor(actor, "akos_processQueue");
-
- switch (cmd) {
- case 1:
- a->putActor(0, 0, 0);
- break;
- case 3:
- _sound->addSoundToQueue(param_1, 0, -1, 0);
- break;
- case 4:
- a->startAnimActor(param_1);
- break;
- case 5:
- a->_forceClip = param_1;
- break;
- case 6:
- a->_offsX = param_1;
- a->_offsY = param_2;
- break;
- case 7:
-#ifndef DISABLE_HE
- assert(_heversion >= 71);
- ((ScummEngine_v71he *)this)->queueAuxEntry(a->_number, param_1);
-#endif
- break;
- case 8:
- _actorToPrintStrFor = a->_number;
-
- a->_talkPosX = a->_heTalkQueue[param_1].posX;
- a->_talkPosY = a->_heTalkQueue[param_1].posY;
- a->_talkColor = a->_heTalkQueue[param_1].color;
-
- _string[0].loadDefault();
- _string[0].color = a->_talkColor;
- actorTalk(a->_heTalkQueue[param_1].sentence);
-
- break;
- case 9:
- _sound->addSoundToQueue(param_1, 0, -1, 4);
- break;
- default:
- error("akos_queCommand(%d,%d,%d,%d)", cmd, a->_number, param_1, param_2);
- }
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::akos_processQueue() {
- byte cmd;
- int actor, param_1, param_2;
-
- while (_akosQueuePos) {
- cmd = _akosQueue[_akosQueuePos].cmd;
- actor = _akosQueue[_akosQueuePos].actor;
- param_1 = _akosQueue[_akosQueuePos].param1;
- param_2 = _akosQueue[_akosQueuePos].param2;
- _akosQueuePos--;
-
- Actor *a = derefActor(actor, "akos_processQueue");
-
- switch (cmd) {
- case 1:
- a->putActor(0, 0, 0);
- break;
- case 3:
- if (param_1 != 0) {
- if (_imuseDigital) {
- _imuseDigital->startSfx(param_1, 63);
- }
- }
- break;
- case 4:
- a->startAnimActor(param_1);
- break;
- case 5:
- a->_forceClip = param_1;
- break;
- case 6:
- a->_offsX = param_1;
- a->_offsY = param_2;
- break;
- case 7:
- if (param_1 != 0) {
- if (_imuseDigital) {
- _imuseDigital->setVolume(param_1, param_2);
- }
- }
- break;
- case 8:
- if (param_1 != 0) {
- if (_imuseDigital) {
- _imuseDigital->setPan(param_1, param_2);
- }
- }
- break;
- case 9:
- if (param_1 != 0) {
- if (_imuseDigital) {
- _imuseDigital->setPriority(param_1, param_2);
- }
- }
- break;
- default:
- error("akos_queCommand(%d,%d,%d,%d)", cmd, a->_number, param_1, param_2);
- }
- }
-}
-#endif
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Akos)
-_GSETPTR(Scumm::bigCostumeScaleTable, GBVARS_BIGSCALETABLE_INDEX, byte, GBVARS_SCUMM)
-//_GSETPTR(Scumm::smallCostumeScaleTableAKOS, GBVARS_SMALLSCALETABLEAKOS_INDEX, byte, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Akos)
-_GRELEASEPTR(GBVARS_BIGSCALETABLE_INDEX, GBVARS_SCUMM)
-//_GRELEASEPTR(GBVARS_SMALLSCALETABLEAKOS_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/akos.h b/scumm/akos.h
deleted file mode 100644
index 1a849903d8..0000000000
--- a/scumm/akos.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef AKOS_H
-#define AKOS_H
-
-#include "scumm/base-costume.h"
-
-namespace Scumm {
-
-struct CostumeData;
-struct AkosHeader;
-struct AkosOffset;
-
-class AkosCostumeLoader : public BaseCostumeLoader {
-protected:
- const byte *_akos;
-
-public:
- AkosCostumeLoader(ScummEngine *vm) : BaseCostumeLoader(vm) {}
-
- void loadCostume(int id);
- byte increaseAnims(Actor *a);
- void costumeDecodeData(Actor *a, int frame, uint usemask);
-
- //void animateLimb(int limb, int f);
- bool hasManyDirections(int id) {
- loadCostume(id);
- return hasManyDirections();
- }
-
-protected:
- bool hasManyDirections();
-};
-
-class AkosRenderer : public BaseCostumeRenderer {
-protected:
- uint16 codec;
-
- // actor palette
- byte palette[256];
-
- // pointer to various parts of the costume resource
- const byte *akos;
- const AkosHeader *akhd;
-
- const byte *akpl, *akci, *aksq;
- const AkosOffset *akof;
- const byte *akcd;
- const byte *akct;
- const uint8 *xmap;
-
- struct {
- byte unk5;
- int unk6;
- byte mask;
- byte color;
- byte shift;
- uint16 bits;
- byte numbits;
- const byte *dataptr;
- byte buffer[336];
- } akos16;
-
-public:
- AkosRenderer(ScummEngine *scumm) : BaseCostumeRenderer(scumm) {
- akos = 0;
- akhd = 0;
- akpl = 0;
- akci = 0;
- aksq = 0;
- akof = 0;
- akcd = 0;
- akct = 0;
- xmap = 0;
- _actorHitMode = false;
- }
-
- bool _actorHitMode;
- int16 _actorHitX, _actorHitY;
- bool _actorHitResult;
-
- void setPalette(byte *palette);
- void setFacing(const Actor *a);
- void setCostume(int costume, int shadow);
-
-protected:
- byte drawLimb(const Actor *a, int limb);
-
- byte codec1(int xmoveCur, int ymoveCur);
- void codec1_genericDecode(Codec1 &v1);
- byte codec5(int xmoveCur, int ymoveCur);
- byte codec16(int xmoveCur, int ymoveCur);
- byte codec32(int xmoveCur, int ymoveCur);
- void akos16SetupBitReader(const byte *src);
- void akos16SkipData(int32 numskip);
- void akos16DecodeLine(byte *buf, int32 numbytes, int32 dir);
- void akos16Decompress(byte *dest, int32 pitch, const byte *src, int32 t_width, int32 t_height, int32 dir, int32 numskip_before, int32 numskip_after, byte transparency, int maskLeft, int maskTop, int zBuf);
-
- void markRectAsDirty(Common::Rect rect);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/base-costume.cpp b/scumm/base-costume.cpp
deleted file mode 100644
index e93b5b80cd..0000000000
--- a/scumm/base-costume.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/base-costume.h"
-#include "scumm/costume.h"
-
-namespace Scumm {
-
-byte BaseCostumeRenderer::drawCostume(const VirtScreen &vs, int numStrips, const Actor *a, bool drawToBackBuf) {
- int i;
- byte result = 0;
-
- _out = vs;
- if (drawToBackBuf)
- _out.pixels = vs.getBackPixels(0, 0);
- else
- _out.pixels = vs.getPixels(0, 0);
-
- _actorX += _vm->virtscr[0].xstart & 7;
- _out.w = _out.pitch;
- _out.pixels = (byte *)_out.pixels - (_vm->virtscr[0].xstart & 7);
-
- _numStrips = numStrips;
-
- if (_vm->_version == 1) {
- _xmove = 0;
- _ymove = 0;
- } else if (_vm->_features & GF_OLD_BUNDLE) {
- _xmove = -72;
- _ymove = -100;
- } else {
- _xmove = _ymove = 0;
- }
- for (i = 0; i < 16; i++)
- result |= drawLimb(a, i);
- return result;
-}
-
-void BaseCostumeRenderer::codec1_ignorePakCols(Codec1 &v1, int num) {
- num *= _height;
-
- do {
- v1.replen = *_srcptr++;
- v1.repcolor = v1.replen >> v1.shr;
- v1.replen &= v1.mask;
-
- if (!v1.replen)
- v1.replen = *_srcptr++;
-
- do {
- if (!--num)
- return;
- } while (--v1.replen);
- } while (1);
-}
-
-bool ScummEngine::isCostumeInUse(int cost) const {
- int i;
- Actor *a;
-
- if (_roomResource != 0)
- for (i = 1; i < _numActors; i++) {
- a = derefActor(i);
- if (a->isInCurrentRoom() && a->_costume == cost)
- return true;
- }
-
- return false;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/base-costume.h b/scumm/base-costume.h
deleted file mode 100644
index e1d096dea9..0000000000
--- a/scumm/base-costume.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef BASE_COSTUME_H
-#define BASE_COSTUME_H
-
-#include "common/scummsys.h"
-#include "scumm/actor.h" // for CostumeData
-
-namespace Scumm {
-
-#if !defined(__GNUC__)
-#pragma START_PACK_STRUCTS
-#endif
-
-struct CostumeInfo {
- uint16 width, height;
- int16 rel_x, rel_y;
- int16 move_x, move_y;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
-#pragma END_PACK_STRUCTS
-#endif
-
-
-
-#ifdef PALMOS_68K
-extern const byte *smallCostumeScaleTable;
-extern const byte *bigCostumeScaleTable;
-#else
-extern const byte smallCostumeScaleTable[256];
-extern const byte bigCostumeScaleTable[768];
-#endif
-
-
-
-class Actor;
-class ScummEngine;
-struct VirtScreen;
-
-class BaseCostumeLoader {
-protected:
- ScummEngine *_vm;
-
-public:
- BaseCostumeLoader(ScummEngine *vm) : _vm(vm) {}
- virtual ~BaseCostumeLoader() {}
-
- virtual void loadCostume(int id) = 0;
- virtual byte increaseAnims(Actor *a) = 0;
- virtual void costumeDecodeData(Actor *a, int frame, uint usemask) = 0;
-
- bool hasManyDirections(int id) { return false; }
-};
-
-
-/**
- * Base class for both ClassicCostumeRenderer and AkosRenderer.
- */
-class BaseCostumeRenderer {
-public:
- Common::Rect _clipOverride;
- byte _actorID;
-
- byte _shadow_mode;
- byte *_shadow_table;
-
- int _actorX, _actorY;
- byte _zbuf;
- byte _scaleX, _scaleY;
-
- int _draw_top, _draw_bottom;
- byte _paletteNum;
- bool _skipLimbs;
- bool _actorDrawVirScr;
-
-
-protected:
- ScummEngine *_vm;
-
- // Destination
- Graphics::Surface _out;
- int32 _numStrips;
-
- // Source pointer
- const byte *_srcptr;
-
- // current move offset
- int _xmove, _ymove;
-
- // whether to draw the actor mirrored
- bool _mirror;
-
- // width and height of cel to decode
- int _width, _height;
-
- struct Codec1 {
- // Parameters for the original ("V1") costume codec.
- const byte *scaletable;
- byte mask, shr;
- byte repcolor;
- byte replen;
- int scaleXstep;
- int x, y;
- int scaleXindex, scaleYindex;
- int skip_width;
- byte *destptr;
- const byte *mask_ptr;
- };
-
-public:
- BaseCostumeRenderer(ScummEngine *scumm) {
- _actorID = 0;
- _shadow_mode = 0;
- _shadow_table = 0;
- _actorX = _actorY = 0;
- _zbuf = 0;
- _scaleX = _scaleY = 0;
- _draw_top = _draw_bottom = 0;
-
- _vm = scumm;
- _numStrips = -1;
- _srcptr = 0;
- _xmove = _ymove = 0;
- _mirror = false;
- _width = _height = 0;
- _skipLimbs = 0;
- _paletteNum = 0;
- }
- virtual ~BaseCostumeRenderer() {}
-
- virtual void setPalette(byte *palette) = 0;
- virtual void setFacing(const Actor *a) = 0;
- virtual void setCostume(int costume, int shadow) = 0;
-
-
- byte drawCostume(const VirtScreen &vs, int numStrips, const Actor *a, bool drawToBackBuf);
-
-protected:
- virtual byte drawLimb(const Actor *a, int limb) = 0;
-
- void codec1_ignorePakCols(Codec1 &v1, int num);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/bomp.cpp b/scumm/bomp.cpp
deleted file mode 100644
index f3f78e4731..0000000000
--- a/scumm/bomp.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/akos.h"
-#include "scumm/bomp.h"
-#include "scumm/util.h"
-
-
-namespace Scumm {
-
-static int32 setupBompScale(byte *scaling, int32 size, byte scale);
-
-static void bompScaleFuncX(byte *line_buffer, byte *scaling_x_ptr, byte skip, int32 size);
-
-static void bompApplyShadow0(const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency, byte HE7Check);
-static void bompApplyShadow1(const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency);
-static void bompApplyShadow3(const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency);
-static void bompApplyActorPalette(byte *actorPalette, byte *line_buffer, int32 size);
-
-
-
-void decompressBomp(byte *dst, const byte *src, int w, int h) {
- assert(w > 0);
- assert(h > 0);
-
- do {
- bompDecodeLine(dst, src + 2, w);
- src += READ_LE_UINT16(src) + 2;
- dst += w;
- } while (--h);
-}
-
-void bompDecodeLine(byte *dst, const byte *src, int len) {
- assert(len > 0);
-
- int num;
- byte code, color;
-
- while (len > 0) {
- code = *src++;
- num = (code >> 1) + 1;
- if (num > len)
- num = len;
- len -= num;
- if (code & 1) {
- color = *src++;
- memset(dst, color, num);
- } else {
- memcpy(dst, src, num);
- src += num;
- }
- dst += num;
- }
-}
-
-void bompDecodeLineReverse(byte *dst, const byte *src, int len) {
- assert(len > 0);
-
- dst += len;
-
- int num;
- byte code, color;
-
- while (len > 0) {
- code = *src++;
- num = (code >> 1) + 1;
- if (num > len)
- num = len;
- len -= num;
- dst -= num;
- if (code & 1) {
- color = *src++;
- memset(dst, color, num);
- } else {
- memcpy(dst, src, num);
- src += num;
- }
- }
-}
-
-void bompApplyMask(byte *line_buffer, byte *mask, byte maskbit, int32 size, byte transparency) {
- while (1) {
- do {
- if (size-- == 0)
- return;
- if (*mask & maskbit) {
- *line_buffer = transparency;
- }
- line_buffer++;
- maskbit >>= 1;
- } while (maskbit);
- mask++;
- maskbit = 128;
- }
-}
-
-void bompApplyShadow(int shadowMode, const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency, byte HE7Check) {
- assert(size > 0);
- switch (shadowMode) {
- case 0:
- bompApplyShadow0(shadowPalette, line_buffer, dst, size, transparency, HE7Check);
- break;
- case 1:
- bompApplyShadow1(shadowPalette, line_buffer, dst, size, transparency);
- break;
- case 3:
- bompApplyShadow3(shadowPalette, line_buffer, dst, size, transparency);
- break;
- default:
- error("Unknown shadow mode %d", shadowMode);
- }
-}
-void bompApplyShadow0(const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency, byte HE7Check = false) {
- while (size-- > 0) {
- byte tmp = *line_buffer++;
- if (tmp != transparency) {
- if (HE7Check)
- *dst = shadowPalette[tmp];
- else
- *dst = tmp;
- }
- dst++;
- }
-}
-
-void bompApplyShadow1(const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency) {
- while (size-- > 0) {
- byte tmp = *line_buffer++;
- if (tmp != transparency) {
- if (tmp == 13) {
- tmp = shadowPalette[*dst];
- }
- *dst = tmp;
- }
- dst++;
- }
-}
-
-void bompApplyShadow3(const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency) {
- while (size-- > 0) {
- byte tmp = *line_buffer++;
- if (tmp != transparency) {
- if (tmp < 8) {
- tmp = shadowPalette[*dst + (tmp << 8)];
- }
- *dst = tmp;
- }
- dst++;
- }
-}
-
-void bompApplyActorPalette(byte *actorPalette, byte *line_buffer, int32 size) {
- if (actorPalette != 0) {
- actorPalette[255] = 255;
- while (size-- > 0) {
- *line_buffer = actorPalette[*line_buffer];
- line_buffer++;
- }
- }
-}
-
-void bompScaleFuncX(byte *line_buffer, byte *scaling_x_ptr, byte skip, int32 size) {
- byte *line_ptr1 = line_buffer;
- byte *line_ptr2 = line_buffer;
-
- byte tmp = *scaling_x_ptr++;
-
- while (size--) {
- if ((skip & tmp) == 0) {
- *line_ptr1++ = *line_ptr2;
- }
- line_ptr2++;
- skip >>= 1;
- if (skip == 0) {
- skip = 128;
- tmp = *scaling_x_ptr++;
- }
- }
-}
-
-void ScummEngine::drawBomp(const BompDrawData &bd, bool mirror) {
- const byte *src;
- byte *dst;
- byte *mask = 0;
- Common::Rect clip;
- byte *scalingYPtr = 0;
- byte skip_y_bits = 0x80;
- byte skip_y_new = 0;
- byte tmp;
- byte bomp_scaling_x[64];
- byte bomp_scaling_y[64];
-
-
- if (bd.x < 0) {
- clip.left = -bd.x;
- } else {
- clip.left = 0;
- }
-
- if (bd.y < 0) {
- clip.top = -bd.y;
- } else {
- clip.top = 0;
- }
-
- clip.right = bd.srcwidth;
- if (clip.right > bd.dst.w - bd.x) {
- clip.right = bd.dst.w - bd.x;
- }
-
- clip.bottom = bd.srcheight;
- if (clip.bottom > bd.dst.h - bd.y) {
- clip.bottom = bd.dst.h - bd.y;
- }
-
- src = bd.dataptr;
- dst = (byte *)bd.dst.pixels + bd.y * bd.dst.pitch + (bd.x + clip.left);
-
- const byte maskbit = revBitMask((bd.x + clip.left) & 7);
-
- // Mask against any additionally imposed mask
- if (bd.maskPtr) {
- mask = bd.maskPtr + (bd.y * gdi._numStrips) + ((bd.x + clip.left) / 8);
- }
-
- // Setup vertical scaling
- if (bd.scale_y != 255) {
- int scaleBottom = setupBompScale(bomp_scaling_y, bd.srcheight, bd.scale_y);
- scalingYPtr = bomp_scaling_y;
-
- skip_y_new = *scalingYPtr++;
- skip_y_bits = 0x80;
-
- if (clip.bottom > scaleBottom) {
- clip.bottom = scaleBottom;
- }
- }
-
- // Setup horizontal scaling
- if (bd.scale_x != 255) {
- int scaleRight = setupBompScale(bomp_scaling_x, bd.srcwidth, bd.scale_x);
-
- if (clip.right > scaleRight) {
- clip.right = scaleRight;
- }
- }
-
- const int width = clip.right - clip.left;
-
- if (width <= 0)
- return;
-
- int pos_y = 0;
- byte line_buffer[1024];
-
- byte *line_ptr = line_buffer + clip.left;
-
- // Loop over all lines
- while (pos_y < clip.bottom) {
- // Decode a single (bomp encoded) line, reversed if we are in mirror mode
- if (mirror)
- bompDecodeLineReverse(line_buffer, src + 2, bd.srcwidth);
- else
- bompDecodeLine(line_buffer, src + 2, bd.srcwidth);
- src += READ_LE_UINT16(src) + 2;
-
- // If vertical scaling is enabled, do it
- if (bd.scale_y != 255) {
- // A bit set means we should skip this line...
- tmp = skip_y_new & skip_y_bits;
-
- // Advance the scale-skip bit mask, if it's 0, get the next scale-skip byte
- skip_y_bits /= 2;
- if (skip_y_bits == 0) {
- skip_y_bits = 0x80;
- skip_y_new = *scalingYPtr++;
- }
-
- // Skip the current line if the above check tells us to
- if (tmp != 0)
- continue;
- }
-
- // Perform horizontal scaling
- if (bd.scale_x != 255) {
- bompScaleFuncX(line_buffer, bomp_scaling_x, 0x80, bd.srcwidth);
- }
-
- // The first clip.top lines are to be clipped, i.e. not drawn
- if (clip.top > 0) {
- clip.top--;
- } else {
- // Replace the parts of the line which are masked with the transparency color
- if (bd.maskPtr)
- bompApplyMask(line_ptr, mask, maskbit, width, 255);
-
- // Apply custom color map, if available
- if (_bompActorPalettePtr)
- bompApplyActorPalette(_bompActorPalettePtr, line_ptr, width);
-
- // Finally, draw the decoded, scaled, masked and recolored line onto
- // the target surface, using the specified shadow mode
- bompApplyShadow(bd.shadowMode, _shadowPalette, line_ptr, dst, width, 255);
- }
-
- // Advance to the next line
- pos_y++;
- mask += gdi._numStrips;
- dst += bd.dst.pitch;
- }
-}
-
-static const byte bitCount[] = {
- 8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4,
- 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
- 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
- 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
- 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
- 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
- 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
- 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2,
- 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
- 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1,
- 4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0,
-};
-
-int32 setupBompScale(byte *scaling, int32 size, byte scale) {
- byte tmp;
- int32 count;
- const byte *tmp_ptr;
- byte *tmp_scaling = scaling;
- byte a = 0;
- byte ret_value = 0;
- const int offsets[8] = { 3, 2, 1, 0, 7, 6, 5, 4 };
-
- count = (256 - size / 2);
- assert(0 <= count && count < 768);
- tmp_ptr = bigCostumeScaleTable + count;
-
- count = (size + 7) / 8;
- while (count--) {
- a = 0;
- for (int i = 0; i < 8; i++) {
- tmp = *(tmp_ptr + offsets[i]);
- a <<= 1;
- if (scale < tmp) {
- a |= 1;
- }
- }
- tmp_ptr += 8;
-
- *tmp_scaling++ = a;
- }
- if ((size & 7) != 0) {
- *(tmp_scaling - 1) |= revBitMask(size & 7);
- }
-
- count = (size + 7) / 8;
- while (count--) {
- tmp = *scaling++;
- ret_value += bitCount[tmp];
- }
-
- return ret_value;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/bomp.h b/scumm/bomp.h
deleted file mode 100644
index 74d367172d..0000000000
--- a/scumm/bomp.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef BOMP_H
-#define BOMP_H
-
-#include "common/scummsys.h"
-
-namespace Scumm {
-
-void bompApplyMask(byte *line_buffer, byte *mask, byte maskbit, int32 size, byte transparency);
-void bompApplyShadow(int shadowMode, const byte *shadowPalette, const byte *line_buffer, byte *dst, int32 size, byte transparency, byte HE7Check = false);
-
-void decompressBomp(byte *dst, const byte *src, int w, int h);
-void bompDecodeLine(byte *dst, const byte *src, int size);
-void bompDecodeLineReverse(byte *dst, const byte *src, int size);
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/boxes.cpp b/scumm/boxes.cpp
deleted file mode 100644
index 4460519480..0000000000
--- a/scumm/boxes.cpp
+++ /dev/null
@@ -1,1271 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/boxes.h"
-#include "scumm/util.h"
-
-#include "common/util.h"
-
-namespace Scumm {
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
-struct Box { /* Internal walkbox file format */
- union {
- struct {
- byte uy;
- byte ly;
- byte ulx;
- byte urx;
- byte llx;
- byte lrx;
- byte mask;
- byte flags;
- } GCC_PACK v2;
-
- struct {
- int16 ulx, uly;
- int16 urx, ury;
- int16 lrx, lry;
- int16 llx, lly;
- byte mask;
- byte flags;
- uint16 scale;
- } GCC_PACK old;
-
- struct {
- int32 ulx, uly;
- int32 urx, ury;
- int32 lrx, lry;
- int32 llx, lly;
- uint32 mask;
- uint32 flags;
- uint32 scaleSlot;
- uint32 scale;
- uint32 unk2;
- uint32 unk3;
- } GCC_PACK v8;
- } GCC_PACK;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-#define BOX_MATRIX_SIZE 2000
-#define BOX_DEBUG 0
-
-
-static bool compareSlope(int X1, int Y1, int X2, int Y2, int X3, int Y3);
-static Common::Point closestPtOnLine(const Common::Point &start, const Common::Point &end, int x, int y);
-
-
-byte ScummEngine::getMaskFromBox(int box) {
- // Fix for bug #740244 and #755863. This appears to have been a
- // long standing bug in the original engine?
- if (_version <= 3 && box == 255)
- return 1;
-
- Box *ptr = getBoxBaseAddr(box);
- if (!ptr)
- return 0;
-
- // WORKAROUND for bug #847827: This is a bug in the data files, as it also
- // occurs with the original engine. We work around it here anyway.
- if (_gameId == GID_INDY4 && _currentRoom == 225 && _roomResource == 94 && box == 8)
- return 0;
-
- if (_version == 8)
- return (byte) FROM_LE_32(ptr->v8.mask);
- else if (_version <= 2)
- return ptr->v2.mask;
- else
- return ptr->old.mask;
-}
-
-void ScummEngine::setBoxFlags(int box, int val) {
- debug(2, "setBoxFlags(%d, 0x%02x)", box, val);
-
- /* SCUMM7+ stuff */
- if (val & 0xC000) {
- assert(box >= 0 && box < 65);
- _extraBoxFlags[box] = val;
- } else {
- Box *ptr = getBoxBaseAddr(box);
- if (!ptr)
- return;
- if (_version == 8)
- ptr->v8.flags = TO_LE_32(val);
- else if (_version <= 2)
- ptr->v2.flags = val;
- else
- ptr->old.flags = val;
- }
-}
-
-byte ScummEngine::getBoxFlags(int box) {
- Box *ptr = getBoxBaseAddr(box);
- if (!ptr)
- return 0;
- if (_version == 8)
- return (byte) FROM_LE_32(ptr->v8.flags);
- else if (_version <= 2)
- return ptr->v2.flags;
- else
- return ptr->old.flags;
-}
-
-void ScummEngine::setBoxScale(int box, int scale) {
- Box *ptr = getBoxBaseAddr(box);
- assert(ptr);
- if (_version == 8)
- ptr->v8.scale = TO_LE_32(scale);
- else if (_version <= 2)
- error("This should not ever be called!");
- else
- ptr->old.scale = TO_LE_16(scale);
-}
-
-void ScummEngine::setBoxScaleSlot(int box, int slot) {
- Box *ptr = getBoxBaseAddr(box);
- assert(ptr);
- ptr->v8.scaleSlot = TO_LE_32(slot);
-}
-
-int ScummEngine::getScale(int box, int x, int y) {
- if (_features & GF_NO_SCALING)
- return 255;
-
- Box *ptr = getBoxBaseAddr(box);
- if (!ptr)
- return 255;
-
- int slot , scale;
-
- if (_version == 8) {
- // COMI has a separate field for the scale slot...
- slot = FROM_LE_32(ptr->v8.scaleSlot);
- scale = FROM_LE_32(ptr->v8.scale);
- } else {
- scale = READ_LE_UINT16(&ptr->old.scale);
- if (scale & 0x8000)
- slot = (scale & 0x7FFF) + 1;
- else
- slot = 0;
- }
-
- // Was a scale slot specified? If so, we compute the effective scale
- // from it, ignoring the box scale.
- if (slot)
- scale = getScaleFromSlot(slot, x, y);
-
- return scale;
-}
-
-
-int ScummEngine::getScaleFromSlot(int slot, int x, int y) {
- assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
- int scale;
- int scaleX = 0, scaleY = 0;
- ScaleSlot &s = _scaleSlots[slot-1];
-
- if (s.y1 == s.y2 && s.x1 == s.x2)
- error("Invalid scale slot %d", slot);
-
- if (s.y1 != s.y2) {
- if (y < 0)
- y = 0;
-
- scaleY = (s.scale2 - s.scale1) * (y - s.y1) / (s.y2 - s.y1) + s.scale1;
- }
- if (s.x1 == s.x2) {
- scale = scaleY;
- } else {
- scaleX = (s.scale2 - s.scale1) * (x - s.x1) / (s.x2 - s.x1) + s.scale1;
-
- if (s.y1 == s.y2) {
- scale = scaleX;
- } else {
- scale = (scaleX + scaleY) / 2;
- }
- }
-
- // Clip the scale to range 1-255
- if (scale < 1)
- scale = 1;
- else if (scale > 255)
- scale = 255;
-
- return scale;
-}
-
-int ScummEngine::getBoxScale(int box) {
- if (_features & GF_NO_SCALING)
- return 255;
- Box *ptr = getBoxBaseAddr(box);
- if (!ptr)
- return 255;
- if (_version == 8)
- return FROM_LE_32(ptr->v8.scale);
- else
- return READ_LE_UINT16(&ptr->old.scale);
-}
-
-/**
- * Convert a rtScaleTable resource to a corresponding scale slot entry.
- *
- * At some point, we discovered that the old scale items (stored in rtScaleTable
- * resources) are in fact the same as (or rather, a predecessor of) the
- * scale slots used in COMI. While not being precomputed (and thus slightly
- * slower), scale slots are more flexible, and most importantly, can cope with
- * rooms higher than 200 pixels. That's an essential feature for DIG and FT
- * and in fact the lack of it caused various bugs in the past.
- *
- * Hence, we decided to switch all games to use the more powerful scale slots.
- * To accomodate old savegames, we attempt here to convert rtScaleTable
- * resources to scale slots.
- */
-void ScummEngine::convertScaleTableToScaleSlot(int slot) {
- assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
-
- byte *resptr = getResourceAddress(rtScaleTable, slot);
- int lowerIdx, upperIdx;
- float m, oldM;
-
- // Do nothing if the given scale table doesn't exist
- if (resptr == 0)
- return;
-
- if (resptr[0] == resptr[199]) {
- // The scale is constant. This usually means we encountered one of the
- // "broken" cases. We set pseudo scale item values which lead to a
- // constant scale of 255.
- setScaleSlot(slot, 0, 0, 255, 0, 199, 255);
- return;
- }
-
- /*
- * Essentially, what we are doing here is some kind of "line fitting"
- * algorithm. The data in the scale table represents a linear graph. What
- * we want to find is the slope and (vertical) offset of this line. Things
- * are complicated by the fact that the line is cut of vertically at 1 and
- * 255. We have to be careful in handling this and some border cases.
- *
- * Some typical graphs look like these:
- * --- --- ---
- * / --- \
- * ___/ --- \___
- *
- * The method used here is to compute the slope of secants fixed at the
- * left and right end. For most cases this detects the cut-over points
- * quite accurately.
- */
-
- // Search for the bend on the left side
- m = (resptr[199] - resptr[0]) / 199.0;
- for (lowerIdx = 0; lowerIdx < 199 && (resptr[lowerIdx] == 1 || resptr[lowerIdx] == 255); lowerIdx++) {
- oldM = m;
- m = (resptr[199] - resptr[lowerIdx+1]) / (float)(199 - (lowerIdx+1));
- if (m > 0) {
- if (m <= oldM)
- break;
- } else {
- if (m >= oldM)
- break;
- }
- }
-
- // Search for the bend on the right side
- m = (resptr[199] - resptr[0]) / 199.0;
- for (upperIdx = 199; upperIdx > 1 && (resptr[upperIdx] == 1 || resptr[upperIdx] == 255); upperIdx--) {
- oldM = m;
- m = (resptr[upperIdx-1] - resptr[0]) / (float)(upperIdx-1);
- if (m > 0) {
- if (m <= oldM)
- break;
- } else {
- if (m >= oldM)
- break;
- }
- }
-
- // If lowerIdx and upperIdx are equal, we assume that there
- // was no bend at all, and go for the maximum range.
- if (lowerIdx == upperIdx) {
- lowerIdx = 0;
- upperIdx = 199;
- }
-
- // The values of y1 and y2, as well as the scale, can now easily be computed
- setScaleSlot(slot, 0, lowerIdx, resptr[lowerIdx], 0, upperIdx, resptr[upperIdx]);
-
- // Compute the variance, for debugging. It shouldn't exceed 1
- ScaleSlot &s = _scaleSlots[slot-1];
- int y;
- int sum = 0;
- int scale;
- float variance;
- for (y = 0; y < 200; y++) {
- scale = (s.scale2 - s.scale1) * (y - s.y1) / (s.y2 - s.y1) + s.scale1;
- if (scale < 1)
- scale = 1;
- else if (scale > 255)
- scale = 255;
-
- sum += (resptr[y] - scale) * (resptr[y] - scale);
- }
- variance = sum / (200.0 - 1.0);
- if (variance > 1)
- debug(1, "scale item %d, variance %f exceeds 1 (room %d)", slot, variance, _currentRoom);
-}
-
-void ScummEngine::setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2) {
- assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
- ScaleSlot &s = _scaleSlots[slot-1];
- s.x2 = x2;
- s.y2 = y2;
- s.scale2 = scale2;
- s.x1 = x1;
- s.y1 = y1;
- s.scale1 = scale1;
-}
-
-byte ScummEngine::getNumBoxes() {
- byte *ptr = getResourceAddress(rtMatrix, 2);
- if (!ptr)
- return 0;
- if (_version == 8)
- return (byte) READ_LE_UINT32(ptr);
- else
- return ptr[0];
-}
-
-Box *ScummEngine::getBoxBaseAddr(int box) {
- byte *ptr = getResourceAddress(rtMatrix, 2);
- if (!ptr || box == 255)
- return NULL;
-
- // The NES version of Maniac Mansion attempts to set flags for boxes 2-4
- // when there are only three boxes (0-2) when walking out to the garage.
- if ((_gameId == GID_MANIAC) && (_platform == Common::kPlatformNES) && (box >= ptr[0]))
- return NULL;
-
- // FIXME: In "pass to adventure", the loom demo, when bobbin enters
- // the tent to the elders, box = 2, but ptr[0] = 2 -> errors out.
- // Hence we disable the check for now. Maybe in PASS (and other old games)
- // we shouldn't subtract 1 from ptr[0] when performing the check?
- // this also seems to be incorrect for atari st demo of zak
- // and assumingly other v2 games
- // The same happens in Indy3EGA (see bug #770351)
- // Also happens in ZakEGA (see bug #771803).
- //
- // This *might* mean that we have a bug in our box implementation
- // OTOH, the original engine, unlike ScummVM, performed no bound
- // checking at all. All the problems so far have been cases where
- // the value was exactly one more than what we consider the maximum.
- // So it's very well possible that all of these are script errors.
- if (_version <= 4 && ptr[0] == box)
- box--;
-
- checkRange(ptr[0] - 1, 0, box, "Illegal box %d");
- if (_version <= 2)
- return (Box *)(ptr + box * SIZEOF_BOX_V2 + 1);
- else if (_version == 3)
- return (Box *)(ptr + box * SIZEOF_BOX_V3 + 1);
- else if (_features & GF_SMALL_HEADER)
- return (Box *)(ptr + box * SIZEOF_BOX + 1);
- else if (_version == 8)
- return (Box *)(ptr + box * SIZEOF_BOX_V8 + 4);
- else
- return (Box *)(ptr + box * SIZEOF_BOX + 2);
-}
-
-int ScummEngine::getSpecialBox(int x, int y) {
- int i;
- int numOfBoxes;
- byte flag;
-
- numOfBoxes = getNumBoxes() - 1;
-
- for (i = numOfBoxes; i >= 0; i--) {
- flag = getBoxFlags(i);
-
- if (!(flag & kBoxInvisible) && (flag & kBoxPlayerOnly))
- return (-1);
-
- if (checkXYInBoxBounds(i, x, y))
- return (i);
- }
-
- return (-1);
-}
-
-bool ScummEngine::checkXYInBoxBounds(int b, int x, int y) {
- BoxCoords box;
-
- if (b < 0 || b == Actor::kInvalidBox)
- return false;
-
- getBoxCoordinates(b, &box);
-
- if (x < box.ul.x && x < box.ur.x && x < box.lr.x && x < box.ll.x)
- return false;
-
- if (x > box.ul.x && x > box.ur.x && x > box.lr.x && x > box.ll.x)
- return false;
-
- if (y < box.ul.y && y < box.ur.y && y < box.lr.y && y < box.ll.y)
- return false;
-
- if (y > box.ul.y && y > box.ur.y && y > box.lr.y && y > box.ll.y)
- return false;
-
- if (box.ul.x == box.ur.x && box.ul.y == box.ur.y && box.lr.x == box.ll.x && box.lr.y == box.ll.y ||
- box.ul.x == box.ll.x && box.ul.y == box.ll.y && box.ur.x == box.lr.x && box.ur.y == box.lr.y) {
-
- Common::Point pt;
- pt = closestPtOnLine(box.ul, box.lr, x, y);
- if (distanceFromPt(x, y, pt.x, pt.y) <= 4)
- return true;
- }
-
- if (!compareSlope(box.ul.x, box.ul.y, box.ur.x, box.ur.y, x, y))
- return false;
-
- if (!compareSlope(box.ur.x, box.ur.y, box.lr.x, box.lr.y, x, y))
- return false;
-
- if (!compareSlope(box.ll.x, box.ll.y, x, y, box.lr.x, box.lr.y))
- return false;
-
- if (!compareSlope(box.ul.x, box.ul.y, x, y, box.ll.x, box.ll.y))
- return false;
-
- return true;
-}
-
-void ScummEngine::getBoxCoordinates(int boxnum, BoxCoords *box) {
- Box *bp = getBoxBaseAddr(boxnum);
- assert(bp);
-
- if (_version == 8) {
- box->ul.x = (short)FROM_LE_32(bp->v8.ulx);
- box->ul.y = (short)FROM_LE_32(bp->v8.uly);
- box->ur.x = (short)FROM_LE_32(bp->v8.urx);
- box->ur.y = (short)FROM_LE_32(bp->v8.ury);
-
- box->ll.x = (short)FROM_LE_32(bp->v8.llx);
- box->ll.y = (short)FROM_LE_32(bp->v8.lly);
- box->lr.x = (short)FROM_LE_32(bp->v8.lrx);
- box->lr.y = (short)FROM_LE_32(bp->v8.lry);
-
- // FIXME: Some walkboxes in CMI appear to have been flipped,
- // in the sense that for instance the lower boundary is above
- // the upper one. Can that really be the case, or is there
- // some more sinister problem afoot?
- //
- // Is this fix sufficient, or will we need something more
- // elaborate?
-
- if (box->ul.y > box->ll.y && box->ur.y > box->lr.y) {
- SWAP(box->ul, box->ll);
- SWAP(box->ur, box->lr);
- }
-
- if (box->ul.x > box->ur.x && box->ll.x > box->lr.x) {
- SWAP(box->ul, box->ur);
- SWAP(box->ll, box->lr);
- }
- } else if (_version <= 2) {
- box->ul.x = bp->v2.ulx * 8;
- box->ul.y = bp->v2.uy * 2;
- box->ur.x = bp->v2.urx * 8;
- box->ur.y = bp->v2.uy * 2;
-
- box->ll.x = bp->v2.llx * 8;
- box->ll.y = bp->v2.ly * 2;
- box->lr.x = bp->v2.lrx * 8;
- box->lr.y = bp->v2.ly * 2;
- } else {
- box->ul.x = (int16)READ_LE_UINT16(&bp->old.ulx);
- box->ul.y = (int16)READ_LE_UINT16(&bp->old.uly);
- box->ur.x = (int16)READ_LE_UINT16(&bp->old.urx);
- box->ur.y = (int16)READ_LE_UINT16(&bp->old.ury);
-
- box->ll.x = (int16)READ_LE_UINT16(&bp->old.llx);
- box->ll.y = (int16)READ_LE_UINT16(&bp->old.lly);
- box->lr.x = (int16)READ_LE_UINT16(&bp->old.lrx);
- box->lr.y = (int16)READ_LE_UINT16(&bp->old.lry);
- }
-}
-
-uint ScummEngine::distanceFromPt(int x, int y, int ptx, int pty) {
- int diffx, diffy;
-
- diffx = ABS(ptx - x);
-
- if (diffx >= 0x1000)
- return 0xFFFFFF;
-
- diffy = ABS(pty - y);
-
- if (diffy >= 0x1000)
- return 0xFFFFFF;
- diffx *= diffx;
- diffy *= diffy;
- return diffx + diffy;
-}
-
-
-bool compareSlope(int X1, int Y1, int X2, int Y2, int X3, int Y3) {
- return (Y2 - Y1) * (X3 - X1) <= (Y3 - Y1) * (X2 - X1);
-}
-
-/**
- * Find the point on a line segment which is closest to a given point.
- *
- * @param start the start of the line segment
- * @param end the end of the line segment
- * @param x the x coordinate of the point which we want to 'project' on the line segment
- * @param y the y coordinate of the point which we want to 'project' on the line segment
- * @return the point on the line segmen closes to the given point
- */
-Common::Point closestPtOnLine(const Common::Point &start, const Common::Point &end, int x, int y) {
- Common::Point pt;
-
- const int lxdiff = end.x - start.x;
- const int lydiff = end.y - start.y;
-
- if (end.x == start.x) { // Vertical line?
- pt.x = start.x;
- pt.y = y;
- } else if (end.y == start.y) { // Horizontal line?
- pt.x = x;
- pt.y = start.y;
- } else {
- const int dist = lxdiff * lxdiff + lydiff * lydiff;
- int a, b, c;
- if (ABS(lxdiff) > ABS(lydiff)) {
- a = start.x * lydiff / lxdiff;
- b = x * lxdiff / lydiff;
-
- c = (a + b - start.y + y) * lydiff * lxdiff / dist;
-
- pt.x = c;
- pt.y = c * lydiff / lxdiff - a + start.y;
- } else {
- a = start.y * lxdiff / lydiff;
- b = y * lydiff / lxdiff;
-
- c = (a + b - start.x + x) * lydiff * lxdiff / dist;
-
- pt.y = c;
- pt.x = c * lxdiff / lydiff - a + start.x;
- }
- }
-
- if (ABS(lydiff) < ABS(lxdiff)) {
- if (lxdiff > 0) {
- if (pt.x < start.x)
- pt = start;
- else if (pt.x > end.x)
- pt = end;
- } else {
- if (pt.x > start.x)
- pt = start;
- else if (pt.x < end.x)
- pt = end;
- }
- } else {
- if (lydiff > 0) {
- if (pt.y < start.y)
- pt = start;
- else if (pt.y > end.y)
- pt = end;
- } else {
- if (pt.y > start.y)
- pt = start;
- else if (pt.y < end.y)
- pt = end;
- }
- }
-
- return pt;
-}
-
-bool ScummEngine::inBoxQuickReject(int b, int x, int y, int threshold) {
- int t;
- BoxCoords box;
-
- getBoxCoordinates(b, &box);
-
- t = x - threshold;
- if (t > box.ul.x && t > box.ur.x && t > box.lr.x && t > box.ll.x)
- return true;
-
- t = x + threshold;
- if (t < box.ul.x && t < box.ur.x && t < box.lr.x && t < box.ll.x)
- return true;
-
- t = y - threshold;
- if (t > box.ul.y && t > box.ur.y && t > box.lr.y && t > box.ll.y)
- return true;
-
- t = y + threshold;
- if (t < box.ul.y && t < box.ur.y && t < box.lr.y && t < box.ll.y)
- return true;
-
- return false;
-}
-
-int ScummEngine::getClosestPtOnBox(int b, int x, int y, int16& outX, int16& outY) {
- Common::Point pt;
- uint dist;
- uint bestdist = 0xFFFFFF;
- BoxCoords box;
-
- getBoxCoordinates(b, &box);
-
- pt = closestPtOnLine(box.ul, box.ur, x, y);
- dist = distanceFromPt(x, y, pt.x, pt.y);
- if (dist < bestdist) {
- bestdist = dist;
- outX = pt.x;
- outY = pt.y;
- }
-
- pt = closestPtOnLine(box.ur, box.lr, x, y);
- dist = distanceFromPt(x, y, pt.x, pt.y);
- if (dist < bestdist) {
- bestdist = dist;
- outX = pt.x;
- outY = pt.y;
- }
-
- pt = closestPtOnLine(box.lr, box.ll, x, y);
- dist = distanceFromPt(x, y, pt.x, pt.y);
- if (dist < bestdist) {
- bestdist = dist;
- outX = pt.x;
- outY = pt.y;
- }
-
- pt = closestPtOnLine(box.ll, box.ul, x, y);
- dist = distanceFromPt(x, y, pt.x, pt.y);
- if (dist < bestdist) {
- bestdist = dist;
- outX = pt.x;
- outY = pt.y;
- }
-
- return bestdist;
-}
-
-byte *ScummEngine::getBoxMatrixBaseAddr() {
- byte *ptr = getResourceAddress(rtMatrix, 1);
- assert(ptr);
- if (*ptr == 0xFF)
- ptr++;
- return ptr;
-}
-
-/*
- * Compute if there is a way that connects box 'from' with box 'to'.
- * Returns the number of a box adjactant to 'from' that is the next on the
- * way to 'to' (this can be 'to' itself or a third box).
- * If there is no connection -1 is return.
- */
-int ScummEngine::getPathToDestBox(byte from, byte to) {
- const byte *boxm;
- byte i;
- const int numOfBoxes = getNumBoxes();
- int dest = -1;
-
- if (from == to)
- return to;
-
- if (to == Actor::kInvalidBox)
- return -1;
-
- if (from == Actor::kInvalidBox)
- return to;
-
- assert(from < numOfBoxes);
- assert(to < numOfBoxes);
-
- boxm = getBoxMatrixBaseAddr();
-
- if (_version <= 2) {
- // The v2 box matrix is a real matrix with numOfBoxes rows and columns.
- // The first numOfBoxes bytes contain indices to the start of the corresponding
- // row (although that seems unnecessary to me - the value is easily computable.
- boxm += numOfBoxes + boxm[from];
- return (int8)boxm[to];
- }
-
- // WORKAROUND #1: It seems that in some cases, the box matrix is corrupt
- // (more precisely, is too short) in the datafiles already. In
- // particular this seems to be the case in room 46 of Indy3 EGA (see
- // also bug #770690). This didn't cause problems in the original
- // engine, because there, the memory layout is different. After the
- // walkbox would follow the rest of the room file, thus the program
- // always behaved the same (and by chance, correct). Not so for us,
- // since random data may follow after the resource in ScummVM.
- //
- // As a workaround, we add a check for the end of the box matrix
- // resource, and abort the search once we reach the end.
- const byte *end = boxm + getResourceSize(rtMatrix, 1);
-
- // WORKAROUND #2: In addition to the above, we have to add this special
- // case to fix the scene in Indy3 where Indy meets Hitler in Berlin.
- // See bug #770690 and also bug #774783.
- if ((_gameId == GID_INDY3) && _roomResource == 46 && from == 1 && to == 0)
- return 0;
-
- // Skip up to the matrix data for box 'from'
- for (i = 0; i < from && boxm < end; i++) {
- while (boxm < end && *boxm != 0xFF)
- boxm += 3;
- boxm++;
- }
-
- // Now search for the entry for box 'to'
- while (boxm < end && boxm[0] != 0xFF) {
- if (boxm[0] <= to && to <= boxm[1])
- dest = (int8)boxm[2];
- boxm += 3;
- }
-
- if (boxm >= end)
- debug(0, "The box matrix apparently is truncated (room %d)", _roomResource);
-
- return dest;
-}
-
-/*
- * Computes the next point actor a has to walk towards in a straight
- * line in order to get from box1 to box3 via box2.
- */
-bool Actor::findPathTowards(byte box1nr, byte box2nr, byte box3nr, Common::Point &foundPath) {
- BoxCoords box1;
- BoxCoords box2;
- Common::Point tmp;
- int i, j;
- int flag;
- int q, pos;
-
- _vm->getBoxCoordinates(box1nr, &box1);
- _vm->getBoxCoordinates(box2nr, &box2);
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- if (box1.ul.x == box1.ur.x && box1.ul.x == box2.ul.x && box1.ul.x == box2.ur.x) {
- flag = 0;
- if (box1.ul.y > box1.ur.y) {
- SWAP(box1.ul.y, box1.ur.y);
- flag |= 1;
- }
-
- if (box2.ul.y > box2.ur.y) {
- SWAP(box2.ul.y, box2.ur.y);
- flag |= 2;
- }
-
- if (box1.ul.y > box2.ur.y || box2.ul.y > box1.ur.y ||
- (box1.ur.y == box2.ul.y || box2.ur.y == box1.ul.y) &&
- box1.ul.y != box1.ur.y && box2.ul.y != box2.ur.y) {
- if (flag & 1)
- SWAP(box1.ul.y, box1.ur.y);
- if (flag & 2)
- SWAP(box2.ul.y, box2.ur.y);
- } else {
- pos = _pos.y;
- if (box2nr == box3nr) {
- int diffX = _walkdata.dest.x - _pos.x;
- int diffY = _walkdata.dest.y - _pos.y;
- int boxDiffX = box1.ul.x - _pos.x;
-
- if (diffX != 0) {
- int t;
-
- diffY *= boxDiffX;
- t = diffY / diffX;
- if (t == 0 && (diffY <= 0 || diffX <= 0)
- && (diffY >= 0 || diffX >= 0))
- t = -1;
- pos = _pos.y + t;
- }
- }
-
- q = pos;
- if (q < box2.ul.y)
- q = box2.ul.y;
- if (q > box2.ur.y)
- q = box2.ur.y;
- if (q < box1.ul.y)
- q = box1.ul.y;
- if (q > box1.ur.y)
- q = box1.ur.y;
- if (q == pos && box2nr == box3nr)
- return true;
- foundPath.y = q;
- foundPath.x = box1.ul.x;
- return false;
- }
- }
-
- if (box1.ul.y == box1.ur.y && box1.ul.y == box2.ul.y && box1.ul.y == box2.ur.y) {
- flag = 0;
- if (box1.ul.x > box1.ur.x) {
- SWAP(box1.ul.x, box1.ur.x);
- flag |= 1;
- }
-
- if (box2.ul.x > box2.ur.x) {
- SWAP(box2.ul.x, box2.ur.x);
- flag |= 2;
- }
-
- if (box1.ul.x > box2.ur.x || box2.ul.x > box1.ur.x ||
- (box1.ur.x == box2.ul.x || box2.ur.x == box1.ul.x) &&
- box1.ul.x != box1.ur.x && box2.ul.x != box2.ur.x) {
- if (flag & 1)
- SWAP(box1.ul.x, box1.ur.x);
- if (flag & 2)
- SWAP(box2.ul.x, box2.ur.x);
- } else {
-
- if (box2nr == box3nr) {
- int diffX = _walkdata.dest.x - _pos.x;
- int diffY = _walkdata.dest.y - _pos.y;
- int boxDiffY = box1.ul.y - _pos.y;
-
- pos = _pos.x;
- if (diffY != 0) {
- pos += diffX * boxDiffY / diffY;
- }
- } else {
- pos = _pos.x;
- }
-
- q = pos;
- if (q < box2.ul.x)
- q = box2.ul.x;
- if (q > box2.ur.x)
- q = box2.ur.x;
- if (q < box1.ul.x)
- q = box1.ul.x;
- if (q > box1.ur.x)
- q = box1.ur.x;
- if (q == pos && box2nr == box3nr)
- return true;
- foundPath.x = q;
- foundPath.y = box1.ul.y;
- return false;
- }
- }
- tmp = box1.ul;
- box1.ul = box1.ur;
- box1.ur = box1.lr;
- box1.lr = box1.ll;
- box1.ll = tmp;
- }
- tmp = box2.ul;
- box2.ul = box2.ur;
- box2.ur = box2.lr;
- box2.lr = box2.ll;
- box2.ll = tmp;
- }
- return false;
-}
-
-#if BOX_DEBUG
-static void printMatrix(byte *boxm, int num) {
- int i;
- for (i = 0; i < num; i++) {
- printf("%d: ", i);
- while (*boxm != 0xFF) {
- printf("%d, ", *boxm);
- boxm++;
- }
- boxm++;
- printf("\n");
- }
-}
-
-static void printMatrix2(byte *matrix, int num) {
- int i, j;
- printf(" ");
- for (i = 0; i < num; i++)
- printf("%2d ", i);
- printf("\n");
- for (i = 0; i < num; i++) {
- printf("%2d: ", i);
- for (j = 0; j < num; j++) {
- int val = matrix[i * 64 + j];
- if (val == Actor::kInvalidBox)
- printf(" ? ");
- else
- printf("%2d ", val);
- }
- printf("\n");
- }
-}
-#endif
-
-void ScummEngine::createBoxMatrix() {
- int num, i, j, k;
- byte *adjacentMatrix, *itineraryMatrix;
-
- // The total number of boxes
- num = getNumBoxes();
- assert(num <= 64);
-
- // Allocate the adjacent & itinerary matrices
- adjacentMatrix = (byte *)malloc(64 * 64);
- itineraryMatrix = (byte *)malloc(64 * 64);
-
- // Initialise the adjacent matrix: each box has distance 0 to itself,
- // and distance 1 to its direct neighbors. Initially, it has distance
- // 255 (= infinity) to all other boxes.
- for (i = 0; i < num; i++) {
- for (j = 0; j < num; j++) {
- if (i == j) {
- adjacentMatrix[i * 64 + j] = 0;
- itineraryMatrix[i * 64 + j] = j;
- } else if (areBoxesNeighbours(i, j)) {
- adjacentMatrix[i * 64 + j] = 1;
- itineraryMatrix[i * 64 + j] = j;
- } else {
- adjacentMatrix[i * 64 + j] = 255;
- itineraryMatrix[i * 64 + j] = Actor::kInvalidBox;
- }
- }
- }
-
- // Compute the shortest routes between boxes via Kleene's algorithm.
- // The original code used some kind of mangled Dijkstra's algorithm;
- // while that might in theory be slightly faster, it was
- // a) extremly obfuscated
- // b) incorrect: it didn't always find the shortest paths
- // c) not any faster in reality for our sparse & small adjacent matrices
- for (k = 0; k < num; k++) {
- for (i = 0; i < num; i++) {
- for (j = 0; j < num; j++) {
- if (i == j)
- continue;
- byte distIK = adjacentMatrix[64 * i + k];
- byte distKJ = adjacentMatrix[64 * k + j];
- if (adjacentMatrix[64 * i + j] > distIK + distKJ) {
- adjacentMatrix[64 * i + j] = distIK + distKJ;
- itineraryMatrix[64 * i + j] = itineraryMatrix[64 * i + k];
- }
- }
- }
-
- }
-
- // "Compress" the distance matrix into the box matrix format used
- // by the engine. The format is like this:
- // For each box (from 0 to num) there is first a byte with value 0xFF,
- // followed by an arbitrary number of byte triples; the end is marked
- // again by the lead 0xFF for the next "row". The meaning of the
- // byte triples is as follows: the first two bytes define a range
- // of box numbers (e.g. 7-11), while the third byte defines an
- // itineray box. Assuming we are in the 5th "row" and encounter
- // the triplet 7,11,15: this means to get from box 5 to any of
- // the boxes 7,8,9,10,11 the shortest way is to go via box 15.
- // See also getPathToDestBox.
-
- byte *matrixStart = res.createResource(rtMatrix, 1, BOX_MATRIX_SIZE);
- const byte *matrixEnd = matrixStart + BOX_MATRIX_SIZE;
-
- #define addToMatrix(b) do { *matrixStart++ = (b); assert(matrixStart < matrixEnd); } while (0)
-
- for (i = 0; i < num; i++) {
- addToMatrix(0xFF);
- for (j = 0; j < num; j++) {
- byte itinerary = itineraryMatrix[64 * i + j];
- if (itinerary != Actor::kInvalidBox) {
- addToMatrix(j);
- while (j < num - 1 && itinerary == itineraryMatrix[64 * i + (j + 1)])
- j++;
- addToMatrix(j);
- addToMatrix(itinerary);
- }
- }
- }
- addToMatrix(0xFF);
-
-
-#if BOX_DEBUG
- printf("Itinerary matrix:\n");
- printMatrix2(itineraryMatrix, num);
- printf("compressed matrix:\n");
- printMatrix(getBoxMatrixBaseAddr(), num);
-#endif
-
- free(adjacentMatrix);
- free(itineraryMatrix);
-}
-
-/** Check if two boxes are neighbours. */
-bool ScummEngine::areBoxesNeighbours(int box1nr, int box2nr) {
- Common::Point tmp;
- BoxCoords box;
- BoxCoords box2;
-
- if (getBoxFlags(box1nr) & kBoxInvisible || getBoxFlags(box2nr) & kBoxInvisible)
- return false;
-
- getBoxCoordinates(box1nr, &box2);
- getBoxCoordinates(box2nr, &box);
-
- // Roughly, the idea of this algorithm is to check if we can find
- // two sides of the two given boxes which touch.
- // In order to keep te code simple, we only match the upper sides;
- // then, we "rotate" the box coordinates four times each, for a total
- // of 16 comparisions (four sides compared with four sides each).
- for (int j = 0; j < 4; j++) {
- for (int k = 0; k < 4; k++) {
- // Are the "upper" sides of the boxes on a single vertical line
- // (i.e. all share one x value) ?
- if (box2.ur.x == box2.ul.x && box.ul.x == box2.ul.x && box.ur.x == box2.ul.x) {
- bool swappedBox2 = false, swappedBox1 = false;
- if (box2.ur.y < box2.ul.y) {
- swappedBox2 = 1;
- SWAP(box2.ur.y, box2.ul.y);
- }
- if (box.ur.y < box.ul.y) {
- swappedBox1 = 1;
- SWAP(box.ur.y, box.ul.y);
- }
- if (box.ur.y < box2.ul.y ||
- box.ul.y > box2.ur.y ||
- (box.ul.y == box2.ur.y ||
- box.ur.y == box2.ul.y) && box2.ur.y != box2.ul.y && box.ul.y != box.ur.y) {
- } else {
- return true;
- }
-
- // Swap back if necessary
- if (swappedBox2) {
- SWAP(box2.ur.y, box2.ul.y);
- }
- if (swappedBox1) {
- SWAP(box.ur.y, box.ul.y);
- }
- }
-
- // Are the "upper" sides of the boxes on a single horizontal line
- // (i.e. all share one y value) ?
- if (box2.ur.y == box2.ul.y && box.ul.y == box2.ul.y && box.ur.y == box2.ul.y) {
- bool swappedBox2 = false, swappedBox1 = false;
- if (box2.ur.x < box2.ul.x) {
- swappedBox2 = 1;
- SWAP(box2.ur.x, box2.ul.x);
- }
- if (box.ur.x < box.ul.x) {
- swappedBox1 = 1;
- SWAP(box.ur.x, box.ul.x);
- }
- if (box.ur.x < box2.ul.x ||
- box.ul.x > box2.ur.x ||
- (box.ul.x == box2.ur.x ||
- box.ur.x == box2.ul.x) && box2.ur.x != box2.ul.x && box.ul.x != box.ur.x) {
-
- } else {
- return true;
- }
-
- // Swap back if necessary
- if (swappedBox2) {
- SWAP(box2.ur.x, box2.ul.x);
- }
- if (swappedBox1) {
- SWAP(box.ur.x, box.ul.x);
- }
- }
-
- // "Rotate" the box coordinates
- tmp = box2.ul;
- box2.ul = box2.ur;
- box2.ur = box2.lr;
- box2.lr = box2.ll;
- box2.ll = tmp;
- }
-
- // "Rotate" the box coordinates
- tmp = box.ul;
- box.ul = box.ur;
- box.ur = box.lr;
- box.lr = box.ll;
- box.ll = tmp;
- }
-
- return false;
-}
-
-void Actor::findPathTowardsOld(byte box1, byte box2, byte finalBox, Common::Point &p2, Common::Point &p3) {
- Common::Point pt;
- Common::Point gateA[2];
- Common::Point gateB[2];
-
- _vm->getGates(box1, box2, gateA, gateB);
-
- p2.x = 32000;
- p3.x = 32000;
-
- // next box (box2) = final box?
- if (box2 == finalBox) {
- // In Indy3, the masks (= z-level) have to match, too -- needed for the
- // 'maze' in the zeppeling (see bug #1032964).
- if (_vm->_gameId != GID_INDY3 || _vm->getMaskFromBox(box1) == _vm->getMaskFromBox(box2)) {
- // Is the actor (x,y) between both gates?
- if (compareSlope(_pos.x, _pos.y, _walkdata.dest.x, _walkdata.dest.y, gateA[0].x, gateA[0].y) !=
- compareSlope(_pos.x, _pos.y, _walkdata.dest.x, _walkdata.dest.y, gateB[0].x, gateB[0].y) &&
- compareSlope(_pos.x, _pos.y, _walkdata.dest.x, _walkdata.dest.y, gateA[1].x, gateA[1].y) !=
- compareSlope(_pos.x, _pos.y, _walkdata.dest.x, _walkdata.dest.y, gateB[1].x, gateB[1].y)) {
- return;
- }
- }
- }
-
- p3 = pt = closestPtOnLine(gateA[1], gateB[1], _pos.x, _pos.y);
-
- if (compareSlope(_pos.x, _pos.y, p3.x, p3.y, gateA[0].x, gateA[0].y) ==
- compareSlope(_pos.x, _pos.y, p3.x, p3.y, gateB[0].x, gateB[0].y)) {
- closestPtOnLine(gateA[0], gateB[0], _pos.x, _pos.y);
- p2 = pt; // if point 2 between gates, ignore!
- }
-}
-
-/**
- * Compute the "gate" between two boxes. The gate is a pair of two lines which
- * both start on box 'box1' and end on 'box2'. For both lines, one of its
- * end points is the corner point of one of the two boxes. The other end point
- * is a point on the other point closest to first end point.
- * This way the lines bound a 'corridor' between the two boxes, through which
- * the actor has to walk to get from box1 to box2.
- */
-void ScummEngine::getGates(int box1, int box2, Common::Point gateA[2], Common::Point gateB[2]) {
- int i, j;
- int dist[8];
- int minDist[3];
- int closest[3];
- int box[3];
- BoxCoords coords;
- Common::Point closestPoint[8];
- Common::Point boxCorner[8];
- int line1, line2;
-
- // For all corner coordinates of the first box, compute the point closest
- // to them on the second box (and also compute the distance of these points).
- getBoxCoordinates(box1, &coords);
- boxCorner[0] = coords.ul;
- boxCorner[1] = coords.ur;
- boxCorner[2] = coords.lr;
- boxCorner[3] = coords.ll;
- for (i = 0; i < 4; i++) {
- dist[i] = getClosestPtOnBox(box2, boxCorner[i].x, boxCorner[i].y, closestPoint[i].x, closestPoint[i].y);
- }
-
- // Now do the same but with the roles of the first and second box swapped.
- getBoxCoordinates(box2, &coords);
- boxCorner[4] = coords.ul;
- boxCorner[5] = coords.ur;
- boxCorner[6] = coords.lr;
- boxCorner[7] = coords.ll;
- for (i = 4; i < 8; i++) {
- dist[i] = getClosestPtOnBox(box1, boxCorner[i].x, boxCorner[i].y, closestPoint[i].x, closestPoint[i].y);
- }
-
- // Find the three closest "close" points between the two boxes.
- for (j = 0; j < 3; j++) {
- minDist[j] = 0xFFFF;
- for (i = 0; i < 8; i++) {
- if (dist[i] < minDist[j]) {
- minDist[j] = dist[i];
- closest[j] = i;
- }
- }
- dist[closest[j]] = 0xFFFF;
- minDist[j] = (int)sqrt((double)minDist[j]);
- box[j] = (closest[j] > 3); // Is the point on the first or on the second box?
- }
-
-
- // Finally, compute the actual "gate".
-
- if (box[0] == box[1] && ABS(minDist[0] - minDist[1]) < 4) {
- line1 = closest[0];
- line2 = closest[1];
-
- } else if (box[0] == box[1] && minDist[0] == minDist[1]) { // parallel
- line1 = closest[0];
- line2 = closest[1];
- } else if (box[0] == box[2] && minDist[0] == minDist[2]) { // parallel
- line1 = closest[0];
- line2 = closest[2];
- } else if (box[1] == box[2] && minDist[1] == minDist[2]) { // parallel
- line1 = closest[1];
- line2 = closest[2];
-
- } else if (box[0] == box[2] && ABS(minDist[0] - minDist[2]) < 4) {
- line1 = closest[0];
- line2 = closest[2];
- } else if (ABS(minDist[0] - minDist[2]) < 4) {
- line1 = closest[1];
- line2 = closest[2];
- } else if (ABS(minDist[0] - minDist[1]) < 4) {
- line1 = closest[0];
- line2 = closest[1];
- } else {
- line1 = closest[0];
- line2 = closest[0];
- }
-
- // Set the gate
- if (line1 < 4) {
- gateA[0] = boxCorner[line1];
- gateA[1] = closestPoint[line1];
- } else {
- gateA[1] = boxCorner[line1];
- gateA[0] = closestPoint[line1];
- }
-
- if (line2 < 4) {
- gateB[0] = boxCorner[line2];
- gateB[1] = closestPoint[line2];
- } else {
- gateB[1] = boxCorner[line2];
- gateB[0] = closestPoint[line2];
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/boxes.h b/scumm/boxes.h
deleted file mode 100644
index f5fb7160fd..0000000000
--- a/scumm/boxes.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef BOXES_H
-#define BOXES_H
-
-#include "common/rect.h"
-
-namespace Scumm {
-
-#define SIZEOF_BOX_V2 8
-#define SIZEOF_BOX_V3 18
-#define SIZEOF_BOX 20
-#define SIZEOF_BOX_V8 52
-
-typedef enum {
- kBoxXFlip = 0x08,
- kBoxYFlip = 0x10,
- kBoxIgnoreScale = 0x20,
- kBoxPlayerOnly = 0x20,
- kBoxLocked = 0x40,
- kBoxInvisible = 0x80
-} BoxFlags;
-
-struct BoxCoords { /* Box coordinates */
- Common::Point ul;
- Common::Point ur;
- Common::Point ll;
- Common::Point lr;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/camera.cpp b/scumm/camera.cpp
deleted file mode 100644
index cc6d9bfaed..0000000000
--- a/scumm/camera.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/intern.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-
-namespace Scumm {
-
-void ScummEngine::setCameraAtEx(int at) {
- if (!(_features & GF_NEW_CAMERA)) {
- camera._mode = kNormalCameraMode;
- camera._cur.x = at;
- setCameraAt(at, 0);
- camera._movingToActor = false;
- }
-}
-
-void ScummEngine::setCameraAt(int pos_x, int pos_y) {
- if (camera._mode != kFollowActorCameraMode || ABS(pos_x - camera._cur.x) > (_screenWidth / 2)) {
- camera._cur.x = pos_x;
- }
- camera._dest.x = pos_x;
-
- if (camera._cur.x < VAR(VAR_CAMERA_MIN_X))
- camera._cur.x = (short) VAR(VAR_CAMERA_MIN_X);
-
- if (camera._cur.x > VAR(VAR_CAMERA_MAX_X))
- camera._cur.x = (short) VAR(VAR_CAMERA_MAX_X);
-
- if (VAR_SCROLL_SCRIPT != 0xFF && VAR(VAR_SCROLL_SCRIPT)) {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x;
- runScript(VAR(VAR_SCROLL_SCRIPT), 0, 0, 0);
- }
-
- // If the camera moved and text is visible, remove it
- if (camera._cur.x != camera._last.x && _charset->_hasMask && _version > 3)
- stopTalk();
-}
-
-void ScummEngine::setCameraFollows(Actor *a) {
-
- int t, i;
-
- camera._mode = kFollowActorCameraMode;
- camera._follows = a->_number;
-
- if (!a->isInCurrentRoom()) {
- startScene(a->getRoom(), 0, 0);
- camera._mode = kFollowActorCameraMode;
- camera._cur.x = a->_pos.x;
- setCameraAt(camera._cur.x, 0);
- }
-
- t = a->_pos.x / 8 - _screenStartStrip;
-
- if (t < camera._leftTrigger || t > camera._rightTrigger)
- setCameraAt(a->_pos.x, 0);
-
- for (i = 1; i < _numActors; i++) {
- if (_actors[i].isInCurrentRoom())
- _actors[i]._needRedraw = true;
- }
- runInventoryScript(0);
-}
-
-void ScummEngine::clampCameraPos(Common::Point *pt) {
- if (pt->x < VAR(VAR_CAMERA_MIN_X))
- pt->x = (short) VAR(VAR_CAMERA_MIN_X);
-
- if (pt->x > VAR(VAR_CAMERA_MAX_X))
- pt->x = (short) VAR(VAR_CAMERA_MAX_X);
-
- if (pt->y < VAR(VAR_CAMERA_MIN_Y))
- pt->y = (short) VAR(VAR_CAMERA_MIN_Y);
-
- if (pt->y > VAR(VAR_CAMERA_MAX_Y))
- pt->y = (short) VAR(VAR_CAMERA_MAX_Y);
-}
-
-void ScummEngine::moveCamera() {
- int pos = camera._cur.x;
- int actorx, t;
- Actor *a = NULL;
-
- camera._cur.x &= 0xFFF8;
-
- if (camera._cur.x < VAR(VAR_CAMERA_MIN_X)) {
- if (VAR_CAMERA_FAST_X != 0xFF && VAR(VAR_CAMERA_FAST_X))
- camera._cur.x = (short) VAR(VAR_CAMERA_MIN_X);
- else
- camera._cur.x += 8;
- cameraMoved();
- return;
- }
-
- if (camera._cur.x > VAR(VAR_CAMERA_MAX_X)) {
- if (VAR_CAMERA_FAST_X != 0xFF && VAR(VAR_CAMERA_FAST_X))
- camera._cur.x = (short) VAR(VAR_CAMERA_MAX_X);
- else
- camera._cur.x -= 8;
- cameraMoved();
- return;
- }
-
- if (camera._mode == kFollowActorCameraMode) {
- a = derefActor(camera._follows, "moveCamera");
-
- actorx = a->_pos.x;
- t = actorx / 8 - _screenStartStrip;
-
- if (t < camera._leftTrigger || t > camera._rightTrigger) {
- if (VAR_CAMERA_FAST_X != 0xFF && VAR(VAR_CAMERA_FAST_X)) {
- if (t > 35)
- camera._dest.x = actorx + 80;
- if (t < 5)
- camera._dest.x = actorx - 80;
- } else
- camera._movingToActor = true;
- }
- }
-
- if (camera._movingToActor) {
- a = derefActor(camera._follows, "moveCamera(2)");
- camera._dest.x = a->_pos.x;
- }
-
- if (camera._dest.x < VAR(VAR_CAMERA_MIN_X))
- camera._dest.x = (short) VAR(VAR_CAMERA_MIN_X);
-
- if (camera._dest.x > VAR(VAR_CAMERA_MAX_X))
- camera._dest.x = (short) VAR(VAR_CAMERA_MAX_X);
-
- if (VAR_CAMERA_FAST_X != 0xFF && VAR(VAR_CAMERA_FAST_X)) {
- camera._cur.x = camera._dest.x;
- } else {
- if (camera._cur.x < camera._dest.x)
- camera._cur.x += 8;
- if (camera._cur.x > camera._dest.x)
- camera._cur.x -= 8;
- }
-
- /* a is set a bit above */
- if (camera._movingToActor && (camera._cur.x / 8) == (a->_pos.x / 8)) {
- camera._movingToActor = false;
- }
-
- cameraMoved();
-
- if (VAR_SCROLL_SCRIPT != 0xFF && VAR(VAR_SCROLL_SCRIPT) && pos != camera._cur.x) {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x;
- runScript(VAR(VAR_SCROLL_SCRIPT), 0, 0, 0);
- }
-}
-
-void ScummEngine::cameraMoved() {
- int screenLeft;
- if (_features & GF_NEW_CAMERA) {
- assert(camera._cur.x >= (_screenWidth / 2) && camera._cur.y >= (_screenHeight / 2));
- } else {
- if (camera._cur.x < (_screenWidth / 2)) {
- camera._cur.x = (_screenWidth / 2);
- } else if (camera._cur.x > _roomWidth - (_screenWidth / 2)) {
- camera._cur.x = _roomWidth - (_screenWidth / 2);
- }
- }
-
- _screenStartStrip = camera._cur.x / 8 - gdi._numStrips / 2;
- _screenEndStrip = _screenStartStrip + gdi._numStrips - 1;
-
- _screenTop = camera._cur.y - (_screenHeight / 2);
- if (_features & GF_NEW_CAMERA) {
- screenLeft = camera._cur.x - (_screenWidth / 2);
- } else {
- screenLeft = _screenStartStrip * 8;
- }
-
- virtscr[0].xstart = screenLeft;
-}
-
-void ScummEngine::panCameraTo(int x, int y) {
- camera._dest.x = x;
- camera._mode = kPanningCameraMode;
- camera._movingToActor = false;
-}
-
-void ScummEngine::actorFollowCamera(int act) {
- if (!(_features & GF_NEW_CAMERA)) {
- int old;
-
- old = camera._follows;
- setCameraFollows(derefActor(act, "actorFollowCamera"));
- if (camera._follows != old)
- runInventoryScript(0);
-
- camera._movingToActor = false;
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::setCameraAt(int pos_x, int pos_y) {
- Common::Point old;
-
- old = camera._cur;
-
- camera._cur.x = pos_x;
- camera._cur.y = pos_y;
-
- clampCameraPos(&camera._cur);
-
- camera._dest = camera._cur;
- VAR(VAR_CAMERA_DEST_X) = camera._dest.x;
- VAR(VAR_CAMERA_DEST_Y) = camera._dest.y;
-
- assert(camera._cur.x >= (_screenWidth / 2) && camera._cur.y >= (_screenHeight / 2));
-
- if (camera._cur.x != old.x || camera._cur.y != old.y) {
- if (VAR(VAR_SCROLL_SCRIPT)) {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x;
- VAR(VAR_CAMERA_POS_Y) = camera._cur.y;
- runScript(VAR(VAR_SCROLL_SCRIPT), 0, 0, 0);
- }
-
- // Even though cameraMoved() is called automatically, we may
- // need to know at once that the camera has moved, or text may
- // be printed at the wrong coordinates. See bugs #795938 and
- // #929242
- cameraMoved();
- }
-}
-
-void ScummEngine_v7::setCameraFollows(Actor *a) {
-
- byte oldfollow = camera._follows;
- int ax, ay;
-
- camera._follows = a->_number;
- VAR(VAR_CAMERA_FOLLOWED_ACTOR) = a->_number;
-
- if (!a->isInCurrentRoom()) {
- startScene(a->getRoom(), 0, 0);
- }
-
- ax = ABS(a->_pos.x - camera._cur.x);
- ay = ABS(a->_pos.y - camera._cur.y);
-
- if (ax > VAR(VAR_CAMERA_THRESHOLD_X) || ay > VAR(VAR_CAMERA_THRESHOLD_Y) || ax > (_screenWidth / 2) || ay > (_screenHeight / 2)) {
- setCameraAt(a->_pos.x, a->_pos.y);
- }
-
- if (a->_number != oldfollow)
- runInventoryScript(0);
-}
-
-void ScummEngine_v7::moveCamera() {
- Common::Point old = camera._cur;
- Actor *a = NULL;
-
- if (camera._follows) {
- a = derefActor(camera._follows, "moveCamera");
- if (ABS(camera._cur.x - a->_pos.x) > VAR(VAR_CAMERA_THRESHOLD_X) ||
- ABS(camera._cur.y - a->_pos.y) > VAR(VAR_CAMERA_THRESHOLD_Y)) {
- camera._movingToActor = true;
- if (VAR(VAR_CAMERA_THRESHOLD_X) == 0)
- camera._cur.x = a->_pos.x;
- if (VAR(VAR_CAMERA_THRESHOLD_Y) == 0)
- camera._cur.y = a->_pos.y;
- clampCameraPos(&camera._cur);
- }
- } else {
- camera._movingToActor = false;
- }
-
- if (camera._movingToActor) {
- VAR(VAR_CAMERA_DEST_X) = camera._dest.x = a->_pos.x;
- VAR(VAR_CAMERA_DEST_Y) = camera._dest.y = a->_pos.y;
- }
-
- assert(camera._cur.x >= (_screenWidth / 2) && camera._cur.y >= (_screenHeight / 2));
-
- clampCameraPos(&camera._dest);
-
- if (camera._cur.x < camera._dest.x) {
- camera._cur.x += (short) VAR(VAR_CAMERA_SPEED_X);
- if (camera._cur.x > camera._dest.x)
- camera._cur.x = camera._dest.x;
- }
-
- if (camera._cur.x > camera._dest.x) {
- camera._cur.x -= (short) VAR(VAR_CAMERA_SPEED_X);
- if (camera._cur.x < camera._dest.x)
- camera._cur.x = camera._dest.x;
- }
-
- if (camera._cur.y < camera._dest.y) {
- camera._cur.y += (short) VAR(VAR_CAMERA_SPEED_Y);
- if (camera._cur.y > camera._dest.y)
- camera._cur.y = camera._dest.y;
- }
-
- if (camera._cur.y > camera._dest.y) {
- camera._cur.y -= (short) VAR(VAR_CAMERA_SPEED_Y);
- if (camera._cur.y < camera._dest.y)
- camera._cur.y = camera._dest.y;
- }
-
- if (camera._cur.x == camera._dest.x && camera._cur.y == camera._dest.y) {
-
- camera._movingToActor = false;
- camera._accel.x = camera._accel.y = 0;
- VAR(VAR_CAMERA_SPEED_X) = VAR(VAR_CAMERA_SPEED_Y) = 0;
- } else {
-
- camera._accel.x += (short) VAR(VAR_CAMERA_ACCEL_X);
- camera._accel.y += (short) VAR(VAR_CAMERA_ACCEL_Y);
-
- VAR(VAR_CAMERA_SPEED_X) += camera._accel.x / 100;
- VAR(VAR_CAMERA_SPEED_Y) += camera._accel.y / 100;
-
- if (VAR(VAR_CAMERA_SPEED_X) < 8)
- VAR(VAR_CAMERA_SPEED_X) = 8;
-
- if (VAR(VAR_CAMERA_SPEED_Y) < 8)
- VAR(VAR_CAMERA_SPEED_Y) = 8;
-
- }
-
- cameraMoved();
-
- if (camera._cur.x != old.x || camera._cur.y != old.y) {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x;
- VAR(VAR_CAMERA_POS_Y) = camera._cur.y;
-
- if (VAR(VAR_SCROLL_SCRIPT))
- runScript(VAR(VAR_SCROLL_SCRIPT), 0, 0, 0);
- }
-}
-
-void ScummEngine_v7::panCameraTo(int x, int y) {
- VAR(VAR_CAMERA_FOLLOWED_ACTOR) = camera._follows = 0;
- VAR(VAR_CAMERA_DEST_X) = camera._dest.x = x;
- VAR(VAR_CAMERA_DEST_Y) = camera._dest.y = y;
-}
-#endif
-
-} // End of namespace Scumm
diff --git a/scumm/charset.cpp b/scumm/charset.cpp
deleted file mode 100644
index e8086ed30a..0000000000
--- a/scumm/charset.cpp
+++ /dev/null
@@ -1,1827 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "scumm/charset.h"
-#include "scumm/scumm.h"
-#include "scumm/nut_renderer.h"
-#include "scumm/util.h"
-#include "scumm/wiz_he.h"
-
-namespace Scumm {
-
-void ScummEngine::loadCJKFont() {
- Common::File fp;
- _useCJKMode = false;
- if (_language == Common::JA_JPN && _version <= 5) { // FM-TOWNS v3 / v5 Kanji
- int numChar = 256 * 32;
- _2byteWidth = 16;
- _2byteHeight = 16;
- // use FM-TOWNS font rom, since game files don't have kanji font resources
- if (fp.open("fmt_fnt.rom", Common::File::kFileReadMode)) {
- _useCJKMode = true;
- debug(2, "Loading FM-TOWNS Kanji rom");
- _2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
- fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
- fp.close();
- }
- } else if (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN) {
- int numChar = 0;
- const char *fontFile = NULL;
-
- switch (_language) {
- case Common::KO_KOR:
- fontFile = "korean.fnt";
- numChar = 2350;
- break;
- case Common::JA_JPN:
- fontFile = (_gameId == GID_DIG) ? "kanji16.fnt" : "japanese.fnt";
- numChar = 1024; //FIXME
- break;
- case Common::ZH_TWN:
- if (_gameId == GID_CMI) {
- fontFile = "chinese.fnt";
- numChar = 1; //FIXME
- }
- break;
- default:
- break;
- }
- if (fontFile && fp.open(fontFile)) {
- debug(2, "Loading CJK Font");
- _useCJKMode = true;
- fp.seek(2, SEEK_CUR);
- _2byteWidth = fp.readByte();
- _2byteHeight = fp.readByte();
-
- _2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
- fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
- fp.close();
- } else {
- error("Couldn't load any font");
- }
- }
-}
-
-static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offset
- enum {
- KANA = 0,
- KANJI = 1,
- EKANJI = 2
- };
- int base = s - ((s + 1) % 32);
- int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA;
-
- if (f >= 0x81 && f <= 0x84) kanjiType = KANA;
- if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI;
- if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;
-
- if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
- c = 48; //correction
- p = -8; //correction
- }
-
- if (kanjiType == KANA) {//Kana
- chunk_f = (f - 0x81) * 2;
- } else if (kanjiType == KANJI) {//Standard Kanji
- p += f - 0x88;
- chunk_f = c + 2 * p;
- } else if (kanjiType == EKANJI) {//Enhanced Kanji
- p += f - 0xe0;
- chunk_f = c + 2 * p;
- }
-
- // Base corrections
- if (base == 0x7f && s == 0x7f)
- base -= 0x20;
- if (base == 0x9f && s == 0xbe)
- base += 0x20;
- if (base == 0xbf && s == 0xde)
- base += 0x20;
- //if (base == 0x7f && s == 0x9e)
- // base += 0x20;
-
- switch (base) {
- case 0x3f:
- cr = 0; //3f
- if (kanjiType == KANA) chunk = 1;
- else if (kanjiType == KANJI) chunk = 31;
- else if (kanjiType == EKANJI) chunk = 111;
- break;
- case 0x5f:
- cr = 0; //5f
- if (kanjiType == KANA) chunk = 17;
- else if (kanjiType == KANJI) chunk = 47;
- else if (kanjiType == EKANJI) chunk = 127;
- break;
- case 0x7f:
- cr = -1; //80
- if (kanjiType == KANA) chunk = 9;
- else if (kanjiType == KANJI) chunk = 63;
- else if (kanjiType == EKANJI) chunk = 143;
- break;
- case 0x9f:
- cr = 1; //9e
- if (kanjiType == KANA) chunk = 2;
- else if (kanjiType == KANJI) chunk = 32;
- else if (kanjiType == EKANJI) chunk = 112;
- break;
- case 0xbf:
- cr = 1; //be
- if (kanjiType == KANA) chunk = 18;
- else if (kanjiType == KANJI) chunk = 48;
- else if (kanjiType == EKANJI) chunk = 128;
- break;
- case 0xdf:
- cr = 1; //de
- if (kanjiType == KANA) chunk = 10;
- else if (kanjiType == KANJI) chunk = 64;
- else if (kanjiType == EKANJI) chunk = 144;
- break;
- default:
- debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
- return 0;
- }
-
- debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
- return ((chunk_f + chunk) * 32 + (s - base)) + cr;
-}
-
-byte *ScummEngine::get2byteCharPtr(int idx) {
- switch (_language) {
- case Common::KO_KOR:
- idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
- break;
- case Common::JA_JPN:
- idx = SJIStoFMTChunk((idx % 256), (idx / 256));
- break;
- case Common::ZH_TWN:
- default:
- idx = 0;
- }
- return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
-}
-
-
-#pragma mark -
-
-
-CharsetRenderer::CharsetRenderer(ScummEngine *vm) {
-
- _nextLeft = 0;
- _nextTop = 0;
-
- _top = 0;
- _left = 0;
- _startLeft = 0;
- _right = 0;
-
- _color = 0;
-
- _center = false;
- _hasMask = false;
- _textScreenID = kMainVirtScreen;
- _blitAlso = false;
- _firstChar = false;
- _disableOffsX = false;
-
- _vm = vm;
- _curId = 0;
-
- const int size = _vm->_screenWidth * _vm->_screenHeight;
- _textSurface.pixels = malloc(size);
- _textSurface.w = _vm->_screenWidth;
- _textSurface.h = _vm->_screenHeight;
- _textSurface.pitch = _vm->_screenWidth;
- _textSurface.bytesPerPixel = 1;
- clearTextSurface();
-}
-
-CharsetRenderer::~CharsetRenderer() {
- free(_textSurface.pixels);
-}
-
-CharsetRendererCommon::CharsetRendererCommon(ScummEngine *vm)
- : CharsetRenderer(vm), _bitDepth(0), _fontHeight(0), _numChars(0) {
- _shadowMode = kNoShadowMode;
- _shadowColor = 0;
-}
-
-void CharsetRendererCommon::setCurID(byte id) {
- checkRange(_vm->_numCharsets - 1, 0, id, "Printing with bad charset %d");
-
- _curId = id;
-
- _fontPtr = _vm->getResourceAddress(rtCharset, id);
- if (_fontPtr == 0)
- error("CharsetRendererCommon::setCurID: charset %d not found!", id);
-
- if (_vm->_version == 4)
- _fontPtr += 17;
- else
- _fontPtr += 29;
-
- _bitDepth = _fontPtr[0];
- _fontHeight = _fontPtr[1];
- _numChars = READ_LE_UINT16(_fontPtr + 2);
-}
-
-void CharsetRendererV3::setCurID(byte id) {
- checkRange(_vm->_numCharsets - 1, 0, id, "Printing with bad charset %d");
-
- _curId = id;
-
- _fontPtr = _vm->getResourceAddress(rtCharset, id);
- if (_fontPtr == 0)
- error("CharsetRendererCommon::setCurID: charset %d not found!", id);
-
- _bitDepth = 1;
- _numChars = _fontPtr[4];
- _fontHeight = _fontPtr[5];
-
- _fontPtr += 6;
- _widthTable = _fontPtr;
- _fontPtr += _numChars;
-}
-
-int CharsetRendererCommon::getFontHeight() {
- if (_vm->_useCJKMode)
- return MAX(_vm->_2byteHeight + 1, _fontHeight);
- else
- return _fontHeight;
-}
-
-int CharsetRendererV3::getFontHeight() {
- if (_vm->_useCJKMode)
- return MAX(_vm->_2byteHeight + 1, _fontHeight);
- else
- return _fontHeight;
-}
-
-// do spacing for variable width old-style font
-int CharsetRendererClassic::getCharWidth(byte chr) {
- if (chr >= 0x80 && _vm->_useCJKMode)
- return _vm->_2byteWidth / 2;
- int spacing = 0;
-
- int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
- if (offs) {
- spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2];
- }
-
- return spacing;
-}
-
-int CharsetRenderer::getStringWidth(int arg, const byte *text) {
- int pos = 0;
- int width = 1;
- byte chr;
- int oldID = getCurID();
- int code = (_vm->_heversion >= 80) ? 127 : 64;
-
- while ((chr = text[pos++]) != 0) {
- if (chr == '\n' || chr == '\r')
- break;
- if (_vm->_heversion >= 72) {
- if (chr == code) {
- chr = text[pos++];
- if (chr == 84 || chr == 116) { // Strings of speech offset/size
- while (chr != code)
- chr = text[pos++];
- continue;
- }
- if (chr == 119) // 'Wait'
- break;
- if (chr == 104|| chr == 110) // 'Newline'
- break;
- }
- } else {
- if (chr == '@')
- continue;
- if (chr == 255 || (_vm->_version <= 6 && chr == 254)) {
- chr = text[pos++];
- if (chr == 3) // 'WAIT'
- break;
- if (chr == 8) { // 'Verb on next line'
- if (arg == 1)
- break;
- while (text[pos++] == ' ')
- ;
- continue;
- }
- if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
- pos += 2;
- continue;
- }
- if (chr == 9 || chr == 1 || chr == 2) // 'Newline'
- break;
- if (chr == 14) {
- int set = text[pos] | (text[pos + 1] << 8);
- pos += 2;
- setCurID(set);
- continue;
- }
- }
- }
- if ((chr & 0x80) && _vm->_useCJKMode) {
- pos++;
- width += _vm->_2byteWidth;
- } else {
- width += getCharWidth(chr);
- }
- }
-
- setCurID(oldID);
-
- return width;
-}
-
-void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
- int lastspace = -1;
- int curw = 1;
- byte chr;
- int oldID = getCurID();
- int code = (_vm->_heversion >= 80) ? 127 : 64;
-
- while ((chr = str[pos++]) != 0) {
- if (_vm->_heversion >= 72) {
- if (chr == code) {
- chr = str[pos++];
- if (chr == 84 || chr == 116) { // Strings of speech offset/size
- while (chr != code)
- chr = str[pos++];
- continue;
- }
- if (chr == 119) // 'Wait'
- break;
- if (chr == 110) { // 'Newline'
- curw = 1;
- continue;
- }
- if (chr == 104) // 'Don't terminate with \n'
- break;
- }
- } else {
- if (chr == '@')
- continue;
- if (chr == 255 || (_vm->_version <= 6 && chr == 254)) {
- chr = str[pos++];
- if (chr == 3) // 'Wait'
- break;
- if (chr == 8) { // 'Verb on next line'
- if (a == 1) {
- curw = 1;
- } else {
- while (str[pos] == ' ')
- str[pos++] = '@';
- }
- continue;
- }
- if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
- pos += 2;
- continue;
- }
- if (chr == 1) { // 'Newline'
- curw = 1;
- continue;
- }
- if (chr == 2) // 'Don't terminate with \n'
- break;
- if (chr == 14) {
- int set = str[pos] | (str[pos + 1] << 8);
- pos += 2;
- setCurID(set);
- continue;
- }
- }
- }
- if (chr == ' ')
- lastspace = pos - 1;
-
- if ((chr & 0x80) && _vm->_useCJKMode) {
- pos++;
- curw += _vm->_2byteWidth;
- } else {
- curw += getCharWidth(chr);
- }
- if (lastspace == -1)
- continue;
- if (curw > maxwidth) {
- str[lastspace] = 0xD;
- curw = 1;
- pos = lastspace + 1;
- lastspace = -1;
- }
- }
-
- setCurID(oldID);
-}
-
-#ifdef PALMOS_68K
-static byte *englishCharsetDataV2;
-static byte *germanCharsetDataV2;
-static byte *frenchCharsetDataV2;
-static byte *italianCharsetDataV2;
-static byte *spanishCharsetDataV2;
-#else
-// English Zak font
-static byte englishCharsetDataV2[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x06, 0x0C, 0x18, 0x3E, 0x03, 0x00,
- 0x80, 0xC0, 0x60, 0x30, 0x18, 0x7C, 0xC0, 0x00,
- 0x00, 0x03, 0x3E, 0x18, 0x0C, 0x06, 0x03, 0x01,
- 0x00, 0xC0, 0x7C, 0x18, 0x30, 0x60, 0xC0, 0x80,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x1F, 0x7F,
- 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0,
- 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18,
- 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x18,
- 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
- 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xF8, 0xF8, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1F, 0x1F, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x07, 0x0C, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x30, 0x18, 0x18,
- 0x18, 0x18, 0x30, 0xE0, 0xC0, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x0C, 0x07, 0x03, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1F, 0x1F, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xF8, 0xF8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
- 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0x66, 0x3C, 0x18,
- 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18,
- 0x18, 0x66, 0xC3, 0xDB, 0xDB, 0xC3, 0x66, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, 0x00,
- 0x18, 0x3E, 0x58, 0x3C, 0x1A, 0x7C, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x49, 0x00,
- 0x3C, 0x66, 0x3C, 0x38, 0x67, 0x66, 0x3F, 0x00,
- 0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00,
- 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00,
- 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00,
- 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
- 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7E, 0x00,
- 0x3C, 0x66, 0x06, 0x0C, 0x30, 0x60, 0x7E, 0x00,
- 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00,
- 0x06, 0x0E, 0x1E, 0x66, 0x7F, 0x06, 0x06, 0x00,
- 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00,
- 0x3C, 0x66, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00,
- 0x7E, 0x66, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00,
- 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x0E, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0E, 0x00,
- 0x7C, 0x82, 0xBA, 0xA2, 0xBA, 0x82, 0x7C, 0x00,
- 0x70, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x70, 0x00,
- 0x3C, 0x66, 0x06, 0x0C, 0x18, 0x00, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
- 0x18, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
- 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
- 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00,
- 0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00,
- 0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7E, 0x00,
- 0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
- 0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00,
- 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
- 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
- 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00,
- 0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00,
- 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00,
- 0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x63, 0x00,
- 0x66, 0x76, 0x7E, 0x7E, 0x6E, 0x66, 0x66, 0x00,
- 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
- 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00,
- 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x0E, 0x00,
- 0x7C, 0x66, 0x66, 0x7C, 0x78, 0x6C, 0x66, 0x00,
- 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00,
- 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00,
- 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00,
- 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00,
- 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
- 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00,
- 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
- 0x0C, 0x12, 0x30, 0x7C, 0x30, 0x62, 0xFC, 0x00,
- 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0x00,
- 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00,
- 0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
- 0x00, 0x00, 0x3C, 0x60, 0x60, 0x60, 0x3C, 0x00,
- 0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00,
- 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
- 0x00, 0x0E, 0x18, 0x3E, 0x18, 0x18, 0x18, 0x00,
- 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x7C,
- 0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00,
- 0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3C,
- 0x00, 0x60, 0x60, 0x6C, 0x78, 0x6C, 0x66, 0x00,
- 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
- 0x00, 0x00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0x00,
- 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
- 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60,
- 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06,
- 0x00, 0x00, 0x7C, 0x66, 0x60, 0x60, 0x60, 0x00,
- 0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00,
- 0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x0E, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00,
- 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x3E, 0x36, 0x00,
- 0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x0C, 0x78,
- 0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00,
- 0x01, 0x03, 0x06, 0x6C, 0x78, 0x70, 0x60, 0x00,
- 0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0xFF, 0x7E, 0x3C, 0x18,
- 0x10, 0x30, 0x70, 0xFF, 0xFF, 0x70, 0x30, 0x10,
- 0x08, 0x0C, 0x0E, 0xFF, 0xFF, 0x0E, 0x0C, 0x08,
-};
-
-// German Zak font
-static byte germanCharsetDataV2[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
- 0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
- 0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
- 0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
- 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
- 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
- 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
- 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
- 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
- 0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
- 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
- 0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
- 0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
- 0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
- 0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
- 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
- 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
- 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
- 0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
- 0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
- 0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x0e, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0e, 0x00,
- 0x7c, 0x82, 0xba, 0xa2, 0xa2, 0xba, 0x82, 0x7c,
- 0x70, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x70, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
- 0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
- 0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
- 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
- 0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
- 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
- 0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
- 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
- 0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
- 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
- 0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
- 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
- 0x00, 0x10, 0x30, 0x7f, 0x7f, 0x30, 0x10, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
- 0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
- 0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
- 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
- 0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
- 0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
- 0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
- 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
- 0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
- 0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x00,
- 0x42, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x1c, 0x36, 0x36, 0x7c, 0x66, 0x66, 0x7c, 0x40,
- 0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
-};
-
-// French Zak font.
-static byte frenchCharsetDataV2[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
- 0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
- 0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
- 0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
- 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
- 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
- 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
- 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
- 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
- 0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
- 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
- 0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
- 0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
- 0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
- 0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
- 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
- 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
- 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
- 0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
- 0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
- 0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x10, 0x08, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x18, 0x24, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x3c, 0x60, 0x60, 0x3c, 0x18, 0x38,
- 0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
- 0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
- 0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
- 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
- 0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
- 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
- 0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
- 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
- 0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
- 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
- 0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
- 0x08, 0x10, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x18, 0x24, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
- 0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
- 0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
- 0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
- 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
- 0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
- 0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
- 0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
- 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
- 0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
- 0x18, 0x24, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x18, 0x24, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
- 0x10, 0x08, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x18, 0x24, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
-};
-
-// Italian Zak font.
-static byte italianCharsetDataV2[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
- 0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
- 0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
- 0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
- 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
- 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
- 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
- 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
- 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
- 0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
- 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
- 0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
- 0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
- 0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
- 0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
- 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
- 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
- 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
- 0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
- 0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
- 0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x10, 0x08, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x08, 0x10, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
- 0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
- 0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
- 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
- 0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
- 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
- 0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
- 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
- 0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
- 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
- 0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
- 0x08, 0x10, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x18, 0x24, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
- 0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
- 0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
- 0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
- 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
- 0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
- 0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
- 0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
- 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
- 0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
- 0x10, 0x08, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x10, 0x08, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
- 0x10, 0x08, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x18, 0x24, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
-};
-
-// Spanish Zak font.
-// FIXME: This is identical to germanCharsetDataV2 it seems?!
-static byte spanishCharsetDataV2[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
- 0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
- 0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
- 0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
- 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
- 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
- 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
- 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
- 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
- 0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
- 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
- 0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
- 0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
- 0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
- 0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
- 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
- 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
- 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
- 0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
- 0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
- 0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
- 0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
- 0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x0e, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0e, 0x00,
- 0x7c, 0x82, 0xba, 0xa2, 0xa2, 0xba, 0x82, 0x7c,
- 0x70, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x70, 0x00,
- 0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
- 0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
- 0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
- 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
- 0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
- 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
- 0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
- 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
- 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
- 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
- 0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
- 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
- 0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
- 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
- 0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
- 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
- 0x00, 0x10, 0x30, 0x7f, 0x7f, 0x30, 0x10, 0x00,
- 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
- 0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
- 0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
- 0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
- 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
- 0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
- 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
- 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
- 0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
- 0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
- 0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
- 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
- 0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
- 0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x66, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x00,
- 0x42, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
- 0x1c, 0x36, 0x36, 0x7c, 0x66, 0x66, 0x7c, 0x40,
- 0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
-};
-#endif
-
-CharsetRendererV2::CharsetRendererV2(ScummEngine *vm, Common::Language language)
- : CharsetRendererV3(vm) {
-
- _fontHeight = 8;
-
- switch (language) {
- case Common::DE_DEU:
- _fontPtr = germanCharsetDataV2;
- break;
- case Common::FR_FRA:
- _fontPtr = frenchCharsetDataV2;
- break;
- case Common::IT_ITA:
- _fontPtr = italianCharsetDataV2;
- break;
- case Common::ES_ESP:
- _fontPtr = spanishCharsetDataV2;
- break;
- default:
- _fontPtr = englishCharsetDataV2;
- break;
- }
-
-#if 0
- // Decompress weird encoding in which the Zak executable contains the font.
- // I leave the code around in case we need to use it again (e.g. we might
- // have to include different fonts for french/spanish/russian/... version
- // of MM / Zak
- //
- int count = 0, len;
- byte b;
- const byte *data = spanishCharsetDataV2;
- const int size = sizeof(spanishCharsetDataV2);
- for (int offset = 0; offset < size; offset++) {
- if (data[offset+1] == 0x00 && data[offset+2] == 0xB2 &&
- data[offset+5] == 0x00 && data[offset+6] == 0xB0) {
- b = data[offset+3];
- len = data[offset+4];
- while (len--) {
- printf("0x%02x, ", b);
- count++;
- if (count % 8 == 0)
- printf("\n");
- }
- offset += 6;
- } else {
- printf("0x%02x, ", data[offset]);
- count++;
- if (count % 8 == 0)
- printf("\n");
- }
- }
- printf("\n");
- _vm->_system->quit();
-#endif
-}
-
-int CharsetRendererV3::getCharWidth(byte chr) {
- if (chr & 0x80 && _vm->_useCJKMode)
- return _vm->_2byteWidth / 2;
- int spacing = 0;
-
- spacing = *(_widthTable + chr);
-
- return spacing;
-}
-
-void CharsetRendererV3::setColor(byte color)
-{
- bool useShadow = false;
- _color = color;
-
- // FM-TOWNS version of Loom uses old color method as well
- if ((_vm->_version >= 2) && (_vm->_features & GF_16COLOR || (_vm->_gameId == GID_LOOM && _vm->_version == 3))) {
- useShadow = ((_color & 0xF0) != 0);
- _color &= 0x0f;
- } else if (_vm->_features & GF_OLD256) {
- useShadow = ((_color & 0x80) != 0);
- _color &= 0x7f;
- } else
- useShadow = false;
-
- enableShadow(useShadow);
-
- translateColor();
-}
-
-void CharsetRendererCommon::enableShadow(bool enable) {
- if (enable) {
- if (_vm->_platform == Common::kPlatformFMTowns) {
- _shadowColor = 8;
- _shadowMode = kFMTOWNSShadowMode;
- } else {
- _shadowColor = 0;
- _shadowMode = kNormalShadowMode;
- }
- } else {
- _shadowMode = kNoShadowMode;
- }
-}
-
-
-void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
- // Indy3 / Zak256 / Loom
- int width, height, origWidth, origHeight;
- VirtScreen *vs;
- byte *charPtr, *dst;
- int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
-
- checkRange(_vm->_numCharsets - 1, 0, _curId, "Printing with bad charset %d");
-
- if ((vs = _vm->findVirtScreen(_top)) == NULL)
- return;
-
- if (chr == '@')
- return;
-
- if (is2byte) {
- charPtr = _vm->get2byteCharPtr(chr);
- width = _vm->_2byteWidth;
- height = _vm->_2byteHeight;
- } else {
- charPtr = _fontPtr + chr * 8;
-// width = height = 8;
- width = getCharWidth(chr);
- height = 8;
- }
-
- origWidth = width;
- origHeight = height;
-
- if (_shadowMode != kNoShadowMode) {
- width++;
- height++;
- }
-
- if (_firstChar) {
- _str.left = _left;
- _str.top = _top;
- _str.right = _left;
- _str.bottom = _top;
- _firstChar = false;
- }
-
- int drawTop = _top - vs->topline;
-
- _vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
-
- if (!ignoreCharsetMask) {
- _hasMask = true;
- _textScreenID = vs->number;
- }
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
- dst = vs->getPixels(_left, drawTop);
- drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
- } else {
- dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
- drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
- }
-
- if (_str.left > _left)
- _str.left = _left;
-
- _left += origWidth;
-
- if (_str.right < _left) {
- _str.right = _left;
- if (_shadowMode != kNoShadowMode)
- _str.right++;
- }
-
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
-}
-
-void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
- byte *charPtr, *dst;
- int width, height;
- int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
- if (is2byte) {
- charPtr = _vm->get2byteCharPtr(chr);
- width = _vm->_2byteWidth;
- height = _vm->_2byteHeight;
- } else {
- charPtr = _fontPtr + chr * 8;
-// width = height = 8;
- width = getCharWidth(chr);
- height = 8;
- }
- dst = (byte *)s.pixels + y * s.pitch + x;
- drawBits1(s, dst, charPtr, y, width, height);
-}
-
-void CharsetRenderer::translateColor() {
- // Based on disassembly
- if (_vm->_renderMode == Common::kRenderCGA) {
- static byte CGAtextColorMap[16] = {0, 3, 3, 3, 5, 5, 5, 15,
- 15, 3, 3, 3, 5, 5, 15, 15};
- _color = CGAtextColorMap[_color & 0x0f];
- }
-
- if (_vm->_renderMode == Common::kRenderHercA || _vm->_renderMode == Common::kRenderHercG) {
- static byte HercTextColorMap[16] = {0, 15, 2, 15, 15, 5, 15, 15,
- 8, 15, 15, 15, 15, 15, 15, 15};
- _color = HercTextColorMap[_color & 0x0f];
- }
-}
-
-
-void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) {
- int width, height, origWidth, origHeight;
- int offsX, offsY;
- VirtScreen *vs;
- const byte *charPtr;
- int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
-
- checkRange(_vm->_numCharsets - 1, 1, _curId, "Printing with bad charset %d");
-
- if ((vs = _vm->findVirtScreen(_top)) == NULL && (vs = _vm->findVirtScreen(_top + getFontHeight())) == NULL)
- return;
-
- if (chr == '@')
- return;
-
- translateColor();
-
- _vm->_charsetColorMap[1] = _color;
-
- if (is2byte) {
- enableShadow(true);
- charPtr = _vm->get2byteCharPtr(chr);
- width = _vm->_2byteWidth;
- height = _vm->_2byteHeight;
- offsX = offsY = 0;
- } else {
- uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
- assert(charOffs < 0x10000);
- if (!charOffs)
- return;
- charPtr = _fontPtr + charOffs;
-
- width = charPtr[0];
- height = charPtr[1];
-
- if (_disableOffsX) {
- offsX = 0;
- } else {
- offsX = (signed char)charPtr[2];
- }
-
- offsY = (signed char)charPtr[3];
-
- charPtr += 4; // Skip over char header
- }
- origWidth = width;
- origHeight = height;
-
- if (_shadowMode != kNoShadowMode) {
- width++;
- height++;
- }
- if (_firstChar) {
- _str.left = 0;
- _str.top = 0;
- _str.right = 0;
- _str.bottom = 0;
- }
-
- _top += offsY;
- _left += offsX;
-
- if (_left + origWidth > _right + 1 || _left < 0) {
- _left += origWidth;
- _top -= offsY;
- return;
- }
-
- _disableOffsX = false;
-
- if (_firstChar) {
- _str.left = _left;
- _str.top = _top;
- _str.right = _left;
- _str.bottom = _top;
- _firstChar = false;
- }
-
- if (_left < _str.left)
- _str.left = _left;
-
- if (_top < _str.top)
- _str.top = _top;
-
- int drawTop = _top - vs->topline;
-
- _vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
-
- byte *dstPtr;
- byte *back = NULL;
-
- if (!ignoreCharsetMask) {
- _hasMask = true;
- _textScreenID = vs->number;
- }
-
- if ((_vm->_heversion >= 71 && _bitDepth >= 8) || (_vm->_heversion >= 90 && _bitDepth == 0)) {
-#ifndef DISABLE_HE
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
- dstPtr = vs->getPixels(0, 0);
- } else {
- dstPtr = (byte *)_textSurface.pixels;
- }
-
- if (_blitAlso && vs->hasTwoBuffers) {
- dstPtr = vs->getBackPixels(0, 0);
- }
-
- Common::Rect rScreen(vs->w, vs->h);
- if (_bitDepth >= 8) {
- byte imagePalette[256];
- memset(imagePalette, 0, sizeof(imagePalette));
- memcpy(imagePalette, _vm->_charsetColorMap, 4);
- Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, 0, imagePalette);
- } else {
- Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen);
- }
-
- if (_blitAlso && vs->hasTwoBuffers) {
- Common::Rect dst(_left, _top, _left + origWidth, _top + origHeight);
- _vm->gdi.copyVirtScreenBuffers(dst);
- }
-#endif
- } else {
- Graphics::Surface dstSurface;
- Graphics::Surface backSurface;
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
- dstSurface = *vs;
- dstPtr = vs->getPixels(_left, drawTop);
- } else {
- dstSurface = _textSurface;
- dstPtr = (byte *)_textSurface.pixels + (_top - _vm->_screenTop) * _textSurface.pitch + _left;
- }
-
- if (_blitAlso && vs->hasTwoBuffers) {
- backSurface = dstSurface;
- back = dstPtr;
- dstSurface = *vs;
- dstPtr = vs->getBackPixels(_left, drawTop);
- }
-
- if (!ignoreCharsetMask && vs->hasTwoBuffers) {
- drawTop = _top - _vm->_screenTop;
- }
-
- if (is2byte) {
- drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight);
- } else {
- drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight);
- }
-
- if (_blitAlso && vs->hasTwoBuffers) {
- // FIXME: Revisiting this code, I think the _blitAlso mode is likely broken
- // right now -- we are copying stuff from "dstPtr" to "back", but "dstPtr" really
- // only conatains charset data...
- // One way to fix this: don't copy etc.; rather simply render the char twice,
- // once to each of the two buffers. That should hypothetically yield
- // identical results, though I didn't try it and right now I don't know
- // any spots where I can test this...
- if (!ignoreCharsetMask)
- warning("This might be broken -- please report where you encountered this to Fingolfin");
-
- // Perform some clipping
- int w = MIN(width, dstSurface.w - _left);
- int h = MIN(height, dstSurface.h - drawTop);
- if (_left < 0) {
- w += _left;
- back -= _left;
- dstPtr -= _left;
- }
- if (drawTop < 0) {
- h += drawTop;
- back -= drawTop * backSurface.pitch;
- dstPtr -= drawTop * dstSurface.pitch;
- }
-
- // Blit the image data
- if (w > 0) {
- while (h-- > 0) {
- memcpy(back, dstPtr, w);
- back += backSurface.pitch;
- dstPtr += dstSurface.pitch;
- }
- }
- }
- }
-
- _left += origWidth;
-
- if (_str.right < _left) {
- _str.right = _left;
- if (_shadowMode != kNoShadowMode)
- _str.right++;
- }
-
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
-
- _top -= offsY;
-}
-
-void CharsetRendererClassic::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
- const byte *charPtr;
- byte *dst;
- int width, height;
- int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
-
- if (is2byte) {
- enableShadow(true);
- charPtr = _vm->get2byteCharPtr(chr);
- width = _vm->_2byteWidth;
- height = _vm->_2byteHeight;
- } else {
- uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
- assert(charOffs < 0x10000);
- if (!charOffs)
- return;
- charPtr = _fontPtr + charOffs;
-
- width = charPtr[0];
- height = charPtr[1];
-
- charPtr += 4; // Skip over char header
- }
-
- dst = (byte *)s.pixels + y * s.pitch + x;
-
- if (is2byte) {
- drawBits1(s, dst, charPtr, y, width, height);
- } else {
- drawBitsN(s, dst, charPtr, *_fontPtr, y, width, height);
- }
-}
-
-void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) {
- int y, x;
- int color;
- byte numbits, bits;
-
- assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
- bits = *src++;
- numbits = 8;
-
- for (y = 0; y < height && y + drawTop < s.h; y++) {
- for (x = 0; x < width; x++) {
- color = (bits >> (8 - bpp)) & 0xFF;
-
- if (color && y + drawTop >= 0) {
- *dst = _vm->_charsetColorMap[color];
- }
- dst++;
- bits <<= bpp;
- numbits -= bpp;
- if (numbits == 0) {
- bits = *src++;
- numbits = 8;
- }
- }
- dst += s.pitch - width;
- }
-}
-
-void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
- int y, x;
- byte bits = 0;
-
- for (y = 0; y < height && y + drawTop < s.h; y++) {
- for (x = 0; x < width; x++) {
- if ((x % 8) == 0)
- bits = *src++;
- if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) {
- if (_shadowMode != kNoShadowMode) {
- *(dst + 1) = _shadowColor;
- *(dst + s.pitch) = _shadowColor;
- if (_shadowMode != kFMTOWNSShadowMode)
- *(dst + s.pitch + 1) = _shadowColor;
- }
- *dst = _color;
- }
- dst++;
- }
-
- dst += s.pitch - width;
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-CharsetRendererNut::CharsetRendererNut(ScummEngine *vm)
- : CharsetRenderer(vm) {
- _current = 0;
-
- for (int i = 0; i < 5; i++) {
- char fontname[256];
- if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO) && (i == 4))
- break;
- sprintf(fontname, "font%d.nut", i);
- _fr[i] = new NutRenderer(_vm);
- if (!(_fr[i]->loadFont(fontname))) {
- delete _fr[i];
- _fr[i] = NULL;
- }
- }
-}
-
-CharsetRendererNut::~CharsetRendererNut() {
- for (int i = 0; i < 5; i++) {
- if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO) && (i == 4))
- break;
- delete _fr[i];
- }
-}
-
-void CharsetRendererNut::setCurID(byte id) {
- assert(id < 5);
- _curId = id;
- _current = _fr[id];
- assert(_current);
-}
-
-int CharsetRendererNut::getCharHeight(byte chr) {
- assert(_current);
- return _current->getCharHeight(chr);
-}
-
-int CharsetRendererNut::getCharWidth(byte chr) {
- assert(_current);
- return _current->getCharWidth(chr);
-}
-
-int CharsetRendererNut::getFontHeight() {
- // FIXME / TODO: how to implement this properly???
- assert(_current);
- return _current->getCharHeight('|');
-}
-
-void CharsetRendererNut::printChar(int chr, bool ignoreCharsetMask) {
- Common::Rect shadow;
-
- assert(_current);
- if (chr == '@')
- return;
-
- shadow.left = _left - 1;
- shadow.top = _top - 1;
-
- // Note that the character is drawn with a shadow, so it is slightly
- // larger than the advertised dimensions. See drawShadowChar() for
- // details.
-
- if (_firstChar) {
- _str.left = (shadow.left >= 0) ? shadow.left : 0;
- _str.top = (shadow.top >= 0) ? shadow.top : 0;
- _str.right = _str.left;
- _str.bottom = _str.top;
- _firstChar = false;
- }
-
- int width = _current->getCharWidth(chr);
- int height = _current->getCharHeight(chr);
-
- if (chr >= 256 && _vm->_useCJKMode)
- width = _vm->_2byteWidth;
-
- shadow.right = _left + width + 2;
- shadow.bottom = _top + height + 2;
-
- Graphics::Surface s;
- if (!ignoreCharsetMask) {
- _hasMask = true;
- _textScreenID = kMainVirtScreen;
- }
-
- int drawTop = _top;
- if (ignoreCharsetMask) {
- VirtScreen *vs = &_vm->virtscr[kMainVirtScreen];
- s = *vs;
- s.pixels = vs->getPixels(0, 0);
- } else {
- s = _textSurface;
- drawTop -= _vm->_screenTop;
- }
-
- _current->drawShadowChar(s, chr, _left, drawTop, _color, _curId != 3);
- _vm->markRectAsDirty(kMainVirtScreen, shadow);
-
- if (_str.left > _left)
- _str.left = _left;
-
- _left += width;
-
- if (_str.right < shadow.right)
- _str.right = shadow.right;
-
- if (_str.bottom < shadow.bottom)
- _str.bottom = shadow.bottom;
-}
-#endif
-
-void CharsetRendererNES::printChar(int chr, bool ignoreCharsetMask) {
- int width, height, origWidth, origHeight;
- VirtScreen *vs;
- byte *charPtr, *dst;
-
- // Init it here each time since it is cheap and fixes bug with
- // charset after game load
- _trTable = _vm->getResourceAddress(rtCostume, 77) + 2;
-
- // HACK: how to set it properly?
- if (_top == 0)
- _top = 16;
-
- if ((vs = _vm->findVirtScreen(_top)) == NULL)
- return;
-
- if (chr == '@')
- return;
-
- charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16;
- width = getCharWidth(chr);
- height = 8;
-
- origWidth = width;
- origHeight = height;
-
- if (_firstChar) {
- _str.left = _left;
- _str.top = _top;
- _str.right = _left;
- _str.bottom = _top;
- _firstChar = false;
- }
-
- int drawTop = _top - vs->topline;
-
- _vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
-
- if (!ignoreCharsetMask) {
- _hasMask = true;
- _textScreenID = vs->number;
- }
-
- if (ignoreCharsetMask || !vs->hasTwoBuffers) {
- dst = vs->getPixels(_left, drawTop);
- drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
- } else {
- dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
- drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
- }
-
- if (_str.left > _left)
- _str.left = _left;
-
- _left += origWidth;
-
- if (_str.right < _left) {
- _str.right = _left;
- if (_shadowMode != kNoShadowMode)
- _str.right++;
- }
-
- if (_str.bottom < _top + height)
- _str.bottom = _top + height;
-}
-
-void CharsetRendererNES::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
- byte *charPtr, *dst;
- int width, height;
-
- if (!_trTable)
- _trTable = _vm->getResourceAddress(rtCostume, 77) + 2;
-
- charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16;
- width = getCharWidth(chr);
- height = 8;
-
- dst = (byte *)s.pixels + y * s.pitch + x;
- drawBits1(s, dst, charPtr, y, width, height);
-}
-
-void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
- for (int i = 0; i < 8; i++) {
- byte c0 = src[i];
- byte c1 = src[i + 8];
- for (int j = 0; j < 8; j++)
- dst[j] = _vm->_NESPalette[0][((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) |
- (_color ? 12 : 8)];
- dst += s.pitch;
- }
-}
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Charset)
-_GSETPTR(Scumm::germanCharsetDataV2, GBVARS_GERMANCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
-_GSETPTR(Scumm::frenchCharsetDataV2, GBVARS_FRENCHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
-_GSETPTR(Scumm::englishCharsetDataV2, GBVARS_ENGLISHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
-_GSETPTR(Scumm::italianCharsetDataV2, GBVARS_ITALIANCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
-_GSETPTR(Scumm::spanishCharsetDataV2, GBVARS_SPANISHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Charset)
-_GRELEASEPTR(GBVARS_GERMANCHARSETDATAV2_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FRENCHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_ENGLISHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_ITALIANCHARSETDATAV2_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_SPANISHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/charset.h b/scumm/charset.h
deleted file mode 100644
index 3746f3be4e..0000000000
--- a/scumm/charset.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef CHARSET_H
-#define CHARSET_H
-
-#include "common/scummsys.h"
-#include "common/rect.h"
-#include "scumm/gfx.h"
-
-namespace Scumm {
-
-class ScummEngine;
-class NutRenderer;
-struct VirtScreen;
-
-static inline bool checkSJISCode(byte c) {
- if ((c > 0x84 && c < 0x88) || (c > 0x9f && c < 0xe0) || (c > 0xea /* && c <= 0xff */))
- return false;
- return true;
-}
-
-
-class CharsetRenderer {
-public:
-
- Common::Rect _str;
- int _nextLeft, _nextTop;
-
- int _top;
- int _left, _startLeft;
- int _right;
-
-protected:
- byte _color;
-
-public:
- bool _center;
-
- bool _hasMask; // True if "removable" text is visible somewhere (should be called _hasText or so)
- VirtScreenNumber _textScreenID; // ID of the virtual screen on which the text is visible.
-
- bool _blitAlso;
- bool _firstChar;
- bool _disableOffsX;
-
- /**
- * All text is normally rendered into this overlay surface. Then later
- * drawStripToScreen() composits it over the game graphics.
- */
- Graphics::Surface _textSurface;
-
-protected:
- ScummEngine *_vm;
- byte _curId;
-
-public:
- CharsetRenderer(ScummEngine *vm);
- virtual ~CharsetRenderer();
-
- void restoreCharsetBg();
- void clearCharsetMask();
- void clearTextSurface();
-
- virtual void printChar(int chr, bool ignoreCharsetMask) = 0;
- virtual void drawChar(int chr, const Graphics::Surface &s, int x, int y) {}
-
- int getStringWidth(int a, const byte *str);
- void addLinebreaks(int a, byte *str, int pos, int maxwidth);
- void translateColor();
-
- virtual void setCurID(byte id) = 0;
- int getCurID() { return _curId; }
-
- virtual int getFontHeight() = 0;
- virtual int getCharHeight(byte chr) { return getFontHeight(); }
- virtual int getCharWidth(byte chr) = 0;
-
- virtual void setColor(byte color) { _color = color; translateColor(); }
-};
-
-class CharsetRendererCommon : public CharsetRenderer {
-protected:
- byte *_fontPtr;
- int _bitDepth;
- int _fontHeight;
- int _numChars;
-
- enum ShadowMode {
- kNoShadowMode,
- kFMTOWNSShadowMode,
- kNormalShadowMode
- };
- byte _shadowColor;
- ShadowMode _shadowMode;
-
- void enableShadow(bool enable);
- void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height);
-
-public:
- CharsetRendererCommon(ScummEngine *vm);
-
- void setCurID(byte id);
-
- int getFontHeight();
-};
-
-class CharsetRendererClassic : public CharsetRendererCommon {
-protected:
- void drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height);
-
-public:
- CharsetRendererClassic(ScummEngine *vm) : CharsetRendererCommon(vm) {}
-
- void printChar(int chr, bool ignoreCharsetMask);
- void drawChar(int chr, const Graphics::Surface &s, int x, int y);
-
- int getCharWidth(byte chr);
-};
-
-class CharsetRendererNES : public CharsetRendererCommon {
-protected:
- byte *_trTable;
-
- void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height);
-
-public:
- CharsetRendererNES(ScummEngine *vm) : CharsetRendererCommon(vm) {}
-
- void setCurID(byte id) {}
- void printChar(int chr, bool ignoreCharsetMask);
- void drawChar(int chr, const Graphics::Surface &s, int x, int y);
-
- int getFontHeight() { return 8; }
- int getCharWidth(byte chr) { return 8; }
-};
-
-class CharsetRendererV3 : public CharsetRendererCommon {
-protected:
- byte *_widthTable;
-
-public:
- CharsetRendererV3(ScummEngine *vm) : CharsetRendererCommon(vm) {}
-
- void printChar(int chr, bool ignoreCharsetMask);
- void drawChar(int chr, const Graphics::Surface &s, int x, int y);
- void setCurID(byte id);
- void setColor(byte color);
- int getFontHeight();
- int getCharWidth(byte chr);
-};
-
-class CharsetRendererV2 : public CharsetRendererV3 {
-public:
- CharsetRendererV2(ScummEngine *vm, Common::Language language);
-
- void setCurID(byte id) {}
- int getCharWidth(byte chr) { return 8; }
-};
-
-#ifndef DISABLE_SCUMM_7_8
-class CharsetRendererNut : public CharsetRenderer {
-protected:
- NutRenderer *_fr[5];
- NutRenderer *_current;
-
-public:
- CharsetRendererNut(ScummEngine *vm);
- ~CharsetRendererNut();
-
- void printChar(int chr, bool ignoreCharsetMask);
-
- void setCurID(byte id);
-
- int getFontHeight();
- int getCharHeight(byte chr);
- int getCharWidth(byte chr);
-};
-#endif
-
-} // End of namespace Scumm
-
-
-#endif
diff --git a/scumm/costume.cpp b/scumm/costume.cpp
deleted file mode 100644
index 48f81111c6..0000000000
--- a/scumm/costume.cpp
+++ /dev/null
@@ -1,1160 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/costume.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-#ifdef PALMOS_68K
-const byte *smallCostumeScaleTable;
-#else
-const byte smallCostumeScaleTable[256] = {
- 0xFF, 0xFD, 0x7D, 0xBD, 0x3D, 0xDD, 0x5D, 0x9D,
- 0x1D, 0xED, 0x6D, 0xAD, 0x2D, 0xCD, 0x4D, 0x8D,
- 0x0D, 0xF5, 0x75, 0xB5, 0x35, 0xD5, 0x55, 0x95,
- 0x15, 0xE5, 0x65, 0xA5, 0x25, 0xC5, 0x45, 0x85,
- 0x05, 0xF9, 0x79, 0xB9, 0x39, 0xD9, 0x59, 0x99,
- 0x19, 0xE9, 0x69, 0xA9, 0x29, 0xC9, 0x49, 0x89,
- 0x09, 0xF1, 0x71, 0xB1, 0x31, 0xD1, 0x51, 0x91,
- 0x11, 0xE1, 0x61, 0xA1, 0x21, 0xC1, 0x41, 0x81,
- 0x01, 0xFB, 0x7B, 0xBB, 0x3B, 0xDB, 0x5B, 0x9B,
- 0x1B, 0xEB, 0x6B, 0xAB, 0x2B, 0xCB, 0x4B, 0x8B,
- 0x0B, 0xF3, 0x73, 0xB3, 0x33, 0xD3, 0x53, 0x93,
- 0x13, 0xE3, 0x63, 0xA3, 0x23, 0xC3, 0x43, 0x83,
- 0x03, 0xF7, 0x77, 0xB7, 0x37, 0xD7, 0x57, 0x97,
- 0x17, 0xE7, 0x67, 0xA7, 0x27, 0xC7, 0x47, 0x87,
- 0x07, 0xEF, 0x6F, 0xAF, 0x2F, 0xCF, 0x4F, 0x8F,
- 0x0F, 0xDF, 0x5F, 0x9F, 0x1F, 0xBF, 0x3F, 0x7F,
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE
-};
-#endif
-
-static const int v1MMNESLookup[25] = {
- 0x00, 0x03, 0x01, 0x06, 0x08,
- 0x02, 0x00, 0x07, 0x0C, 0x04,
- 0x09, 0x0A, 0x12, 0x0B, 0x14,
- 0x0D, 0x11, 0x0F, 0x0E, 0x10,
- 0x17, 0x00, 0x01, 0x05, 0x16
-};
-
-
-byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
- int i, skip = 0;
- byte drawFlag = 1;
- bool use_scaling;
- byte startScaleIndexX;
- int ex1, ex2;
- Common::Rect rect;
- int step;
- Codec1 v1;
-
-
- const int scaletableSize = 128;
- const bool newAmiCost = (_vm->_version == 5) && (_vm->_platform == Common::kPlatformAmiga);
-
- CHECK_HEAP
-
- v1.scaletable = smallCostumeScaleTable;
-
- if (_loaded._numColors == 32) {
- v1.mask = 7;
- v1.shr = 3;
- } else {
- v1.mask = 15;
- v1.shr = 4;
- }
-
- switch (_loaded._format) {
- case 0x60:
- case 0x61:
- // This format is used e.g. in the Sam&Max intro
- ex1 = _srcptr[0];
- ex2 = _srcptr[1];
- _srcptr += 2;
- if (ex1 != 0xFF || ex2 != 0xFF) {
- ex1 = READ_LE_UINT16(_loaded._frameOffsets + ex1 * 2);
- _srcptr = _loaded._baseptr + READ_LE_UINT16(_loaded._baseptr + ex1 + ex2 * 2) + 14;
- }
- }
-
- use_scaling = (_scaleX != 0xFF) || (_scaleY != 0xFF);
-
- v1.x = _actorX;
- v1.y = _actorY;
-
- if (use_scaling) {
-
- /* Scale direction */
- v1.scaleXstep = -1;
- if (xmoveCur < 0) {
- xmoveCur = -xmoveCur;
- v1.scaleXstep = 1;
- }
-
- if (_mirror) {
- /* Adjust X position */
- startScaleIndexX = _scaleIndexX = scaletableSize - xmoveCur;
- for (i = 0; i < xmoveCur; i++) {
- if (v1.scaletable[_scaleIndexX++] < _scaleX)
- v1.x -= v1.scaleXstep;
- }
-
- rect.left = rect.right = v1.x;
-
- _scaleIndexX = startScaleIndexX;
- for (i = 0; i < _width; i++) {
- if (rect.right < 0) {
- skip++;
- startScaleIndexX = _scaleIndexX;
- }
- if (v1.scaletable[_scaleIndexX++] < _scaleX)
- rect.right++;
- }
- } else {
- /* No mirror */
- /* Adjust X position */
- startScaleIndexX = _scaleIndexX = xmoveCur + scaletableSize;
- for (i = 0; i < xmoveCur; i++) {
- if (v1.scaletable[_scaleIndexX--] < _scaleX)
- v1.x += v1.scaleXstep;
- }
-
- rect.left = rect.right = v1.x;
-
- _scaleIndexX = startScaleIndexX;
- for (i = 0; i < _width; i++) {
- if (rect.left >= _out.w) {
- startScaleIndexX = _scaleIndexX;
- skip++;
- }
- if (v1.scaletable[_scaleIndexX--] < _scaleX)
- rect.left--;
- }
- }
- _scaleIndexX = startScaleIndexX;
-
- if (skip)
- skip--;
-
- step = -1;
- if (ymoveCur < 0) {
- ymoveCur = -ymoveCur;
- step = 1;
- }
-
- _scaleIndexY = scaletableSize - ymoveCur;
- for (i = 0; i < ymoveCur; i++) {
- if (v1.scaletable[_scaleIndexY++] < _scaleY)
- v1.y -= step;
- }
-
- rect.top = rect.bottom = v1.y;
- _scaleIndexY = scaletableSize - ymoveCur;
- for (i = 0; i < _height; i++) {
- if (v1.scaletable[_scaleIndexY++] < _scaleY)
- rect.bottom++;
- }
-
- _scaleIndexY = scaletableSize - ymoveCur;
- } else {
- if (!_mirror)
- xmoveCur = -xmoveCur;
-
- v1.x += xmoveCur;
- v1.y += ymoveCur;
-
- if (_mirror) {
- rect.left = v1.x;
- rect.right = v1.x + _width;
- } else {
- rect.left = v1.x - _width;
- rect.right = v1.x;
- }
-
- rect.top = v1.y;
- rect.bottom = rect.top + _height;
-
- }
-
- v1.skip_width = _width;
- v1.scaleXstep = _mirror ? 1 : -1;
-
- if (_vm->_version == 1)
- // V1 games uses 8 x 8 pixels for actors
- _vm->markRectAsDirty(kMainVirtScreen, rect.left, rect.right + 8, rect.top, rect.bottom, _actorID);
- else
- _vm->markRectAsDirty(kMainVirtScreen, rect.left, rect.right + 1, rect.top, rect.bottom, _actorID);
-
- if (rect.top >= _out.h || rect.bottom <= 0)
- return 0;
-
- if (rect.left >= _out.w || rect.right <= 0)
- return 0;
-
- v1.replen = 0;
-
- if (_mirror) {
- if (!use_scaling)
- skip = -v1.x;
- if (skip > 0) {
- if (!newAmiCost && _loaded._format != 0x57) {
- v1.skip_width -= skip;
- codec1_ignorePakCols(v1, skip);
- v1.x = 0;
- }
- } else {
- skip = rect.right - _out.w;
- if (skip <= 0) {
- drawFlag = 2;
- } else {
- v1.skip_width -= skip;
- }
- }
- } else {
- if (!use_scaling)
- skip = rect.right - _out.w;
- if (skip > 0) {
- if (!newAmiCost && _loaded._format != 0x57) {
- v1.skip_width -= skip;
- codec1_ignorePakCols(v1, skip);
- v1.x = _out.w - 1;
- }
- } else {
- // V1 games uses 8 x 8 pixels for actors
- if (_loaded._format == 0x57)
- skip = -8 - rect.left;
- else
- skip = -1 - rect.left;
- if (skip <= 0)
- drawFlag = 2;
- else
- v1.skip_width -= skip;
- }
- }
-
- if (v1.skip_width <= 0)
- return 0;
-
- if (rect.left < 0)
- rect.left = 0;
-
- if (rect.top < 0)
- rect.top = 0;
-
- if (rect.top > _out.h)
- rect.top = _out.h;
-
- if (rect.bottom > _out.h)
- rect.bottom = _out.h;
-
- if (_draw_top > rect.top)
- _draw_top = rect.top;
- if (_draw_bottom < rect.bottom)
- _draw_bottom = rect.bottom;
-
- if (_height + rect.top >= 256) {
- CHECK_HEAP
- return 2;
- }
-
- v1.destptr = (byte *)_out.pixels + v1.y * _out.pitch + v1.x;
-
- v1.mask_ptr = _vm->getMaskBuffer(0, v1.y, _zbuf);
-
- CHECK_HEAP
-
- if (_loaded._format == 0x57) {
- // The v1 costume renderer needs the actor number, which is
- // the same thing as the costume renderer's _actorID.
- procC64(v1, _actorID);
- } else if (newAmiCost)
- proc3_ami(v1);
- else
- proc3(v1);
-
- CHECK_HEAP
- return drawFlag;
-}
-
-static const int v1MMActorPalatte1[25] = {
- 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
-};
-static const int v1MMActorPalatte2[25] = {
- 0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7
-};
-
-#define MASK_AT(xoff) \
- (mask && (mask[((v1.x + xoff) / 8)] & revBitMask((v1.x + xoff) & 7)))
-#define LINE(c,p) \
- pcolor = (color >> c) & 3; \
- if (pcolor) { \
- if (!MASK_AT(p)) \
- dst[p] = palette[pcolor]; \
- if (!MASK_AT(p + 1)) \
- dst[p + 1] = palette[pcolor]; \
- }
-
-void ClassicCostumeRenderer::procC64(Codec1 &v1, int actor) {
- const byte *mask, *src;
- byte *dst;
- byte len;
- int y;
- uint height;
- byte color, pcolor;
- bool rep;
-
- y = v1.y;
- src = _srcptr;
- dst = v1.destptr;
- len = v1.replen;
- color = v1.repcolor;
- height = _height;
-
- v1.skip_width /= 8;
-
- // Set up the palette data
- byte palette[4] = { 0, 0, 0, 0 };
- if (!(_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_color)) {
- palette[2] = 11;
- palette[3] = 11;
- } else if (_vm->_gameId == GID_MANIAC) {
- palette[1] = v1MMActorPalatte1[actor];
- palette[2] = v1MMActorPalatte2[actor];
- } else {
- palette[1] = (_vm->_platform == Common::kPlatformC64) ? 10 : 8;
- palette[2] = _palette[actor];
- }
- mask = v1.mask_ptr;
-
- if (len)
- goto StartPos;
-
- do {
- len = *src++;
- if (len & 0x80)
- color = *src++;
- StartPos:;
- rep = (len & 0x80) != 0;
- len &= 0x7f;
- while (len--) {
- if (!rep)
- color = *src++;
-
- if (0 <= y && y < _out.h && 0 <= v1.x && v1.x < _out.w) {
- if (!_mirror) {
- LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6);
- } else {
- LINE(6, 0); LINE(4, 2); LINE(2, 4); LINE(0, 6);
- }
- }
- dst += _out.pitch;
- y++;
- mask += _numStrips;
- if (!--height) {
- if (!--v1.skip_width)
- return;
- height = _height;
- y = v1.y;
- v1.x += 8 * v1.scaleXstep;
- if (v1.x < 0 || v1.x >= _out.w)
- return;
- mask = v1.mask_ptr;
- v1.destptr += 8 * v1.scaleXstep;
- dst = v1.destptr;
- }
- }
- } while (1);
-}
-
-#undef LINE
-#undef MASK_AT
-
-void ClassicCostumeRenderer::proc3(Codec1 &v1) {
- const byte *mask, *src;
- byte *dst;
- byte len, maskbit;
- int y;
- uint color, height, pcolor;
- const byte *scaleytab;
- bool masked;
-
- y = v1.y;
- src = _srcptr;
- dst = v1.destptr;
- len = v1.replen;
- color = v1.repcolor;
- height = _height;
-
- scaleytab = &v1.scaletable[_scaleIndexY];
- maskbit = revBitMask(v1.x & 7);
- mask = v1.mask_ptr + v1.x / 8;
-
- if (len)
- goto StartPos;
-
- do {
- len = *src++;
- color = len >> v1.shr;
- len &= v1.mask;
- if (!len)
- len = *src++;
-
- do {
- if (_scaleY == 255 || *scaleytab++ < _scaleY) {
- masked = (y < 0 || y >= _out.h) || (v1.mask_ptr && (mask[0] & maskbit));
-
- if (color && !masked) {
- if (_shadow_mode & 0x20) {
- pcolor = _shadow_table[*dst];
- } else {
- pcolor = _palette[color];
- if (pcolor == 13 && _shadow_table)
- pcolor = _shadow_table[*dst];
- }
- *dst = pcolor;
- }
- dst += _out.pitch;
- mask += _numStrips;
- y++;
- }
- if (!--height) {
- if (!--v1.skip_width)
- return;
- height = _height;
- y = v1.y;
-
- scaleytab = &v1.scaletable[_scaleIndexY];
-
- if (_scaleX == 255 || v1.scaletable[_scaleIndexX] < _scaleX) {
- v1.x += v1.scaleXstep;
- if (v1.x < 0 || v1.x >= _out.w)
- return;
- maskbit = revBitMask(v1.x & 7);
- v1.destptr += v1.scaleXstep;
- }
- _scaleIndexX += v1.scaleXstep;
- dst = v1.destptr;
- mask = v1.mask_ptr + v1.x / 8;
- }
- StartPos:;
- } while (--len);
- } while (1);
-}
-
-void ClassicCostumeRenderer::proc3_ami(Codec1 &v1) {
- const byte *mask, *src;
- byte *dst;
- byte maskbit, len, height, width;
- int color;
- int y;
- bool masked;
- int oldXpos, oldScaleIndexX;
-
- mask = v1.mask_ptr + v1.x / 8;
- dst = v1.destptr;
- height = _height;
- width = _width;
- src = _srcptr;
- maskbit = revBitMask(v1.x & 7);
- y = v1.y;
- oldXpos = v1.x;
- oldScaleIndexX = _scaleIndexX;
-
- do {
- len = *src++;
- color = len >> v1.shr;
- len &= v1.mask;
- if (!len)
- len = *src++;
- do {
- if (_scaleY == 255 || v1.scaletable[_scaleIndexY] < _scaleY) {
- masked = (y < 0 || y >= _out.h) || (v1.mask_ptr && (mask[0] & maskbit));
-
- if (color && v1.x >= 0 && v1.x < _out.w && !masked) {
- *dst = _palette[color];
- }
-
- if (_scaleX == 255 || v1.scaletable[_scaleIndexX] < _scaleX) {
- v1.x += v1.scaleXstep;
- dst += v1.scaleXstep;
- maskbit = revBitMask(v1.x & 7);
- }
- _scaleIndexX += v1.scaleXstep;
- mask = v1.mask_ptr + v1.x / 8;
- }
- if (!--width) {
- if (!--height)
- return;
-
- if (y >= _out.h)
- return;
-
- if (v1.x != oldXpos) {
- dst += _out.pitch - (v1.x - oldXpos);
- v1.mask_ptr += _numStrips;
- mask = v1.mask_ptr + oldXpos / 8;
- maskbit = revBitMask(oldXpos & 7);
- y++;
- }
- width = _width;
- v1.x = oldXpos;
- _scaleIndexX = oldScaleIndexX;
- _scaleIndexY++;
- }
- } while (--len);
- } while (1);
-}
-
-void ClassicCostumeLoader::loadCostume(int id) {
- _id = id;
- byte *ptr = _vm->getResourceAddress(rtCostume, id);
-
- if (_vm->_version >= 6)
- ptr += 8;
- else if (_vm->_features & GF_OLD_BUNDLE)
- ptr += -2;
- else if (_vm->_features & GF_SMALL_HEADER)
- ptr += 0;
- else
- ptr += 2;
-
- _baseptr = ptr;
-
- _numAnim = ptr[6];
- _format = ptr[7] & 0x7F;
- _mirror = (ptr[7] & 0x80) != 0;
- _palette = ptr + 8;
- switch (_format) {
- case 0x57: // Only used in V1 games
- _numColors = 0;
- break;
- case 0x58:
- _numColors = 16;
- break;
- case 0x59:
- _numColors = 32;
- break;
- case 0x60: // New since version 6
- _numColors = 16;
- break;
- case 0x61: // New since version 6
- _numColors = 32;
- break;
- default:
- error("Costume %d with format 0x%X is invalid", id, _format);
- }
-
-
- // In GF_OLD_BUNDLE games, there is no actual palette, just a single color byte.
- // Don't forget, these games were designed around a fixed 16 color HW palette :-)
- // In addition, all offsets are shifted by 2; we accomodate that via a separate
- // _baseptr value (instead of adding tons of if's throughout the code).
- if (_vm->_features & GF_OLD_BUNDLE) {
- _numColors = (_format == 0x57) ? 0 : 1;
- _baseptr += 2;
- }
- ptr += 8 + _numColors;
- _frameOffsets = ptr + 2;
- if (_format == 0x57) {
- _dataOffsets = ptr + 18;
- _baseptr += 4;
- } else {
- _dataOffsets = ptr + 34;
- }
- _animCmds = _baseptr + READ_LE_UINT16(ptr);
-}
-
-byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) {
- const byte darkpalette[16] = {0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D};
- const CostumeData &cost = a->_cost;
- const byte *palette, *src, *sprdata;
- int anim, frameNum, frame, offset, numSprites;
-
- // If the specified limb is stopped or not existing, do nothing.
- if (cost.curpos[limb] == 0xFFFF)
- return 0;
-
- if (_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_base)
- palette = _vm->_NESPalette[1];
- else
- palette = darkpalette;
-
- src = _loaded._dataOffsets;
- anim = 4 * cost.frame[limb] + newDirToOldDir(a->getFacing());
- frameNum = cost.curpos[limb];
- frame = src[src[2 * anim] + frameNum];
-
- offset = READ_LE_UINT16(_vm->_NEScostdesc + v1MMNESLookup[_loaded._id] * 2);
- numSprites = _vm->_NEScostlens[offset + frame] + 1;
- sprdata = _vm->_NEScostdata + READ_LE_UINT16(_vm->_NEScostoffs + 2 * (offset + frame)) + numSprites * 3;
-
- bool flipped = (newDirToOldDir(a->getFacing()) == 1);
- int left = 239, right = 0, top = 239, bottom = 0;
- byte *maskBuf = _vm->getMaskBuffer(0, 0, 1);
-
- for (int spr = 0; spr < numSprites; spr++) {
- byte mask, tile, sprpal;
- int8 y, x;
-
- sprdata -= 3;
-
- mask = (sprdata[0] & 0x80) ? 0x01 : 0x80;
- y = sprdata[0] << 1;
- y >>= 1;
-
- tile = sprdata[1];
-
- sprpal = (sprdata[2] & 0x03) << 2;
- x = sprdata[2];
- x >>= 2;
-
- if (flipped) {
- mask = (mask == 0x80) ? 0x01 : 0x80;
- x = -x;
- }
-
- if ((_actorX + x < 0) || (_actorX + x + 8 >= _out.w))
- continue;
- if ((_actorY + y < 0) || (_actorY + y + 8 >= _out.h))
- continue;
-
- for (int ty = 0; ty < 8; ty++) {
- byte c1 = _vm->_NESPatTable[0][tile * 16 + ty];
- byte c2 = _vm->_NESPatTable[0][tile * 16 + ty + 8];
-
- for (int tx = 0; tx < 8; tx++) {
- unsigned char c = ((c1 & mask) ? 1 : 0) | ((c2 & mask) ? 2 : 0) | sprpal;
- if (mask == 0x01) {
- c1 >>= 1;
- c2 >>= 1;
- } else {
- c1 <<= 1;
- c2 <<= 1;
- }
- if (!(c & 3))
- continue;
- int my = _actorY + y + ty;
- int mx = _actorX + x + tx;
- if (!(_zbuf && (maskBuf[my * _numStrips + mx / 8] & revBitMask(mx & 7))))
- *((byte *)_out.pixels + my * _out.pitch + mx) = palette[c];
- }
- }
- left = MIN(left, _actorX + x);
- right = MAX(right, _actorX + x + 8);
- top = MIN(top, _actorY + y);
- bottom = MAX(bottom, _actorY + y + 8);
- }
-
- _draw_top = top;
- _draw_bottom = bottom;
-
- _vm->markRectAsDirty(kMainVirtScreen, left, right, top, bottom, _actorID);
-
- return 0;
-}
-
-byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
- int i;
- int code;
- const byte *frameptr;
- const CostumeData &cost = a->_cost;
-
- // If the specified limb is stopped or not existing, do nothing.
- if (cost.curpos[limb] == 0xFFFF || cost.stopped & (1 << limb))
- return 0;
-
- // Determine the position the limb is at
- i = cost.curpos[limb] & 0x7FFF;
-
- // Get the frame pointer for that limb
- frameptr = _loaded._baseptr + READ_LE_UINT16(_loaded._frameOffsets + limb * 2);
-
- // Determine the offset to the costume data for the limb at position i
- code = _loaded._animCmds[i] & 0x7F;
-
- // Code 0x7B indicates a limb for which there is nothing to draw
- if (code != 0x7B) {
- _srcptr = _loaded._baseptr + READ_LE_UINT16(frameptr + code * 2);
-
- if (!(_vm->_features & GF_OLD256) || code < 0x79) {
- const CostumeInfo *costumeInfo;
- int xmoveCur, ymoveCur;
-
- if (_loaded._format == 0x57) {
- _width = _srcptr[0] * 8;
- _height = _srcptr[1];
- xmoveCur = _xmove + (int8)_srcptr[2] * 8;
- ymoveCur = _ymove - (int8)_srcptr[3];
- _xmove += (int8)_srcptr[4] * 8;
- _ymove -= (int8)_srcptr[5];
- _srcptr += 6;
- } else {
- costumeInfo = (const CostumeInfo *)_srcptr;
- _width = READ_LE_UINT16(&costumeInfo->width);
- _height = READ_LE_UINT16(&costumeInfo->height);
- xmoveCur = _xmove + (int16)READ_LE_UINT16(&costumeInfo->rel_x);
- ymoveCur = _ymove + (int16)READ_LE_UINT16(&costumeInfo->rel_y);
- _xmove += (int16)READ_LE_UINT16(&costumeInfo->move_x);
- _ymove -= (int16)READ_LE_UINT16(&costumeInfo->move_y);
- _srcptr += 12;
- }
-
- return mainRoutine(xmoveCur, ymoveCur);
- }
- }
-
- return 0;
-
-}
-
-void NESCostumeRenderer::setPalette(byte *palette) {
- // TODO
-}
-
-void NESCostumeRenderer::setFacing(const Actor *a) {
- // TODO
- //_mirror = newDirToOldDir(a->getFacing()) != 0 || _loaded._mirror;
-}
-
-void NESCostumeRenderer::setCostume(int costume, int shadow) {
- _loaded.loadCostume(costume);
-}
-
-void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
- const byte *r;
- uint mask, j;
- int i;
- byte extra, cmd;
- int anim;
-
- loadCostume(a->_costume);
-
- anim = newDirToOldDir(a->getFacing()) + frame * 4;
-
- if (anim > _numAnim) {
- return;
- }
-
- r = _baseptr + READ_LE_UINT16(_dataOffsets + anim * 2);
-
- if (r == _baseptr) {
- return;
- }
-
- if (_vm->_version == 1) {
- mask = *r++ << 8;
- } else {
- mask = READ_LE_UINT16(r);
- r += 2;
- }
- i = 0;
- do {
- if (mask & 0x8000) {
- if (_vm->_version <= 3) {
- j = *r++;
-
- if (j == 0xFF)
- j = 0xFFFF;
- } else {
- j = READ_LE_UINT16(r);
- r += 2;
- }
- if (usemask & 0x8000) {
- if (j == 0xFFFF) {
- a->_cost.curpos[i] = 0xFFFF;
- a->_cost.start[i] = 0;
- a->_cost.frame[i] = frame;
- } else {
- extra = *r++;
- cmd = _animCmds[j];
- if (cmd == 0x7A) {
- a->_cost.stopped &= ~(1 << i);
- } else if (cmd == 0x79) {
- a->_cost.stopped |= (1 << i);
- } else {
- a->_cost.curpos[i] = a->_cost.start[i] = j;
- a->_cost.end[i] = j + (extra & 0x7F);
- if (extra & 0x80)
- a->_cost.curpos[i] |= 0x8000;
- a->_cost.frame[i] = frame;
- }
- }
- } else {
- if (j != 0xFFFF)
- r++;
- }
- }
- i++;
- usemask <<= 1;
- mask <<= 1;
- } while (mask&0xFFFF);
-}
-
-void ClassicCostumeRenderer::setPalette(byte *palette) {
- int i;
- byte color;
-
- if (_loaded._format == 0x57) {
- memcpy(_palette, palette, 13);
- } else if (_vm->_features & GF_OLD_BUNDLE) {
- if ((_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_color)) {
- memcpy(_palette, palette, 16);
- } else {
- memset(_palette, 8, 16);
- _palette[12] = 0;
- }
- _palette[_loaded._palette[0]] = _palette[0];
- } else {
- if ((_vm->VAR_CURRENT_LIGHTS == 0xFF) || (_vm->VAR(_vm->VAR_CURRENT_LIGHTS) & LIGHTMODE_actor_color)) {
- for (i = 0; i < _loaded._numColors; i++) {
- color = palette[i];
- if (color == 255)
- color = _loaded._palette[i];
- _palette[i] = color;
- }
- } else {
- memset(_palette, 8, _loaded._numColors);
- _palette[12] = 0;
- }
- }
-}
-
-void ClassicCostumeRenderer::setFacing(const Actor *a) {
- _mirror = newDirToOldDir(a->getFacing()) != 0 || _loaded._mirror;
-}
-
-void ClassicCostumeRenderer::setCostume(int costume, int shadow) {
- _loaded.loadCostume(costume);
-}
-
-byte ClassicCostumeLoader::increaseAnims(Actor *a) {
- int i;
- byte r = 0;
-
- for (i = 0; i != 16; i++) {
- if (a->_cost.curpos[i] != 0xFFFF)
- r += increaseAnim(a, i);
- }
- return r;
-}
-
-byte ClassicCostumeLoader::increaseAnim(Actor *a, int slot) {
- int highflag;
- int i, end;
- byte code, nc;
-
- if (a->_cost.curpos[slot] == 0xFFFF)
- return 0;
-
- highflag = a->_cost.curpos[slot] & 0x8000;
- i = a->_cost.curpos[slot] & 0x7FFF;
- end = a->_cost.end[slot];
- code = _animCmds[i] & 0x7F;
-
- if (_vm->_version <= 3) {
- if (_animCmds[i] & 0x80)
- a->_cost.soundCounter++;
- }
-
- do {
- if (!highflag) {
- if (i++ >= end)
- i = a->_cost.start[slot];
- } else {
- if (i != end)
- i++;
- }
- nc = _animCmds[i];
-
- if (nc == 0x7C) {
- a->_cost.animCounter++;
- if (a->_cost.start[slot] != end)
- continue;
- } else {
- if (_vm->_version >= 6) {
- if (nc >= 0x71 && nc <= 0x78) {
- uint sound = (_vm->_heversion == 60) ? 0x78 - nc : nc - 0x71;
- _vm->_sound->addSoundToQueue2(a->_sound[sound]);
- if (a->_cost.start[slot] != end)
- continue;
- }
- } else {
- if (nc == 0x78) {
- a->_cost.soundCounter++;
- if (a->_cost.start[slot] != end)
- continue;
- }
- }
- }
-
- a->_cost.curpos[slot] = i | highflag;
- return (_animCmds[i] & 0x7F) != code;
- } while (1);
-}
-
-/**
- * costume ID -> v1MMNESLookup[] -> desc -> lens & offs -> data -> Gfx & pal
- */
-void NESCostumeLoader::loadCostume(int id) {
- _id = id;
- _baseptr = _vm->getResourceAddress(rtCostume, id);
- _dataOffsets = _baseptr + 2;
- _numAnim = 0x17;
-}
-
-void NESCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
- int anim;
-
- loadCostume(a->_costume);
-
- anim = 4 * frame + newDirToOldDir(a->getFacing());
-
- if (anim > _numAnim) {
- return;
- }
-
- a->_cost.curpos[0] = 0;
- a->_cost.start[0] = 0;
- a->_cost.end[0] = _dataOffsets[2 * anim + 1];
- a->_cost.frame[0] = frame;
-}
-
-byte NESCostumeLoader::increaseAnims(Actor *a) {
- int i;
- byte r = 0;
-
- for (i = 0; i != 16; i++) {
- if (a->_cost.curpos[i] != 0xFFFF)
- r += increaseAnim(a, i);
- }
- return r;
-}
-
-byte NESCostumeLoader::increaseAnim(Actor *a, int slot) {
- int oldframe = a->_cost.curpos[slot]++;
- if (a->_cost.curpos[slot] >= a->_cost.end[slot])
- a->_cost.curpos[slot] = a->_cost.start[slot];
- return (a->_cost.curpos[slot] != oldframe);
-}
-
-static const byte actorColorsMMC64[] = {
- 0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5,
- 4, 1, 0, 5, 4, 2, 2, 7, 7, 0, 6, 6, 6, 6, 6, 6
-};
-
-byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
- if (limb >= 8)
- return 0;
-
- if (limb == 0) {
- _draw_top = 200;
- _draw_bottom = 0;
- }
-
- // TODO:
- // get out how animations are handled
- byte state = a->_moving != 0 ? 0 : 1;
- byte unk1 = (_loaded._animCmds + (state*32) + newDirToOldDir(a->getFacing()) * 8)[limb];
- byte unk2 = _loaded._frameOffsets[_loaded._frameOffsets[limb] + (unk1 & 0x7f)];
- bool flipped = (unk1 & 0x80) != 0;
-
- byte p1 = _loaded._frameOffsets[unk2];
- byte temp1 = _loaded._baseptr[p1];
- byte temp2 = temp1 + _loaded._dataOffsets[4];
- int offL = _loaded._baseptr[temp1 + 2];
- int offH = _loaded._baseptr[temp2];
- int off = (offH << 8) + offL;
-
- const byte *data = _loaded._baseptr + off;
- const byte actorColors[] = {
- 0, 10, actorColorsMMC64[_actorID], 0
- };
-
- int width = *data++;
- int height = *data++;
- int offsetX = *data++;
- int offsetY = *data++;
- // these two fields seems to be most times zero
- // byte6 was one time 255 in one costume I tried
-// int byte5 = *data++;
-// int byte6 = *data++;
-// debug(3, "byte5: %d", byte5);
-// debug(3, "byte6: %d", byte6);
- data += 2;
-
- if (!width || !height)
- return 0;
-
- int xpos = 0;
- int ypos = _loaded._maxHeight - offsetY;
-
- if (flipped) {
- if (offsetX)
- xpos += (offsetX-1) * 8;
- } else {
- xpos += offsetX * 8;
- }
-
- // + 4 could be commented, because maybe the _actorX position is
- // wrong, I looked at the scumm-c64 interpreter by lloyd
- // and there Bernhard is directly on the right in the intro
- // but here in ScummVM he is 4 pixel left of the other position.
- xpos += _actorX - (a->_width / 2) + 4;
- ypos += _actorY - _loaded._maxHeight;
-
- if (flipped) {
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- byte c = data[y*width+x];
- byte b, d;
- int realX = 0;
- if (offsetX == 0||offsetX == 1) {
- realX = width-(x+1);
- } else if (offsetX == 2) {
- realX = width-(x+2);
- }
- byte *dest = &(((byte*)_out.pixels)[((y + ypos) * _out.pitch) + ((realX * 8) + xpos)]);
-
- for (int i = 0; i <= 6; i += 2) {
- if ((d = (c >> i) & 0x03)) {
- b = actorColors[d];
- *dest++ = b;
- *dest++ = b;
- continue;
- }
- dest += 2;
- }
- }
- }
- } else {
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- byte c = data[y*width+x];
- byte b, d;
- byte *dest = &(((byte*)_out.pixels)[((y + ypos) * _out.pitch) + ((x * 8) + xpos)]);
-
- for (int i = 6; i >= 0; i -= 2) {
- if ((d = (c >> i) & 0x03)) {
- b = actorColors[d];
- *dest++ = b;
- *dest++ = b;
- continue;
- }
- dest += 2;
- }
- }
- }
- }
-
- _draw_top = MIN(_draw_top, ypos);
- _draw_bottom = MAX(_draw_bottom, ypos+height);
- // if +4 above is NOT commented, here "+(flipped ? 4 : 0)" can be commented out
- // and other way round
- _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos+(width*8)/*+(flipped ? 4 : 0)*/, ypos, ypos+height, _actorID);
-
- return 0;
-}
-
-void C64CostumeRenderer::setCostume(int costume, int shadow) {
- _loaded.loadCostume(costume);
-}
-
-void C64CostumeLoader::loadCostume(int id) {
- const byte *ptr = _vm->getResourceAddress(rtCostume, id);
- _id = id;
- _baseptr = ptr + 9;
-
- _format = 0x57;
- _numColors = 0;
- _numAnim = 0;
- _mirror = 0;
- _palette = &actorColorsMMC64[id];
-
- _frameOffsets = _baseptr + READ_LE_UINT16(ptr + 5);
- _dataOffsets = ptr;
- _animCmds = _baseptr + READ_LE_UINT16(ptr + 7);
-
- _maxHeight = 0;
- for (int i = 0; i < 8; ++i) {
- int pid = _frameOffsets[_frameOffsets[i]];
- byte p1 = _frameOffsets[pid];
- byte b = _baseptr[p1];
- byte c = b + _dataOffsets[4];
- int offL = _baseptr[b + 2];
- int offH = _baseptr[c];
- int off = (offH << 8) + offL;
- const byte *data = _baseptr + off;
-
- if (data[3] > _maxHeight) {
- _maxHeight = data[3]; // data[3] is libs's Y offset
- }
- }
- ++_maxHeight;
-}
-
-void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
-}
-
-byte C64CostumeLoader::increaseAnims(Actor *a) {
- return 0;
-}
-
-byte C64CostumeLoader::increaseAnim(Actor *a, int slot) {
- return 0;
-}
-
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Costume)
-_GSETPTR(Scumm::smallCostumeScaleTable, GBVARS_SMALLSCALETABLE_INDEX, byte, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Costume)
-_GRELEASEPTR(GBVARS_SMALLSCALETABLE_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/costume.h b/scumm/costume.h
deleted file mode 100644
index 56c97e0a8c..0000000000
--- a/scumm/costume.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef COSTUME_H
-#define COSTUME_H
-
-#include "scumm/base-costume.h"
-
-namespace Scumm {
-
-class ClassicCostumeLoader : public BaseCostumeLoader {
-public:
- int _id;
- const byte *_baseptr;
- const byte *_animCmds;
- const byte *_dataOffsets;
- const byte *_palette;
- const byte *_frameOffsets;
- byte _numColors;
- byte _numAnim;
- byte _format;
- bool _mirror;
-
- ClassicCostumeLoader(ScummEngine *vm) :
- BaseCostumeLoader(vm),
- _id(-1), _baseptr(0), _animCmds(0), _dataOffsets(0), _palette(0),
- _frameOffsets(0), _numColors(0), _numAnim(0), _format(0), _mirror(false) {}
-
- void loadCostume(int id);
- void costumeDecodeData(Actor *a, int frame, uint usemask);
- byte increaseAnims(Actor *a);
-
-protected:
- byte increaseAnim(Actor *a, int slot);
-};
-
-class NESCostumeLoader : public BaseCostumeLoader {
-public:
- int _id;
- const byte *_baseptr;
- const byte *_dataOffsets;
- byte _numAnim;
-
- NESCostumeLoader(ScummEngine *vm) : BaseCostumeLoader(vm) {}
- void loadCostume(int id);
- void costumeDecodeData(Actor *a, int frame, uint usemask);
- byte increaseAnims(Actor *a);
-
-protected:
- byte increaseAnim(Actor *a, int slot);
-};
-
-class C64CostumeLoader : public ClassicCostumeLoader {
-public:
- C64CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {}
- void loadCostume(int id);
- void costumeDecodeData(Actor *a, int frame, uint usemask);
- byte increaseAnims(Actor *a);
-
- int _maxHeight;
-protected:
- byte increaseAnim(Actor *a, int slot);
-};
-
-class ClassicCostumeRenderer : public BaseCostumeRenderer {
-protected:
- ClassicCostumeLoader _loaded;
-
- byte _scaleIndexX; /* must wrap at 256 */
- byte _scaleIndexY;
- byte _palette[32];
-
-public:
- ClassicCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
-
- void setPalette(byte *palette);
- void setFacing(const Actor *a);
- void setCostume(int costume, int shadow);
-
-protected:
- byte drawLimb(const Actor *a, int limb);
-
- void proc3(Codec1 &v1);
- void proc3_ami(Codec1 &v1);
-
- void procC64(Codec1 &v1, int actor);
-
- byte mainRoutine(int xmoveCur, int ymoveCur);
-};
-
-class NESCostumeRenderer : public BaseCostumeRenderer {
-protected:
- NESCostumeLoader _loaded;
-
-public:
- NESCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
-
- void setPalette(byte *palette);
- void setFacing(const Actor *a);
- void setCostume(int costume, int shadow);
-
-protected:
- byte drawLimb(const Actor *a, int limb);
-};
-
-class C64CostumeRenderer : public BaseCostumeRenderer {
-protected:
- C64CostumeLoader _loaded;
-
-public:
- C64CostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {}
-
- void setPalette(byte *palette) {}
- void setFacing(const Actor *a) {}
- void setCostume(int costume, int shadow);
-
-protected:
- byte drawLimb(const Actor *a, int limb);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp
deleted file mode 100644
index 6fee33e79b..0000000000
--- a/scumm/cursor.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "common/util.h"
-#include "scumm/bomp.h"
-#include "scumm/charset.h"
-#include "scumm/intern.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-/*
- * Mouse cursor cycle colors (for the default crosshair).
- */
-static const byte default_v1_cursor_colors[4] = {
- 1, 1, 12, 11
-};
-
-static const byte default_cursor_colors[4] = {
- 15, 15, 7, 8
-};
-
-
-static const uint16 default_cursor_images[4][16] = {
- /* cross-hair */
- { 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000, 0x7e3f,
- 0x0000, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0000 },
- /* hourglass */
- { 0x0000, 0x7ffe, 0x6006, 0x300c, 0x1818, 0x0c30, 0x0660, 0x03c0,
- 0x0660, 0x0c30, 0x1998, 0x33cc, 0x67e6, 0x7ffe, 0x0000, 0x0000 },
- /* arrow */
- { 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x7f00,
- 0x7f80, 0x78c0, 0x7c00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0180 },
- /* hand */
- { 0x1e00, 0x1200, 0x1200, 0x1200, 0x1200, 0x13ff, 0x1249, 0x1249,
- 0xf249, 0x9001, 0x9001, 0x9001, 0x8001, 0x8001, 0x8001, 0xffff },
-};
-
-static const byte default_cursor_hotspots[10] = {
- 8, 7, 8, 7, 1, 1, 5, 0,
- 8, 7, //zak256
-};
-
-static const uint16 default_he_cursor[64] = {
- 0x0000, 0x0000, 0x3800, 0x0000, 0x7e00, 0x0000, 0x5f80, 0x0000,
- 0x5fe0, 0x0000, 0x2ff8, 0x0000, 0x27fe, 0x0000, 0x17ff, 0x8000,
- 0x13ff, 0xe000, 0x09ff, 0xf000, 0x09ff, 0xf800, 0x04ff, 0xf800,
- 0x047f, 0xf000, 0x027f, 0xe000, 0x023f, 0xf000, 0x011f, 0xf800,
- 0x0111, 0xfc00, 0x0080, 0xfc00, 0x0084, 0x0c00, 0x004a, 0x0800,
- 0x0031, 0x1000, 0x0000, 0xe000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-};
-
-static const byte default_v6_cursor[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
- 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, 0x0F,0x0F,0x0F, 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0xFF,
- 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x0F,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x00,0x0F,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-};
-
-ScummEngine_v5::ScummEngine_v5(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine(detector, syst, gs, md5sum, substResFileNameIndex) {
-
- for (int i = 0; i < 4; i++) {
- memcpy(_cursorImages[i], default_cursor_images[i], 32);
- }
- memcpy(_cursorHotspots, default_cursor_hotspots, 8);
-}
-
-
-void ScummEngine::setupCursor() {
- _cursor.animate = 1;
-}
-
-void ScummEngine_v5::animateCursor() {
- if (_cursor.animate) {
- if (!(_cursor.animateIndex & 0x1)) {
- setBuiltinCursor((_cursor.animateIndex >> 1) & 3);
- }
- _cursor.animateIndex++;
- }
-}
-
-void ScummEngine_v6::setCursorHotspot(int x, int y) {
- _cursor.hotspotX = x;
- _cursor.hotspotY = y;
-}
-
-void ScummEngine_v6::setCursorTransparency(int a) {
- int i, size;
-
- size = _cursor.width * _cursor.height;
-
- for (i = 0; i < size; i++)
- if (_grabbedCursor[i] == (byte)a)
- _grabbedCursor[i] = 0xFF;
-
- updateCursor();
-}
-
-void ScummEngine::updateCursor() {
- const int transColor = (_heversion >= 80) ? 5 : 255;
- _system->setMouseCursor(_grabbedCursor, _cursor.width, _cursor.height,
- _cursor.hotspotX, _cursor.hotspotY,
- (_platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
- (_heversion == 70 ? 2 : 1));
-}
-
-void ScummEngine_v6::grabCursor(int x, int y, int w, int h) {
- VirtScreen *vs = findVirtScreen(y);
-
- if (vs == NULL) {
- debug(0, "grabCursor: invalid Y %d", y);
- return;
- }
-
- setCursorFromBuffer((byte *)vs->pixels + (y - vs->topline) * vs->pitch + x, w, h, vs->pitch);
-}
-
-void ScummEngine_v6::setDefaultCursor() {
- setCursorHotspot(7, 6);
- setCursorFromBuffer(default_v6_cursor, 16, 13, 16);
-}
-
-void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, int pitch) {
- uint size;
- byte *dst;
-
- size = width * height;
- if (size > sizeof(_grabbedCursor))
- error("grabCursor: grabbed cursor too big");
-
- _cursor.width = width;
- _cursor.height = height;
- _cursor.animate = 0;
-
- dst = _grabbedCursor;
- for (; height; height--) {
- memcpy(dst, ptr, width);
- dst += width;
- ptr += pitch;
- }
-
- updateCursor();
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v70he::setCursorFromImg(uint img, uint room, uint imgindex) {
- _resExtractor->setCursor(img);
-}
-
-void ScummEngine_v90he::setDefaultCursor() {
- const uint16 *src;
- int i, j;
- static byte palette[] = { 0xff, 0xff, 0xff, 0,
- 0, 0, 0, 0};
-
- memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
-
- _cursor.hotspotX = _cursor.hotspotY = 2;
- src = default_he_cursor;
-
- _cursor.width = 32;
- _cursor.height = 32;
-
- for (i = 0; i < 32; i++) {
- for (j = 0; j < 32; j++) {
- if (*src & (1 << (15 - (j % 16))))
- _grabbedCursor[32 * i + j] = 0xfe;
- if (j == 15)
- src++;
- }
- src++;
- }
-
- // Since white color position is not guaranteed
- // we setup our own palette if supported by backend
- if (_system->hasFeature(OSystem::kFeatureCursorHasPalette))
- _system->setCursorPalette(palette, 0xfe, 2);
-
- updateCursor();
-}
-#endif
-
-void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) {
- int w, h;
- const byte *dataptr, *bomp;
- uint32 size;
- FindObjectInRoom foir;
- const ImageHeader *imhd;
-
- if (room == (uint) - 1)
- room = getObjectRoom(img);
-
- findObjectInRoom(&foir, foCodeHeader | foImageHeader | foCheckAlreadyLoaded, img, room);
- imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), foir.obim);
-
- if (_version == 8) {
- setCursorHotspot(READ_LE_UINT32(&imhd->v8.hotspot[0].x),
- READ_LE_UINT32(&imhd->v8.hotspot[0].y));
- w = READ_LE_UINT32(&imhd->v8.width) / 8;
- h = READ_LE_UINT32(&imhd->v8.height) / 8;
- } else if (_version == 7) {
- setCursorHotspot(READ_LE_UINT16(&imhd->v7.hotspot[0].x),
- READ_LE_UINT16(&imhd->v7.hotspot[0].y));
- w = READ_LE_UINT16(&imhd->v7.width) / 8;
- h = READ_LE_UINT16(&imhd->v7.height) / 8;
- } else {
- if (_heversion == 0) {
- setCursorHotspot(READ_LE_UINT16(&imhd->old.hotspot[0].x),
- READ_LE_UINT16(&imhd->old.hotspot[0].y));
- }
- w = READ_LE_UINT16(&foir.cdhd->v6.w) / 8;
- h = READ_LE_UINT16(&foir.cdhd->v6.h) / 8;
- }
-
- dataptr = getObjectImage(foir.obim, imgindex);
- assert(dataptr);
- if (_version == 8) {
- bomp = dataptr;
- } else {
- size = READ_BE_UINT32(dataptr + 4);
- if (size > sizeof(_grabbedCursor))
- error("setCursorFromImg: Cursor image too large");
-
- bomp = findResource(MKID('BOMP'), dataptr);
- }
-
- if (bomp != NULL)
- useBompCursor(bomp, w, h);
- else
- useIm01Cursor(dataptr, w, h);
-}
-
-void ScummEngine_v6::useIm01Cursor(const byte *im, int w, int h) {
- VirtScreen *vs = &virtscr[0];
- byte *buf, *dst;
- const byte *src;
- int i;
-
- w *= 8;
- h *= 8;
-
- // Backup the screen content
- dst = buf = (byte *)malloc(w * h);
- src = vs->getPixels(0, 0);
-
- for (i = 0; i < h; i++) {
- memcpy(dst, src, w);
- dst += w;
- src += vs->pitch;
- }
-
- // Do some drawing
- drawBox(0, 0, w - 1, h - 1, 0xFF);
-
- vs->hasTwoBuffers = false;
- gdi.disableZBuffer();
- gdi.drawBitmap(im, vs, _screenStartStrip, 0, w, h, 0, w / 8, 0);
- vs->hasTwoBuffers = true;
- gdi.enableZBuffer();
-
- // Grab the data we just drew and setup the cursor with it
- setCursorFromBuffer(vs->getPixels(0, 0), w, h, vs->pitch);
-
- // Restore the screen content
- src = buf;
- dst = vs->getPixels(0, 0);
-
- for (i = 0; i < h; i++) {
- memcpy(dst, src, w);
- dst += vs->pitch;
- src += w;
- }
-
- free(buf);
-}
-
-void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
- uint size;
-
- width *= 8;
- height *= 8;
-
- size = width * height;
- if (size > sizeof(_grabbedCursor))
- error("useBompCursor: cursor too big (%d)", size);
-
- _cursor.width = width;
- _cursor.height = height;
- _cursor.animate = 0;
-
- // Skip the header
- if (_version == 8) {
- im += 16;
- } else {
- im += 18;
- }
- decompressBomp(_grabbedCursor, im, width, height);
-
- updateCursor();
-}
-
-void ScummEngine_v5::redefineBuiltinCursorFromChar(int index, int chr) {
- // Cursor image in both Looms are based on images from charset.
- if (_gameId != GID_LOOM) {
- // FIXME: Actually: is this opcode ever called by a non-Loom game?
- // Which V3-V5 game besides Loom makes use of custom cursors, ever?
- error("V3--V5 SO_CURSOR_IMAGE(%d,%d) called - tell Fingolfin where you saw this!", index, chr);
- }
-
- assert(index >= 0 && index < 4);
-
-// const int oldID = _charset->getCurID();
-
- if (_version == 3) {
- _charset->setCurID(0);
- } else if (_version >= 4) {
- _charset->setCurID(1);
- }
-
- Graphics::Surface s;
- byte buf[16*17];
- memset(buf, 123, 16*17);
- s.pixels = buf;
- s.w = _charset->getCharWidth(chr);
- s.h = _charset->getFontHeight();
- s.pitch = s.w;
- // s.h = 17 for FM-TOWNS Loom Japanese. Fixes bug #1166917
- assert(s.w <= 16 && s.h <= 17);
- s.bytesPerPixel = 1;
-
- _charset->drawChar(chr, s, 0, 0);
-
- uint16 *ptr = _cursorImages[index];
- memset(ptr, 0, 17 * sizeof(uint16));
- for (int h = 0; h < s.h; h++) {
- for (int w = 0; w < s.w; w++) {
- if (buf[s.pitch * h + w] != 123)
- *ptr |= 1 << (15 - w);
- }
- ptr++;
- }
-
-// _charset->setCurID(oldID);
-}
-
-void ScummEngine_v5::redefineBuiltinCursorHotspot(int index, int x, int y) {
- // Cursor image in both Looms are based on images from charset.
- if (_gameId != GID_LOOM) {
- // FIXME: Actually: is this opcode ever called by a non-Loom game?
- // Which V3-V5 game besides Loom makes use of custom cursors, ever?
- error("V3--V5 SO_CURSOR_HOTSPOT(%d,%d,%d) called - tell Fingolfin where you saw this!", index, x, y);
- }
-
- assert(index >= 0 && index < 4);
-
- _cursorHotspots[index * 2] = x;
- _cursorHotspots[index * 2 + 1] = y;
-}
-
-void ScummEngine_v5::setBuiltinCursor(int idx) {
- int i, j;
- byte color;
-
- memset(_grabbedCursor, 0xFF, sizeof(_grabbedCursor));
-
- if (_version == 1)
- color = default_v1_cursor_colors[idx];
- else
- color = default_cursor_colors[idx];
-
- if (_platform == Common::kPlatformNES) {
- _cursor.width = 8;
- _cursor.height = 8;
- _cursor.hotspotX = 0;
- _cursor.hotspotY = 0;
-
- byte *dst = _grabbedCursor;
- byte *src = &_NESPatTable[0][0xfa * 16];
- byte *palette = _NESPalette[1];
-
- for (i = 0; i < 8; i++) {
- byte c0 = src[i];
- byte c1 = src[i + 8];
- for (j = 0; j < 8; j++)
- *dst++ = palette[((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | ((idx == 3) ? 4 : 0)];
- }
-
- } else if (_version <= 2 && _platform == Common::kPlatformAmiga) {
- _cursor.width = 15;
- _cursor.height = 15;
- _cursor.hotspotX = 7;
- _cursor.hotspotY = 7;
-
- byte *hotspot = _grabbedCursor + _cursor.hotspotY * _cursor.width + _cursor.hotspotX;
-
- // Crosshair, symmetric
- // TODO: Instead of setting this up via code, we should simply extend
- // default_cursor_images to contain this shape.
- for (i = 0; i < 5; i++) {
- *(hotspot - 3 - i) = color;
- *(hotspot + 3 + i) = color;
- *(hotspot - _cursor.width * (3 + i)) = color;
- *(hotspot + _cursor.width * (3 + i)) = color;
- }
-
- // Arrow heads, diagonal lines
- for (i = 1; i <= 2; i++) {
- *(hotspot - _cursor.width * i - (3 + i)) = color;
- *(hotspot + _cursor.width * i - (3 + i)) = color;
- *(hotspot - _cursor.width * i + (3 + i)) = color;
- *(hotspot + _cursor.width * i + (3 + i)) = color;
- *(hotspot - _cursor.width * (3 + i) - i) = color;
- *(hotspot + _cursor.width * (3 + i) - i) = color;
- *(hotspot - _cursor.width * (3 + i) + i) = color;
- *(hotspot + _cursor.width * (3 + i) + i) = color;
- }
- } else if (_version <= 2) {
- _cursor.width = 23;
- _cursor.height = 21;
- _cursor.hotspotX = 11;
- _cursor.hotspotY = 10;
-
- byte *hotspot = _grabbedCursor + _cursor.hotspotY * _cursor.width + _cursor.hotspotX;
-
- // Crosshair, slightly assymetric
- // TODO: Instead of setting this up via code, we should simply extend
- // default_cursor_images to contain this shape.
-
- for (i = 0; i < 7; i++) {
- *(hotspot - 5 - i) = color;
- *(hotspot + 5 + i) = color;
- }
-
- for (i = 0; i < 8; i++) {
- *(hotspot - _cursor.width * (3 + i)) = color;
- *(hotspot + _cursor.width * (3 + i)) = color;
- }
-
- // Arrow heads, diagonal lines
-
- for (i = 1; i <= 3; i++) {
- *(hotspot - _cursor.width * i - 5 - i) = color;
- *(hotspot + _cursor.width * i - 5 - i) = color;
- *(hotspot - _cursor.width * i + 5 + i) = color;
- *(hotspot + _cursor.width * i + 5 + i) = color;
- *(hotspot - _cursor.width * (i + 3) - i) = color;
- *(hotspot - _cursor.width * (i + 3) + i) = color;
- *(hotspot + _cursor.width * (i + 3) - i) = color;
- *(hotspot + _cursor.width * (i + 3) + i) = color;
- }
-
- // Final touches
-
- *(hotspot - _cursor.width - 7) = color;
- *(hotspot - _cursor.width + 7) = color;
- *(hotspot + _cursor.width - 7) = color;
- *(hotspot + _cursor.width + 7) = color;
- *(hotspot - (_cursor.width * 5) - 1) = color;
- *(hotspot - (_cursor.width * 5) + 1) = color;
- *(hotspot + (_cursor.width * 5) - 1) = color;
- *(hotspot + (_cursor.width * 5) + 1) = color;
- } else {
- const uint16 *src;
-
- _cursor.hotspotX = _cursorHotspots[2 * _currentCursor];
- _cursor.hotspotY = _cursorHotspots[2 * _currentCursor + 1];
- src = _cursorImages[_currentCursor];
-
- _cursor.width = 16;
- _cursor.height = 16;
-
- for (i = 0; i < 16; i++) {
- for (j = 0; j < 16; j++) {
- if (src[i] & (1 << j))
- _grabbedCursor[16 * i + 15 - j] = color;
- }
- }
- }
-
- updateCursor();
-}
-
-} // End of namespace Scumm
diff --git a/scumm/debugger.cpp b/scumm/debugger.cpp
deleted file mode 100644
index e14e9a36f0..0000000000
--- a/scumm/debugger.cpp
+++ /dev/null
@@ -1,915 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-#include "common/file.h"
-#include "common/str.h"
-#include "common/system.h"
-#include "common/util.h"
-
-#include "scumm/actor.h"
-#include "scumm/boxes.h"
-#include "scumm/debugger.h"
-#include "scumm/imuse.h"
-#include "scumm/object.h"
-#include "scumm/player_v2.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-
-#include "common/debugger.cpp"
-
-namespace Scumm {
-
-// Debug channel lookup table for Debugger console
-static const dbgChannelDesc debugChannels[] = {
- {"SCRIPTS", "Track script execution", DEBUG_SCRIPTS},
- {"OPCODES", "Track opcode execution", DEBUG_OPCODES},
- {"IMUSE", "Track iMUSE events", DEBUG_IMUSE},
- {"RESOURCE", "Track resource loading/management", DEBUG_RESOURCE},
- {"VARS", "Track variable changes", DEBUG_VARS},
- {"ACTORS", "Actor-related debug", DEBUG_ACTORS},
- {"SOUND", "Sound related debug", DEBUG_SOUND},
- {"INSANE", "Track INSANE", DEBUG_INSANE},
- {"SMUSH", "Track SMUSH", DEBUG_SMUSH}
-};
-
-
-void CDECL debugC(int channel, const char *s, ...) {
- char buf[STRINGBUFLEN];
- va_list va;
-
- // FIXME: Still spew all debug at -d9, for crashes in startup etc.
- // Add setting from commandline ( / abstract channel interface)
- if (!(g_scumm->_debugFlags & channel) && (gDebugLevel < 9))
- return;
-
- va_start(va, s);
- vsnprintf(buf, STRINGBUFLEN, s, va);
- va_end(va);
-
- debug(buf);
-}
-
-ScummDebugger::ScummDebugger(ScummEngine *s)
- : Common::Debugger<ScummDebugger>() {
- _vm = s;
-
- // Register variables
- DVar_Register("debug_countdown", &_frame_countdown, DVAR_INT, 0);
-
- DVar_Register("scumm_speed", &_vm->_fastMode, DVAR_BYTE, 0);
- DVar_Register("scumm_room", &_vm->_currentRoom, DVAR_BYTE, 0);
- DVar_Register("scumm_roomresource", &_vm->_roomResource, DVAR_INT, 0);
- DVar_Register("scumm_vars", &_vm->_scummVars, DVAR_INTARRAY, _vm->_numVariables);
-
- DVar_Register("scumm_gamename", &_vm->_targetName, DVAR_STRING, 0);
- DVar_Register("scumm_exename", &_vm->_baseName, DVAR_STRING, 0);
- DVar_Register("scumm_gameid", &_vm->_gameId, DVAR_BYTE, 0);
-
- // Register commands
- DCmd_Register("continue", &ScummDebugger::Cmd_Exit);
- DCmd_Register("exit", &ScummDebugger::Cmd_Exit);
- DCmd_Register("quit", &ScummDebugger::Cmd_Exit);
- DCmd_Register("restart", &ScummDebugger::Cmd_Restart);
-
- DCmd_Register("actor", &ScummDebugger::Cmd_Actor);
- DCmd_Register("actors", &ScummDebugger::Cmd_PrintActor);
- DCmd_Register("box", &ScummDebugger::Cmd_PrintBox);
- DCmd_Register("matrix", &ScummDebugger::Cmd_PrintBoxMatrix);
- DCmd_Register("camera", &ScummDebugger::Cmd_Camera);
- DCmd_Register("room", &ScummDebugger::Cmd_Room);
- DCmd_Register("objects", &ScummDebugger::Cmd_PrintObjects);
- DCmd_Register("object", &ScummDebugger::Cmd_Object);
- DCmd_Register("script", &ScummDebugger::Cmd_Script);
- DCmd_Register("scr", &ScummDebugger::Cmd_Script);
- DCmd_Register("scripts", &ScummDebugger::Cmd_PrintScript);
- DCmd_Register("importres", &ScummDebugger::Cmd_ImportRes);
-
- if (_vm->_gameId == GID_LOOM)
- DCmd_Register("drafts", &ScummDebugger::Cmd_PrintDraft);
-
- DCmd_Register("loadgame", &ScummDebugger::Cmd_LoadGame);
- DCmd_Register("savegame", &ScummDebugger::Cmd_SaveGame);
-
- DCmd_Register("level", &ScummDebugger::Cmd_DebugLevel);
- DCmd_Register("debug", &ScummDebugger::Cmd_Debug);
- DCmd_Register("help", &ScummDebugger::Cmd_Help);
-
- DCmd_Register("show", &ScummDebugger::Cmd_Show);
- DCmd_Register("hide", &ScummDebugger::Cmd_Hide);
-
- DCmd_Register("imuse", &ScummDebugger::Cmd_IMuse);
-}
-
-ScummDebugger::~ScummDebugger() {} // we need this here for __SYMBIAN32__
-
-void ScummDebugger::preEnter() {
- // Pause sound output
- _old_soundsPaused = _vm->_sound->_soundsPaused;
- _vm->_sound->pauseSounds(true);
-}
-
-void ScummDebugger::postEnter() {
- // Resume previous sound state
- _vm->_sound->pauseSounds(_old_soundsPaused);
-}
-
-///////////////////////////////////////////////////
-// Now the fun stuff:
-
-// Commands
-bool ScummDebugger::Cmd_Exit(int argc, const char **argv) {
- _detach_now = true;
- return false;
-}
-
-bool ScummDebugger::Cmd_Restart(int argc, const char **argv) {
- _vm->restart();
-
- _detach_now = true;
- return false;
-}
-
-bool ScummDebugger::Cmd_IMuse(int argc, const char **argv) {
- if (!_vm->_imuse && !_vm->_musicEngine) {
- DebugPrintf("No iMuse engine is active.\n");
- return true;
- }
-
- if (argc > 1) {
- if (!strcmp(argv[1], "panic")) {
- _vm->_musicEngine->stopAllSounds();
- DebugPrintf("AAAIIIEEEEEE!\n");
- DebugPrintf("Shutting down all music tracks\n");
- return true;
- } else if (!strcmp(argv[1], "play")) {
- if (argc > 2 && (!strcmp(argv[2], "random") || atoi(argv[2]) != 0)) {
- int sound = atoi(argv[2]);
- if (!strcmp(argv[2], "random")) {
- DebugPrintf("Selecting from %d songs...\n", _vm->_numSounds);
- sound = _vm->_rnd.getRandomNumber(_vm->_numSounds);
- }
- _vm->ensureResourceLoaded(rtSound, sound);
- _vm->_musicEngine->startSound(sound);
-
- DebugPrintf("Attempted to start music %d.\n", sound);
- } else {
- DebugPrintf("Specify a music resource # from 1-255.\n");
- }
- return true;
- } else if (!strcmp(argv[1], "stop")) {
- if (argc > 2 && (!strcmp(argv[2], "all") || atoi(argv[2]) != 0)) {
- if (!strcmp(argv[2], "all")) {
- _vm->_musicEngine->stopAllSounds();
- DebugPrintf("Shutting down all music tracks.\n");
- } else {
- _vm->_musicEngine->stopSound(atoi(argv[2]));
- DebugPrintf("Attempted to stop music %d.\n", atoi(argv[2]));
- }
- } else {
- DebugPrintf("Specify a music resource # or \"all\".\n");
- }
- return true;
- }
- }
-
- DebugPrintf("Available iMuse commands:\n");
- DebugPrintf(" panic - Stop all music tracks\n");
- DebugPrintf(" play # - Play a music resource\n");
- DebugPrintf(" stop # - Stop a music resource\n");
- return true;
-}
-
-bool ScummDebugger::Cmd_Room(int argc, const char **argv) {
- if (argc > 1) {
- int room = atoi(argv[1]);
- _vm->_actors[_vm->VAR(_vm->VAR_EGO)]._room = room;
- _vm->_sound->stopAllSounds();
- _vm->startScene(room, 0, 0);
- _vm->_fullRedraw = true;
- return false;
- } else {
- DebugPrintf("Current room: %d [%d] - use 'room <roomnum>' to switch\n", _vm->_currentRoom, _vm->_roomResource);
- return true;
- }
-}
-
-bool ScummDebugger::Cmd_LoadGame(int argc, const char **argv) {
- if (argc > 1) {
- int slot = atoi(argv[1]);
-
- _vm->requestLoad(slot);
-
- _detach_now = true;
- return false;
- }
-
- DebugPrintf("Syntax: loadgame <slotnum>\n");
- return true;
-}
-
-bool ScummDebugger::Cmd_SaveGame(int argc, const char **argv) {
- if (argc > 2) {
- int slot = atoi(argv[1]);
-
- _vm->requestSave(slot, argv[2]);
- } else
- DebugPrintf("Syntax: savegame <slotnum> <name>\n");
-
- return true;
-}
-
-bool ScummDebugger::Cmd_Show(int argc, const char **argv) {
-
- if (argc != 2) {
- DebugPrintf("Syntax: show <parameter>\n");
- return true;
- }
-
- if (!strcmp(argv[1], "hex")) {
- _vm->_hexdumpScripts = true;
- DebugPrintf("Script hex dumping on\n");
- } else if (!strncmp(argv[1], "sta", 3)) {
- _vm->_showStack = 1;
- DebugPrintf("Stack tracing on\n");
- } else {
- DebugPrintf("Unknown show parameter '%s'\nParameters are 'hex' for hex dumping and 'sta' for stack tracing\n", argv[1]);
- }
- return true;
-}
-
-bool ScummDebugger::Cmd_Hide(int argc, const char **argv) {
-
- if (argc != 2) {
- DebugPrintf("Syntax: hide <parameter>\n");
- return true;
- }
-
- if (!strcmp(argv[1], "hex")) {
- _vm->_hexdumpScripts = false;
- DebugPrintf("Script hex dumping off\n");
- } else if (!strncmp(argv[1], "sta", 3)) {
- _vm->_showStack = 0;
- DebugPrintf("Stack tracing off\n");
- } else {
- DebugPrintf("Unknown hide parameter '%s'\nParameters are 'hex' to turn off hex dumping and 'sta' to turn off stack tracing\n", argv[1]);
- }
- return true;
-}
-
-bool ScummDebugger::Cmd_Script(int argc, const char** argv) {
- int scriptnum;
-
- if (argc < 2) {
- DebugPrintf("Syntax: script <scriptnum> <command>\n");
- return true;
- }
-
- scriptnum = atoi(argv[1]);
-
- // FIXME: what is the max range on these?
- // if (scriptnum >= _vm->_numScripts) {
- // DebugPrintf("Script number %d is out of range (range: 1 - %d)\n", scriptnum, _vm->_numScripts);
- // return true;
- //}
-
- if ((!strcmp(argv[2], "kill")) || (!strcmp(argv[2], "stop"))) {
- _vm->stopScript(scriptnum);
- } else if ((!strcmp(argv[2], "run")) || (!strcmp(argv[2], "start"))) {
- _vm->runScript(scriptnum, 0, 0, 0);
- return false;
- } else {
- DebugPrintf("Unknown script command '%s'\nUse <kill/stop | run/start> as command\n", argv[2]);
- }
-
- return true;
-}
-
-bool ScummDebugger::Cmd_ImportRes(int argc, const char** argv) {
- Common::File file;
- uint32 size;
- int resnum;
-
- if (argc != 4) {
- DebugPrintf("Syntax: importres <restype> <filename> <resnum>\n");
- return true;
- }
-
- resnum = atoi(argv[3]);
- // FIXME add bounds check
-
- if (!strncmp(argv[1], "scr", 3)) {
- file.open(argv[2], Common::File::kFileReadMode);
- if (file.isOpen() == false) {
- DebugPrintf("Could not open file %s\n", argv[2]);
- return true;
- }
- if (_vm->_features & GF_SMALL_HEADER) {
- size = file.readUint16LE();
- file.seek(-2, SEEK_CUR);
- } else if (_vm->_features & GF_SMALL_HEADER) {
- if (_vm->_version == 4)
- file.seek(8, SEEK_CUR);
- size = file.readUint32LE();
- file.readUint16LE();
- file.seek(-6, SEEK_CUR);
- } else {
- file.readUint32BE();
- size = file.readUint32BE();
- file.seek(-8, SEEK_CUR);
- }
-
- file.read(_vm->res.createResource(rtScript, resnum, size), size);
-
- } else
- DebugPrintf("Unknown importres type '%s'\n", argv[1]);
- return true;
-}
-
-bool ScummDebugger::Cmd_PrintScript(int argc, const char **argv) {
- int i;
- ScriptSlot *ss = _vm->vm.slot;
- DebugPrintf("+-----------------------------------+\n");
- DebugPrintf("|# | num|offst|sta|typ|fr|rec|fc|cut|\n");
- DebugPrintf("+--+----+-----+---+---+--+---+--+---+\n");
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
- if (ss->number) {
- DebugPrintf("|%2d|%4d|%05x|%3d|%3d|%2d|%3d|%2d|%3d|\n",
- i, ss->number, ss->offs, ss->status, ss->where,
- ss->freezeResistant, ss->recursive,
- ss->freezeCount, ss->cutsceneOverride);
- }
- }
- DebugPrintf("+-----------------------------------+\n");
-
- return true;
-}
-
-bool ScummDebugger::Cmd_Actor(int argc, const char **argv) {
- Actor *a;
- int actnum;
- int value = 0, value2 = 0;
-
- if (argc < 3) {
- DebugPrintf("Syntax: actor <actornum> <command> <parameter>\n");
- return true;
- }
-
- actnum = atoi(argv[1]);
- if (actnum >= _vm->_numActors) {
- DebugPrintf("Actor %d is out of range (range: 1 - %d)\n", actnum, _vm->_numActors);
- return true;
- }
-
- a = &_vm->_actors[actnum];
- if (argc > 3)
- value = atoi(argv[3]);
- if (argc > 4)
- value2 = atoi(argv[4]);
-
- if (!strcmp(argv[2], "animvar")) {
- a->setAnimVar(value, value2);
- DebugPrintf("Actor[%d].animVar[%d] = %d\n", actnum, value, a->getAnimVar(value));
- } else if (!strcmp(argv[2], "anim")) {
- a->animateActor(value);
- DebugPrintf("Actor[%d].animateActor(%d)\n", actnum, value);
- } else if (!strcmp(argv[2], "ignoreboxes")) {
- a->_ignoreBoxes = (value > 0);
- DebugPrintf("Actor[%d].ignoreBoxes = %d\n", actnum, a->_ignoreBoxes);
- } else if (!strcmp(argv[2], "x")) {
- a->putActor(value, a->_pos.y, a->_room);
- DebugPrintf("Actor[%d].x = %d\n", actnum, a->_pos.x);
- _vm->_fullRedraw = true;
- } else if (!strcmp(argv[2], "y")) {
- a->putActor(a->_pos.x, value, a->_room);
- DebugPrintf("Actor[%d].y = %d\n", actnum, a->_pos.y);
- _vm->_fullRedraw = true;
- } else if (!strcmp(argv[2], "_elevation")) {
- a->setElevation(value);
- DebugPrintf("Actor[%d]._elevation = %d\n", actnum, a->getElevation());
- _vm->_fullRedraw = true;
- } else if (!strcmp(argv[2], "costume")) {
- if (value >= _vm->res.num[rtCostume])
- DebugPrintf("Costume not changed as %d exceeds max of %d\n", value, _vm->res.num[rtCostume]);
- else {
- a->setActorCostume(value);
- _vm->_fullRedraw = true;
- DebugPrintf("Actor[%d].costume = %d\n", actnum, a->_costume);
- }
- } else if (!strcmp(argv[2], "name")) {
- DebugPrintf("Name of actor %d: %s\n", actnum, _vm->getObjOrActorName(actnum));
- } else {
- DebugPrintf("Unknown actor command '%s'\nUse <ignoreboxes |costume> as command\n", argv[2]);
- }
-
- return true;
-
-}
-bool ScummDebugger::Cmd_PrintActor(int argc, const char **argv) {
- int i;
- Actor *a;
-
- DebugPrintf("+-----------------------------------------------------------+\n");
- DebugPrintf("|# | x | y | w |elev|cos|box|mov| zp|frm|scl|dir| cls |\n");
- DebugPrintf("+--+----+----+---+----+---+---+---+---+---+---+---+---------+\n");
- for (i = 1; i < _vm->_numActors; i++) {
- a = &_vm->_actors[i];
- if (a->_visible)
- DebugPrintf("|%2d|%4d|%4d|%3d|%4d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|$%08x|\n",
- a->_number, a->_pos.x, a->_pos.y, a->_width, a->getElevation(),
- a->_costume, a->_walkbox, a->_moving, a->_forceClip, a->_frame,
- a->_scalex, a->getFacing(), _vm->_classData[a->_number]);
- }
- DebugPrintf("\n");
- return true;
-}
-
-bool ScummDebugger::Cmd_PrintObjects(int argc, const char **argv) {
- int i;
- ObjectData *o;
- DebugPrintf("Objects in current room\n");
- DebugPrintf("+---------------------------------+------------+\n");
- DebugPrintf("|num | x | y |width|height|state|fl| cls |\n");
- DebugPrintf("+----+----+----+-----+------+-----+--+---------+\n");
-
- for (i = 1; i < _vm->_numLocalObjects ; i++) {
- o = &(_vm->_objs[i]);
- if (o->obj_nr == 0)
- continue;
- DebugPrintf("|%4d|%4d|%4d|%5d|%6d|%5d|%2d|$%08x|\n",
- o->obj_nr, o->x_pos, o->y_pos, o->width, o->height, o->state,
- o->fl_object_index, _vm->_classData[o->obj_nr]);
- }
- DebugPrintf("\n");
-
- return true;
-}
-
-bool ScummDebugger::Cmd_Object(int argc, const char **argv) {
- int i;
- int obj;
-
- if (argc < 3) {
- DebugPrintf("Syntax: object <objectnum> <command> <parameter>\n");
- return true;
- }
-
- obj = atoi(argv[1]);
- if (obj >= _vm->_numGlobalObjects) {
- DebugPrintf("Object %d is out of range (range: 1 - %d)\n", obj, _vm->_numGlobalObjects);
- return true;
- }
-
- if (!strcmp(argv[2], "pickup")) {
- for (i = 0; i < _vm->_numInventory; i++) {
- if (_vm->_inventory[i] == (uint16)obj) {
- _vm->putOwner(obj, _vm->VAR(_vm->VAR_EGO));
- _vm->runInventoryScript(obj);
- return true;
- }
- }
-
- if (argc == 3)
- _vm->addObjectToInventory(obj, _vm->_currentRoom);
- else
- _vm->addObjectToInventory(obj, atoi(argv[3]));
-
- _vm->putOwner(obj, _vm->VAR(_vm->VAR_EGO));
- _vm->putClass(obj, kObjectClassUntouchable, 1);
- _vm->putState(obj, 1);
- _vm->markObjectRectAsDirty(obj);
- _vm->clearDrawObjectQueue();
- _vm->runInventoryScript(obj);
- } else if (!strcmp(argv[2], "state")) {
- _vm->putState(obj, atoi(argv[3]));
- //is BgNeedsRedraw enough?
- _vm->_bgNeedsRedraw = true;
- } else if (!strcmp(argv[2], "name")) {
- DebugPrintf("Name of object %d: %s\n", obj, _vm->getObjOrActorName(obj));
- } else {
- DebugPrintf("Unknown object command '%s'\nUse <pickup | state> as command\n", argv[2]);
- }
-
- return true;
-}
-
-bool ScummDebugger::Cmd_Help(int argc, const char **argv) {
- // console normally has 39 line width
- // wrap around nicely
- int width = 0, size, i;
-
- DebugPrintf("Commands are:\n");
- for (i = 0 ; i < _dcmd_count ; i++) {
- size = strlen(_dcmds[i].name) + 1;
-
- if ((width + size) >= 39) {
- DebugPrintf("\n");
- width = size;
- } else
- width += size;
-
- DebugPrintf("%s ", _dcmds[i].name);
- }
-
- width = 0;
-
- DebugPrintf("\n\nVariables are:\n");
- for (i = 0 ; i < _dvar_count ; i++) {
- size = strlen(_dvars[i].name) + 1;
-
- if ((width + size) >= 39) {
- DebugPrintf("\n");
- width = size;
- } else
- width += size;
-
- DebugPrintf("%s ", _dvars[i].name);
- }
-
- DebugPrintf("\n");
-
- return true;
-}
-
-bool ScummDebugger::Cmd_Debug(int argc, const char **argv) {
- int numChannels = sizeof(debugChannels) / sizeof(dbgChannelDesc);
-
- bool setFlag = false; // Remove or add debug channel?
-
- if ((argc == 1) && (_vm->_debugFlags == 0)) {
- DebugPrintf("No debug flags are enabled\n");
- DebugPrintf("Available Channels: ");
- for (int i = 0; i < numChannels; i++) {
- DebugPrintf("%s, ", debugChannels[i].channel);
- }
- DebugPrintf("\n");
- return true;
- }
-
- if ((argc == 1) && (_vm->_debugFlags > 0)) {
- for (int i = 0; i < numChannels; i++) {
- if (_vm->_debugFlags & debugChannels[i].flag)
- DebugPrintf("%s - %s\n", debugChannels[i].channel,
- debugChannels[i].desc);
- }
- return true;
- }
-
- // Enable or disable channel?
- if (argv[1][0] == '+') {
- setFlag = true;
- } else if (argv[1][0] == '-') {
- setFlag = false;
- } else {
- DebugPrintf("Syntax: Debug +CHANNEL, or Debug -CHANNEL\n");
- DebugPrintf("Available Channels: ");
- for (int i = 0; i < numChannels; i++) {
- DebugPrintf("%s, ", debugChannels[i].channel);
- DebugPrintf("\n");
- }
- }
-
- // Identify flag
- const char *realFlag = argv[1] + 1;
- for (int i = 0; i < numChannels; i++) {
- if ((scumm_stricmp(debugChannels[i].channel, realFlag)) == 0) {
- if (setFlag) {
- _vm->_debugFlags |= debugChannels[i].flag;
- DebugPrintf("Enable ");
- } else {
- _vm->_debugFlags &= ~debugChannels[i].flag;
- DebugPrintf("Disable ");
- }
-
- DebugPrintf("%s\n", debugChannels[i].desc);
- return true;
- }
- }
-
- DebugPrintf("Unknown flag. Type 'Debug ?' for syntax\n");
- return true;
-}
-
-bool ScummDebugger::Cmd_DebugLevel(int argc, const char **argv) {
- if (argc == 1) {
- if (_vm->_debugMode == false)
- DebugPrintf("Debugging is not enabled at this time\n");
- else
- DebugPrintf("Debugging is currently set at level %d\n", gDebugLevel);
- } else { // set level
- gDebugLevel = atoi(argv[1]);
- if (gDebugLevel >= 0) {
- _vm->_debugMode = true;
- DebugPrintf("Debug level set to level %d\n", gDebugLevel);
- } else if (gDebugLevel < 0) {
- _vm->_debugMode = false;
- DebugPrintf("Debugging is now disabled\n");
- } else
- DebugPrintf("Not a valid debug level\n");
- }
-
- return true;
-}
-
-bool ScummDebugger::Cmd_Camera(int argc, const char **argv) {
- DebugPrintf("Camera: cur (%d,%d) - dest (%d,%d) - accel (%d,%d) -- last (%d,%d)\n",
- _vm->camera._cur.x, _vm->camera._cur.y, _vm->camera._dest.x, _vm->camera._dest.y,
- _vm->camera._accel.x, _vm->camera._accel.y, _vm->camera._last.x, _vm->camera._last.y);
-
- return true;
-}
-
-bool ScummDebugger::Cmd_PrintBox(int argc, const char **argv) {
- int num, i = 0;
-
- if (argc > 1) {
- for (i = 1; i < argc; i++)
- printBox(atoi(argv[i]));
- } else {
- num = _vm->getNumBoxes();
- DebugPrintf("\nWalk boxes:\n");
- for (i = 0; i < num; i++)
- printBox(i);
- }
- return true;
-}
-
-bool ScummDebugger::Cmd_PrintBoxMatrix(int argc, const char **argv) {
- byte *boxm = _vm->getBoxMatrixBaseAddr();
- int num = _vm->getNumBoxes();
- int i, j;
-
- DebugPrintf("Walk matrix:\n");
- if (_vm->_version <= 2)
- boxm += num;
- for (i = 0; i < num; i++) {
- DebugPrintf("%d: ", i);
- if (_vm->_version <= 2) {
- for (j = 0; j < num; j++)
- DebugPrintf("[%d] ", *boxm++);
- } else {
- while (*boxm != 0xFF) {
- DebugPrintf("[%d-%d=>%d] ", boxm[0], boxm[1], boxm[2]);
- boxm += 3;
- }
- boxm++;
- }
- DebugPrintf("\n");
- }
- return true;
-}
-
-void ScummDebugger::printBox(int box) {
- if (box < 0 || box >= _vm->getNumBoxes()) {
- DebugPrintf("%d is not a valid box!\n", box);
- return;
- }
- BoxCoords coords;
- int flags = _vm->getBoxFlags(box);
- int mask = _vm->getMaskFromBox(box);
- int scale = _vm->getBoxScale(box);
-
- _vm->getBoxCoordinates(box, &coords);
-
- // Print out coords, flags, zbuffer mask
- DebugPrintf("%d: [%d x %d] [%d x %d] [%d x %d] [%d x %d], flags=0x%02x, mask=%d, scale=%d\n",
- box,
- coords.ul.x, coords.ul.y, coords.ll.x, coords.ll.y,
- coords.ur.x, coords.ur.y, coords.lr.x, coords.lr.y,
- flags, mask, scale);
-
- // Draw the box
- drawBox(box);
-}
-
-/************ ENDER: Temporary debug code for boxen **************/
-
-static int gfxPrimitivesCompareInt(const void *a, const void *b);
-
-
-static void hlineColor(ScummEngine *scumm, int x1, int x2, int y, byte color) {
- VirtScreen *vs = &scumm->virtscr[0];
- byte *ptr;
-
- // Clip y
- y += scumm->_screenTop;
- if (y < 0 || y >= scumm->_screenHeight)
- return;
-
- if (x2 < x1)
- SWAP(x2, x1);
-
- // Clip x1 / x2
- const int left = scumm->_screenStartStrip * 8;
- const int right = scumm->_screenEndStrip * 8;
- if (x1 < left)
- x1 = left;
- if (x2 >= right)
- x2 = right - 1;
-
-
- ptr = (byte *)vs->pixels + x1 + y * vs->pitch;
-
- while (x1++ <= x2) {
- *ptr++ = color;
- }
-}
-
-static int gfxPrimitivesCompareInt(const void *a, const void *b) {
- return (*(const int *)a) - (*(const int *)b);
-}
-
-static void fillQuad(ScummEngine *scumm, Common::Point v[4], int color) {
- const int N = 4;
- int i;
- int y;
- int miny, maxy;
- Common::Point pt1, pt2;
-
- int polyInts[N];
-
-
- // Determine Y maxima
- miny = maxy = v[0].y;
- for (i = 1; i < N; i++) {
- if (v[i].y < miny) {
- miny = v[i].y;
- } else if (v[i].y > maxy) {
- maxy = v[i].y;
- }
- }
-
- // Draw, scanning y
- for (y = miny; y <= maxy; y++) {
- int ints = 0;
- for (i = 0; i < N; i++) {
- int ind1 = i;
- int ind2 = (i + 1) % N;
- pt1 = v[ind1];
- pt2 = v[ind2];
- if (pt1.y > pt2.y) {
- SWAP(pt1, pt2);
- }
-
- if (pt1.y <= y && y <= pt2.y) {
- if (y == pt1.y && y == pt2.y) {
- hlineColor(scumm, pt1.x, pt2.x, y, color);
- } else if ((y >= pt1.y) && (y < pt2.y)) {
- polyInts[ints++] = (y - pt1.y) * (pt2.x - pt1.x) / (pt2.y - pt1.y) + pt1.x;
- } else if ((y == maxy) && (y > pt1.y) && (y <= pt2.y)) {
- polyInts[ints++] = (y - pt1.y) * (pt2.x - pt1.x) / (pt2.y - pt1.y) + pt1.x;
- }
- }
- }
- qsort(polyInts, ints, sizeof(int), gfxPrimitivesCompareInt);
-
- for (i = 0; i < ints; i += 2) {
- hlineColor(scumm, polyInts[i], polyInts[i + 1], y, color);
- }
- }
-
- return;
-}
-
-void ScummDebugger::drawBox(int box) {
- BoxCoords coords;
- Common::Point r[4];
-
- _vm->getBoxCoordinates(box, &coords);
-
- r[0] = coords.ul;
- r[1] = coords.ur;
- r[2] = coords.lr;
- r[3] = coords.ll;
-
- // TODO - maybe use different colors for each box, and/or print the box number inside it?
- fillQuad(_vm, r, 13);
-
- VirtScreen *vs = _vm->findVirtScreen(coords.ul.y);
- if (vs != NULL)
- _vm->markRectAsDirty(vs->number, 0, vs->w, 0, vs->h);
- _vm->drawDirtyScreenParts();
- _vm->_system->updateScreen();
-}
-
-bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) {
- const char *names[] = {
- "Opening", "Straw to Gold", "Dyeing",
- "Night Vision", "Twisting", "Sleep",
- "Emptying", "Invisibility", "Terror",
- "Sharpening", "Reflection", "Healing",
- "Silence", "Shaping", "Unmaking",
- "Transcendence"
- };
- int odds[] = {
- 15162, 15676, 16190, 64, 16961, 17475, 17989, 18503,
- 73, 19274, 76, 77, 20302, 20816, 21330, 84
- };
-
- const char *notes = "cdefgabC";
- int i, base, draft;
-
- if (_vm->_gameId != GID_LOOM) {
- DebugPrintf("Command only works with Loom/LoomCD\n");
- return true;
- }
-
- // There are 16 drafts, stored from variable 50 or 100 and upwards.
- // Each draft occupies two variables. Even-numbered variables contain
- // the notes for each draft, and a number of flags:
- //
- // +---+---+---+---+-----+-----+-----+-----+
- // | A | B | C | D | 444 | 333 | 222 | 111 |
- // +---+---+---+---+-----+-----+-----+-----+
- //
- // A Unknown
- // B The player has used the draft successfully at least once
- // C The player has knowledge of the draft
- // D Unknown
- // 444 The fourth note
- // 333 The third note
- // 222 The second note
- // 111 The first note
- //
- // I don't yet know what the odd-numbered variables are used for.
- // Possibly they store information on where and/or how the draft can
- // be used. They appear to remain constant throughout the game.
-
- base = (_vm->_version == 3) ? 50 : 100;
-
- if (argc == 2) {
- // We had to debug a problem at the end of the game that only
- // happened if you interrupted the intro at a specific point.
- // That made it useful with a command to learn all the drafts
- // and notes.
-
- if (strcmp(argv[1], "learn") == 0) {
- for (i = 0; i < 16; i++)
- _vm->_scummVars[base + 2 * i] |= 0x2000;
- _vm->_scummVars[base + 72] = 8;
-
- // In theory, we could run script 18 here to redraw
- // the distaff, but I don't know if that's a safe
- // thing to do.
-
- DebugPrintf("Learned all drafts and notes.\n");
- return true;
- }
-
- // During the testing of EGA Loom we had some trouble with the
- // drafts data structure being overwritten. I don't expect
- // this command is particularly useful any more, but it will
- // attempt to repair the (probably) static part of it.
-
- if (strcmp(argv[1], "fix") == 0) {
- for (i = 0; i < 16; i++)
- _vm->_scummVars[base + 2 * i + 1] = odds[i];
- DebugPrintf(
- "An attempt has been made to repair\n"
- "the internal drafts data structure.\n"
- "Continue on your own risk.\n");
- return true;
- }
- }
-
- // Probably the most useful command for ordinary use: list the drafts.
-
- for (i = 0; i < 16; i++) {
- draft = _vm->_scummVars[base + i * 2];
- DebugPrintf("%d %-13s %c%c%c%c %c%c %5d %c\n",
- base + 2 * i,
- names[i],
- notes[draft & 0x0007],
- notes[(draft & 0x0038) >> 3],
- notes[(draft & 0x01c0) >> 6],
- notes[(draft & 0x0e00) >> 9],
- (draft & 0x2000) ? 'K' : ' ',
- (draft & 0x4000) ? 'U' : ' ',
- _vm->_scummVars[base + 2 * i + 1],
- (_vm->_scummVars[base + 2 * i + 1] != odds[i]) ? '!' : ' ');
- }
-
- return true;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/debugger.h b/scumm/debugger.h
deleted file mode 100644
index 664c28923d..0000000000
--- a/scumm/debugger.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef DEBUGGER_H
-#define DEBUGGER_H
-
-#include "common/debugger.h"
-
-namespace Scumm {
-
-class ScummEngine;
-
-class ScummDebugger : public Common::Debugger<ScummDebugger> {
-public:
- ScummDebugger(ScummEngine *s);
- virtual ~ScummDebugger(); // we need this here for __SYMBIAN32__
-
-protected:
- ScummEngine *_vm;
- bool _old_soundsPaused;
-
- virtual void preEnter();
- virtual void postEnter();
-
- // Commands
- bool Cmd_Exit(int argc, const char **argv);
- bool Cmd_Room(int argc, const char **argv);
- bool Cmd_LoadGame(int argc, const char **argv);
- bool Cmd_SaveGame(int argc, const char **argv);
- bool Cmd_Restart(int argc, const char **argv);
-
- bool Cmd_PrintActor(int argc, const char **argv);
- bool Cmd_PrintBox(int argc, const char **argv);
- bool Cmd_PrintBoxMatrix(int argc, const char **argv);
- bool Cmd_PrintObjects(int argc, const char **argv);
- bool Cmd_Actor(int argc, const char **argv);
- bool Cmd_Camera(int argc, const char **argv);
- bool Cmd_Object(int argc, const char **argv);
- bool Cmd_Script(int argc, const char **argv);
- bool Cmd_PrintScript(int argc, const char **argv);
- bool Cmd_ImportRes(int argc, const char **argv);
-
- bool Cmd_PrintDraft(int argc, const char **argv);
-
- bool Cmd_Debug(int argc, const char **argv);
- bool Cmd_DebugLevel(int argc, const char **argv);
- bool Cmd_Help(int argc, const char **argv);
-
- bool Cmd_Show(int argc, const char **argv);
- bool Cmd_Hide(int argc, const char **argv);
-
- bool Cmd_IMuse (int argc, const char **argv);
-
- void printBox(int box);
- void drawBox(int box);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/dialogs.cpp b/scumm/dialogs.cpp
deleted file mode 100644
index eafd956251..0000000000
--- a/scumm/dialogs.cpp
+++ /dev/null
@@ -1,986 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-#include "common/savefile.h"
-#include "common/system.h"
-#include "common/scaler.h"
-
-#include "gui/about.h"
-#include "gui/chooser.h"
-#include "gui/newgui.h"
-#include "gui/ListWidget.h"
-
-#include "scumm/dialogs.h"
-#include "scumm/sound.h"
-#include "scumm/scumm.h"
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/player_v2.h"
-#include "scumm/verbs.h"
-#include "sound/mididrv.h"
-#include "sound/mixer.h"
-
-#ifndef DISABLE_HELP
-#include "scumm/help.h"
-#endif
-
-#ifdef SMALL_SCREEN_DEVICE
-#include "KeysDialog.h"
-#endif
-
-using GUI::CommandSender;
-using GUI::StaticTextWidget;
-using GUI::kButtonWidth;
-using GUI::kButtonHeight;
-using GUI::kBigButtonWidth;
-using GUI::kBigButtonHeight;
-using GUI::kCloseCmd;
-using GUI::kTextAlignCenter;
-using GUI::kTextAlignLeft;
-using GUI::WIDGET_ENABLED;
-
-typedef GUI::OptionsDialog GUI_OptionsDialog;
-typedef GUI::ChooserDialog GUI_ChooserDialog;
-typedef GUI::Dialog GUI_Dialog;
-
-namespace Scumm {
-
-struct ResString {
- int num;
- char string[80];
-};
-
-#ifdef PALMOS_68K
-static ResString *string_map_table_v7;
-static ResString *string_map_table_v6;
-static ResString *string_map_table_v5;
-#else
-static ResString string_map_table_v7[] = {
- {96, "game name and version"}, //that's how it's supposed to be
- {77, "Select a game to LOAD"},
- {76, "Name your SAVE game"},
- {70, "save"}, //boot8
- {71, "load"}, //boot9
- {72, "play"}, //boot10
- {73, "cancel"}, //boot11
- {74, "quit"}, //boot12
- {75, "ok"}, //boot13
- {85, "game paused"}, // boot3
- {96, "the dig v1.0"},
-
- /* this is the almost complete string map for v7
- {63, "how may I serve you?"},
- {64, "the dig v1.0"}, //(game name/version)
- {67, "text display only"},
- {68, "c:\\dig"}, //boot007 (save path ?)
- {69, "the dig"}, //boot21 (game name)
- {70, "save"}, //boot8
- {71, "load"}, //boot9
- {72, "play"}, //boot10
- {73, "cancel"}, //boot11
- {74, "quit"}, //boot12
- {75, "ok"}, //boot13
- {76, "name your save game"}, //boot19
- {77, "select a game to load"}, //boot20
- {78, "you must enter a name"},//boot14
- {79, "saving '%s'"}, //boot17
- {80, "loading '%s'"}, //boot18
- {81, "the game was NOT saved"}, //boot15
- {82, "the game was NOT loaded"}, //boot16
- {83, "how may I serve you?"},
- {84, "how may I serve you?"},
- {85, "game paused"}, // boot3
- {86, "Are you sure you want to restart"},
- {87, "Are you sure you want to quit?"}, //boot05
- {89, "how may I serve you?"},
- {90, "music"}, //boot22
- {91, "voice"}, //boot23
- {92, "sfx"}, //boot24
- {93, "disabled"}, //boot25
- {94, "text speed"}, //boot26
- {95, "text display"}, //boot27
- {96, "the dig v1.0"},*/
-
-};
-
-static ResString string_map_table_v6[] = {
- {117, "How may I serve you?"},
- {109, "Select a game to LOAD"},
- {108, "Name your SAVE game"},
- {96, "Save"},
- {97, "Load"},
- {98, "Play"},
- {99, "Cancel"},
- {100, "Quit"},
- {101, "OK"},
- {93, "Game paused"},
- {210, "Game version"}
-};
-
-static ResString string_map_table_v5[] = {
- {28, "How may I serve you?"},
- {20, "Select a game to LOAD"},
- {19, "Name your SAVE game"},
- {7, "Save"},
- {8, "Load"},
- {9, "Play"},
- {10, "Cancel"},
- {11, "Quit"},
- {12, "OK"},
- {4, "Game paused"}
-};
-#endif
-
-#pragma mark -
-
-ScummDialog::ScummDialog(ScummEngine *scumm, int x, int y, int w, int h)
- : GUI::Dialog(x, y, w, h), _vm(scumm) {
-_drawingHints |= GUI::THEME_HINT_SPECIAL_COLOR;
-}
-
-const Common::String ScummDialog::queryResString(int stringno) {
- byte buf[256];
- byte *result;
-
- if (stringno == 0)
- return String();
-
- if (_vm->_version >= 7)
- result = _vm->getStringAddressVar(string_map_table_v7[stringno - 1].num);
- else if (_vm->_version == 6)
- result = _vm->getStringAddressVar(string_map_table_v6[stringno - 1].num);
- else if (_vm->_version == 5)
- result = _vm->getStringAddress(string_map_table_v5[stringno - 1].num);
- else
- // TODO: For V8 games, maybe grab the strings from the language file?
- return string_map_table_v5[stringno - 1].string;
-
- if (result && *result == '/') {
- _vm->translateText(result, buf);
- result = buf;
- }
-
- if (!result || *result == '\0') { // Gracelessly degrade to english :)
- return string_map_table_v5[stringno - 1].string;
- }
-
- // Convert to a proper string (take care of FF codes)
- byte chr;
- String tmp;
- while ((chr = *result++)) {
- if (chr == 0xFF) {
- result += 3;
- } else if (chr != '@') {
- tmp += chr;
- }
- }
- return tmp;
-}
-
-#pragma mark -
-
-Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode);
-
-enum {
- kSaveCmd = 'SAVE',
- kLoadCmd = 'LOAD',
- kPlayCmd = 'PLAY',
- kOptionsCmd = 'OPTN',
- kHelpCmd = 'HELP',
- kAboutCmd = 'ABOU',
- kQuitCmd = 'QUIT'
-};
-
-class SaveLoadChooser : public GUI::ChooserDialog, public BaseSaveLoadChooser {
- typedef Common::String String;
- typedef Common::StringList StringList;
-protected:
- bool _saveMode;
-
-public:
- SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode);
-
- virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
- const String &getResultString() const;
- void setList(const StringList& list) { GUI_ChooserDialog::setList(list); }
- int runModal() { return GUI_ChooserDialog::runModal(); }
-};
-
-SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode)
- : GUI::ChooserDialog(title, buttonLabel, 182), _saveMode(saveMode) {
-
- _list->setEditable(saveMode);
- _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
-}
-
-const Common::String &SaveLoadChooser::getResultString() const {
- return _list->getSelectedString();
-}
-
-void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
- int selItem = _list->getSelected();
- switch (cmd) {
- case GUI::kListItemActivatedCmd:
- case GUI::kListItemDoubleClickedCmd:
- if (selItem >= 0) {
- if (_saveMode || !getResultString().isEmpty()) {
- setResult(selItem);
- close();
- }
- }
- break;
- case GUI::kListSelectionChangedCmd:
- if (_saveMode) {
- _list->startEditMode();
- }
- // Disable button if nothing is selected, or (in load mode) if an empty
- // list item is selected. We allow choosing an empty item in save mode
- // because we then just assign a default name.
- _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty()));
- _chooseButton->draw();
- break;
- default:
- GUI_ChooserDialog::handleCommand(sender, cmd, data);
- }
-}
-
-#pragma mark -
-
-enum {
- kChooseCmd = 'Chos'
-};
-
-// only for use with >= 640x400 resolutions
-class SaveLoadChooserEx : public GUI::Dialog, public BaseSaveLoadChooser {
- typedef Common::String String;
- typedef Common::StringList StringList;
-protected:
- bool _saveMode;
- GUI::ListWidget *_list;
- GUI::ButtonWidget *_chooseButton;
- GUI::GraphicsWidget *_gfxWidget;
- GUI::StaticTextWidget *_date;
- GUI::StaticTextWidget *_time;
- GUI::StaticTextWidget *_playtime;
- ScummEngine *_scumm;
-
-public:
- SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine);
-
- virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
- const String &getResultString() const;
- void setList(const StringList& list);
- int runModal();
-};
-
-SaveLoadChooserEx::SaveLoadChooserEx(const String &title, const String &buttonLabel, bool saveMode, ScummEngine *engine)
- : Dialog(8, 8, engine->_system->getOverlayWidth() - 2 * 8, engine->_system->getOverlayHeight() - 16), _saveMode(saveMode), _list(0), _chooseButton(0), _gfxWidget(0), _scumm(engine) {
-
- new StaticTextWidget(this, 10, 6, _w - 2 * 10, kLineHeight, title, kTextAlignCenter);
-
- // Add choice list
- _list = new GUI::ListWidget(this, 10, 18, _w - 2 * 10 - 180, _h - 14 - kBigButtonHeight - 18, GUI::kBigWidgetSize);
- _list->setEditable(saveMode);
- _list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
-
- // Add the thumbnail display
- _gfxWidget = new GUI::GraphicsWidget(this,
- _w - (kThumbnailWidth + 22),
- 18,
- kThumbnailWidth + 8,
- ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8);
- _gfxWidget->setFlags(GUI::WIDGET_BORDER);
-
- int height = 18 + ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8;
-
- _date = new StaticTextWidget(this,
- _w - (kThumbnailWidth + 22),
- height,
- kThumbnailWidth + 8,
- kLineHeight,
- "No date saved",
- kTextAlignCenter);
- _date->setFlags(GUI::WIDGET_CLEARBG);
-
- height += kLineHeight;
-
- _time = new StaticTextWidget(this,
- _w - (kThumbnailWidth + 22),
- height,
- kThumbnailWidth + 8,
- kLineHeight,
- "No time saved",
- kTextAlignCenter);
- _time->setFlags(GUI::WIDGET_CLEARBG);
-
- height += kLineHeight;
-
- _playtime = new StaticTextWidget(this,
- _w - (kThumbnailWidth + 22),
- height,
- kThumbnailWidth + 8,
- kLineHeight,
- "No playtime saved",
- kTextAlignCenter);
- _playtime->setFlags(GUI::WIDGET_CLEARBG);
-
- // Buttons
- addButton(this, _w - 2 * (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, "Cancel", kCloseCmd, 0, GUI::kBigWidgetSize);
- _chooseButton = addButton(this, _w - (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, buttonLabel, kChooseCmd, 0, GUI::kBigWidgetSize);
- _chooseButton->setEnabled(false);
-}
-
-const Common::String &SaveLoadChooserEx::getResultString() const {
- return _list->getSelectedString();
-}
-
-void SaveLoadChooserEx::setList(const StringList& list) {
- _list->setList(list);
-}
-
-int SaveLoadChooserEx::runModal() {
- _gfxWidget->setGfx(0);
- int ret = Dialog::runModal();
- return ret;
-}
-
-void SaveLoadChooserEx::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
- int selItem = _list->getSelected();
- switch (cmd) {
- case GUI::kListItemActivatedCmd:
- case GUI::kListItemDoubleClickedCmd:
- if (selItem >= 0) {
- if (_saveMode || !getResultString().isEmpty()) {
- _list->endEditMode();
- setResult(selItem);
- close();
- }
- }
- break;
- case kChooseCmd:
- _list->endEditMode();
- setResult(selItem);
- close();
- break;
- case GUI::kListSelectionChangedCmd: {
- Graphics::Surface *thumb;
- thumb = _scumm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
- _gfxWidget->setGfx(thumb);
- if (thumb)
- thumb->free();
- delete thumb;
- _gfxWidget->draw();
-
- InfoStuff infos;
- memset(&infos, 0, sizeof(InfoStuff));
- char buffer[32];
- if (_scumm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) {
- snprintf(buffer, 32, "Date: %.2d.%.2d.%.4d",
- (infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF,
- infos.date & 0xFFFF);
- _date->setLabel(buffer);
- _date->draw();
-
- snprintf(buffer, 32, "Time: %.2d:%.2d",
- (infos.time >> 8) & 0xFF, infos.time & 0xFF);
- _time->setLabel(buffer);
- _time->draw();
-
- int minutes = infos.playtime / 60;
- int hours = minutes / 60;
- minutes %= 60;
-
- snprintf(buffer, 32, "Playtime: %.2d:%.2d",
- hours & 0xFF, minutes & 0xFF);
- _playtime->setLabel(buffer);
- _playtime->draw();
- } else {
- snprintf(buffer, 32, "No date saved");
- _date->setLabel(buffer);
- _date->draw();
-
- snprintf(buffer, 32, "No time saved");
- _time->setLabel(buffer);
- _time->draw();
-
- snprintf(buffer, 32, "No playtime saved");
- _playtime->setLabel(buffer);
- _playtime->draw();
- }
-
- if (_saveMode) {
- _list->startEditMode();
- }
- // Disable button if nothing is selected, or (in load mode) if an empty
- // list item is selected. We allow choosing an empty item in save mode
- // because we then just assign a default name.
- _chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty()));
- _chooseButton->draw();
- } break;
- case kCloseCmd:
- setResult(-1);
- default:
- Dialog::handleCommand(sender, cmd, data);
- }
-}
-
-#pragma mark -
-
-Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
- // Get savegame names
- Common::StringList l;
- char name[32];
- uint i = saveMode ? 1 : 0;
- bool avail_saves[81];
-
- scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves));
- for (; i < ARRAYSIZE(avail_saves); i++) {
- if (avail_saves[i])
- scumm->getSavegameName(i, name);
- else
- name[0] = 0;
- l.push_back(name);
- }
-
- return l;
-}
-
-#define addBigButton(label, cmd, hotkey) \
- new GUI::ButtonWidget(this, hOffset, y, buttonWidth, buttonHeight, label, cmd, hotkey, ws); \
- y += (buttonHeight + vAddOff)
-
-MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
- : ScummDialog(scumm, 0, 0, 0, 0) {
-
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
-
- int hOffset;
- int vSpace;
- int vAddOff;
-
- GUI::WidgetSize ws;
- int buttonWidth;
- int buttonHeight;
-
- if (screenW >= 400 && screenH >= 300) {
- buttonWidth = 160;
- buttonHeight = 28;
- ws = GUI::kBigWidgetSize;
- hOffset = 12;
- vSpace = 7;
- vAddOff = 3;
- } else {
- buttonWidth = 90;
- buttonHeight = 16;
- ws = GUI::kNormalWidgetSize;
- hOffset = 8;
- vSpace = 5;
- vAddOff = 2;
- }
-
- int y = vSpace + vAddOff;
-
-
- addBigButton("Resume", kPlayCmd, 'P');
- y += vSpace;
-
- addBigButton("Load", kLoadCmd, 'L');
- addBigButton("Save", kSaveCmd, 'S');
- y += vSpace;
-
- addBigButton("Options", kOptionsCmd, 'O');
-#ifndef DISABLE_HELP
- addBigButton("Help", kHelpCmd, 'H');
-#endif
- addBigButton("About", kAboutCmd, 'A');
- y += vSpace;
-
- addBigButton("Quit", kQuitCmd, 'Q');
-
-
- _w = buttonWidth + 2 * hOffset;
- _h = y + vSpace;
-
- _x = (screenW - _w) / 2;
- _y = (screenH - _h) / 2;
-
-
- //
- // Create the sub dialog(s)
- //
- _aboutDialog = new GUI::AboutDialog();
- _optionsDialog = new ConfigDialog(scumm);
-#ifndef DISABLE_HELP
- _helpDialog = new HelpDialog(scumm);
-#endif
- if (scumm->_system->getOverlayWidth() <= 320) {
- _saveDialog = new SaveLoadChooser("Save game:", "Save", true);
- _loadDialog = new SaveLoadChooser("Load game:", "Load", false);
- } else {
- _saveDialog = new SaveLoadChooserEx("Save game:", "Save", true, scumm);
- _loadDialog = new SaveLoadChooserEx("Load game:", "Load", false, scumm);
- }
-}
-
-MainMenuDialog::~MainMenuDialog() {
- delete _aboutDialog;
- delete _optionsDialog;
-#ifndef DISABLE_HELP
- delete _helpDialog;
-#endif
- delete _saveDialog;
- delete _loadDialog;
-}
-
-void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
- switch (cmd) {
- case kSaveCmd:
- save();
- break;
- case kLoadCmd:
- load();
- break;
- case kPlayCmd:
- close();
- break;
- case kOptionsCmd:
- _optionsDialog->runModal();
- break;
- case kAboutCmd:
- _aboutDialog->runModal();
- break;
-#ifndef DISABLE_HELP
- case kHelpCmd:
- _helpDialog->runModal();
- break;
-#endif
- case kQuitCmd:
- _vm->_quit = true;
- close();
- break;
- default:
- ScummDialog::handleCommand(sender, cmd, data);
- }
-}
-
-void MainMenuDialog::save() {
- int idx;
- _saveDialog->setList(generateSavegameList(_vm, true));
- idx = _saveDialog->runModal();
- if (idx >= 0) {
- const String &result = _saveDialog->getResultString();
- char buffer[20];
- const char *str;
- if (result.isEmpty()) {
- // If the user was lazy and entered no save name, come up with a default name.
- sprintf(buffer, "Save %d", idx + 1);
- str = buffer;
- } else
- str = result.c_str();
- _vm->requestSave(idx + 1, str);
- close();
- }
-}
-
-void MainMenuDialog::load() {
- int idx;
- _loadDialog->setList(generateSavegameList(_vm, false));
- idx = _loadDialog->runModal();
- if (idx >= 0) {
- _vm->requestLoad(idx);
- close();
- }
-}
-
-#pragma mark -
-
-enum {
- kOKCmd = 'ok '
-};
-
-enum {
- kKeysCmd = 'KEYS'
-};
-
-ConfigDialog::ConfigDialog(ScummEngine *scumm)
- : GUI::OptionsDialog("", 40, 30, 240, 124), _vm(scumm) {
-
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
-
- _w = screenW - 2 * 40;
-
- GUI::WidgetSize ws;
- int buttonWidth;
- int buttonHeight;
-
- if (screenW >= 400 && screenH >= 300) {
- ws = GUI::kBigWidgetSize;
- buttonWidth = kBigButtonWidth;
- buttonHeight = kBigButtonHeight;
- } else {
- ws = GUI::kNormalWidgetSize;
- buttonWidth = kButtonWidth;
- buttonHeight = kButtonHeight;
- }
-
- int yoffset = 8;
-
- //
- // Sound controllers
- //
-
- yoffset = addVolumeControls(this, yoffset, ws) + 4;
-
- //
- // Some misc options
- //
-
- _subtitlesCheckbox = addCheckbox(this, 15, yoffset, "Show subtitles", 0, 'S', ws);
- yoffset += _subtitlesCheckbox->getHeight();
-
- _speechCheckbox = addCheckbox(this, 15, yoffset, "Enable speech", 0, 'E', ws);
- yoffset += _speechCheckbox->getHeight() + 4;
-
- //
- // Add the buttons
- //
-
- _w = 8 + 3 * (buttonWidth + 4); // FIXME/TODO
-
- addButton(this, _w - (buttonWidth + 4) - 4, yoffset, "OK", GUI::OptionsDialog::kOKCmd, 'O', ws);
- addButton(this, _w - 2 * (buttonWidth + 4) - 4, yoffset, "Cancel", kCloseCmd, 'C', ws);
-#ifdef SMALL_SCREEN_DEVICE
- addButton(this, _w - 3 * (buttonWidth + 4) - 4, yoffset, "Keys", kKeysCmd, 'K', ws);
-#endif
-
- yoffset += buttonHeight;
-
- _h = yoffset + 8;
-
- _x = (screenW - _w) / 2;
- _y = (screenH - _h) / 2;
-
-#ifdef SMALL_SCREEN_DEVICE
- //
- // Create the sub dialog(s)
- //
-
- _keysDialog = new GUI::KeysDialog();
-#endif
-}
-
-ConfigDialog::~ConfigDialog() {
-#ifdef SMALL_SCREEN_DEVICE
- delete _keysDialog;
-#endif
-}
-
-void ConfigDialog::open() {
- GUI_OptionsDialog::open();
-
- // update checkboxes, too
- _subtitlesCheckbox->setState(ConfMan.getBool("subtitles"));
- _speechCheckbox->setState(!ConfMan.getBool("speech_mute"));
-}
-
-void ConfigDialog::close() {
- if (getResult()) {
- // Subtitles
- ConfMan.set("subtitles", _subtitlesCheckbox->getState(), _domain);
- ConfMan.set("speech_mute", !_speechCheckbox->getState(), _domain);
- // Sync with current setting
- if (ConfMan.getBool("speech_mute"))
- _vm->_voiceMode = 2;
- else
- _vm->_voiceMode = ConfMan.getBool("subtitles");
-
- if (_vm->_version >= 7)
- _vm->VAR(_vm->VAR_VOICE_MODE) = _vm->_voiceMode;
- }
-
- GUI_OptionsDialog::close();
-
- _vm->setupVolumes();
-}
-
-void ConfigDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
- switch (cmd) {
- case kKeysCmd:
-#ifdef SMALL_SCREEN_DEVICE
- _keysDialog->runModal();
-#endif
- break;
- default:
- GUI_OptionsDialog::handleCommand (sender, cmd, data);
- }
-}
-
-#ifndef DISABLE_HELP
-
-#pragma mark -
-
-enum {
- kNextCmd = 'NEXT',
- kPrevCmd = 'PREV'
-};
-
-HelpDialog::HelpDialog(ScummEngine *scumm)
- : ScummDialog(scumm, 5, 5, 310, 190) {
- _drawingHints &= ~GUI::THEME_HINT_SPECIAL_COLOR;
-
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
-
- GUI::WidgetSize ws;
- int buttonHeight;
- int buttonWidth;
-
- if (screenW >= 400 && screenH >= 300) {
- ws = GUI::kBigWidgetSize;
- buttonHeight = kBigButtonHeight;
- buttonWidth = kBigButtonWidth;
- _w = 370;
- _x = (screenW - _w) / 2;
- } else {
- ws = GUI::kNormalWidgetSize;
- buttonHeight = kButtonHeight;
- buttonWidth = kButtonWidth;
- _x = 5;
- _w = screenW - 2 * 5;
- }
-
- int lineHeight = g_gui.getFontHeight();
-
- _h = 5 + (2 + HELP_NUM_LINES) * lineHeight + buttonHeight + 7;
- _y = (screenH - _h) / 2;
-
- _title = new StaticTextWidget(this, 10, 5, _w, lineHeight, "", kTextAlignCenter, ws);
-
- for (int i = 0; i < HELP_NUM_LINES; i++) {
- _key[i] = new StaticTextWidget(this, 10, 5 + lineHeight * (i + 2), 80, lineHeight, "", kTextAlignLeft, ws);
- _dsc[i] = new StaticTextWidget(this, 90, 5 + lineHeight * (i + 2), _w - 10 - 90, lineHeight, "", kTextAlignLeft, ws);
- }
-
- _page = 1;
- _numPages = ScummHelp::numPages(scumm->_gameId);
-
- int y = 5 + lineHeight * (HELP_NUM_LINES + 2) + 2;
-
- _prevButton = addButton(this, 10, y, "Previous", kPrevCmd, 'P', ws);
- _nextButton = addButton(this, 10 + buttonWidth + 8, y, "Next", kNextCmd, 'N', ws);
- addButton(this, _w - 8 - buttonWidth, y, "Close", kCloseCmd, 'C', ws);
- _prevButton->clearFlags(WIDGET_ENABLED);
-
- displayKeyBindings();
-}
-
-void HelpDialog::displayKeyBindings() {
-
- String titleStr, *keyStr, *dscStr;
-
- ScummHelp::updateStrings(_vm->_gameId, _vm->_version, _vm->_platform, _page, titleStr, keyStr, dscStr);
-
- _title->setLabel(titleStr);
- for (int i = 0; i < HELP_NUM_LINES; i++) {
- _key[i]->setLabel(keyStr[i]);
- _dsc[i]->setLabel(dscStr[i]);
- }
-
- delete [] keyStr;
- delete [] dscStr;
-}
-
-void HelpDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
-
- switch (cmd) {
- case kNextCmd:
- _page++;
- if (_page >= _numPages) {
- _nextButton->clearFlags(WIDGET_ENABLED);
- }
- if (_page >= 2) {
- _prevButton->setFlags(WIDGET_ENABLED);
- }
- displayKeyBindings();
- draw();
- break;
- case kPrevCmd:
- _page--;
- if (_page <= _numPages) {
- _nextButton->setFlags(WIDGET_ENABLED);
- }
- if (_page <= 1) {
- _prevButton->clearFlags(WIDGET_ENABLED);
- }
- displayKeyBindings();
- draw();
- break;
- default:
- ScummDialog::handleCommand(sender, cmd, data);
- }
-}
-
-#endif
-
-#pragma mark -
-
-InfoDialog::InfoDialog(ScummEngine *scumm, int res)
-: ScummDialog(scumm, 0, 80, 0, 16) { // dummy x and w
- setInfoText(queryResString (res));
-}
-
-InfoDialog::InfoDialog(ScummEngine *scumm, const String& message)
-: ScummDialog(scumm, 0, 80, 0, 16) { // dummy x and w
- setInfoText(message);
-}
-
-void InfoDialog::setInfoText(const String& message) {
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
- GUI::WidgetSize ws;
-
- if (screenW >= 400 && screenH >= 300) {
- ws = GUI::kBigWidgetSize;
- } else {
- ws = GUI::kNormalWidgetSize;
- }
-
- int width = g_gui.getStringWidth(message) + 16;
- int height = g_gui.getFontHeight() + 8;
-
- _w = width;
- _h = height;
- _x = (screenW - width) / 2;
- _y = (screenH - height) / 2;
-
- new StaticTextWidget(this, 4, 4, _w - 8, _h, message, kTextAlignCenter, ws);
-}
-
-#pragma mark -
-
-PauseDialog::PauseDialog(ScummEngine *scumm, int res)
- : InfoDialog(scumm, res) {
-}
-
-void PauseDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
- if (ascii == ' ') // Close pause dialog if space key is pressed
- close();
- else
- ScummDialog::handleKeyDown(ascii, keycode, modifiers);
-}
-
-ConfirmDialog::ConfirmDialog(ScummEngine *scumm, const String& message)
- : InfoDialog(scumm, message) {
-}
-
-void ConfirmDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
- if (tolower(ascii) == 'n') {
- setResult(0);
- close();
- } else if (tolower(ascii) == 'y') {
- setResult(1);
- close();
- } else
- ScummDialog::handleKeyDown(ascii, keycode, modifiers);
-}
-
-#pragma mark -
-
-ValueDisplayDialog::ValueDisplayDialog(const Common::String& label, int minVal, int maxVal, int val, uint16 incKey, uint16 decKey)
- : GUI::Dialog(0, 80, 0, 16), _label(label), _min(minVal), _max(maxVal), _value(val), _incKey(incKey), _decKey(decKey) {
- assert(_min <= _value && _value <= _max);
-
- const int screenW = g_system->getOverlayWidth();
- const int screenH = g_system->getOverlayHeight();
-
- if (screenW >= 400 && screenH >= 300) {
- _percentBarWidth = kBigPercentBarWidth;
- } else {
- _percentBarWidth = kPercentBarWidth;
- }
-
- int width = g_gui.getStringWidth(label) + 16 + _percentBarWidth;
- int height = g_gui.getFontHeight() + 4 * 2;
-
- _x = (screenW - width) / 2;
- _y = (screenH - height) / 2;
- _w = width;
- _h = height;
-}
-
-void ValueDisplayDialog::drawDialog() {
- const int labelWidth = _w - 8 - _percentBarWidth;
- g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), GUI::THEME_HINT_SAVE_BACKGROUND | GUI::THEME_HINT_FIRST_DRAW);
- g_gui.theme()->drawText(Common::Rect(_x+4, _y+4, _x+labelWidth+4, _y+g_gui.theme()->getFontHeight()+4), _label);
- g_gui.theme()->drawSlider(Common::Rect(_x+4+labelWidth, _y+4, _x+_w-4, _y+_h-4), _percentBarWidth * (_value - _min) / (_max - _min));
-}
-
-void ValueDisplayDialog::handleTickle() {
- if (getMillis() > _timer)
- close();
-}
-
-void ValueDisplayDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
- if (ascii == _incKey || ascii == _decKey) {
- if (ascii == _incKey && _value < _max)
- _value++;
- else if (ascii == _decKey && _value > _min)
- _value--;
-
- setResult(_value);
- _timer = getMillis() + kDisplayDelay;
- draw();
- } else {
- close();
- }
-}
-
-void ValueDisplayDialog::open() {
- GUI_Dialog::open();
- setResult(_value);
- _timer = getMillis() + kDisplayDelay;
-}
-
-
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Dialogs)
-_GSETPTR(Scumm::string_map_table_v7, GBVARS_STRINGMAPTABLEV7_INDEX, Scumm::ResString, GBVARS_SCUMM)
-_GSETPTR(Scumm::string_map_table_v6, GBVARS_STRINGMAPTABLEV6_INDEX, Scumm::ResString, GBVARS_SCUMM)
-_GSETPTR(Scumm::string_map_table_v5, GBVARS_STRINGMAPTABLEV5_INDEX, Scumm::ResString, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Dialogs)
-_GRELEASEPTR(GBVARS_STRINGMAPTABLEV7_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_STRINGMAPTABLEV6_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_STRINGMAPTABLEV5_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/dialogs.h b/scumm/dialogs.h
deleted file mode 100644
index 60d796956e..0000000000
--- a/scumm/dialogs.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef SCUMM_DIALOGS_H
-#define SCUMM_DIALOGS_H
-
-#include "common/str.h"
-#include "gui/dialog.h"
-#include "gui/options.h"
-#include "gui/widget.h"
-
-#ifndef DISABLE_HELP
-#include "scumm/help.h"
-#endif
-
-namespace GUI {
- class ListWidget;
-}
-
-
-namespace Scumm {
-
-class ScummEngine;
-
-class ScummDialog : public GUI::Dialog {
-public:
- ScummDialog(ScummEngine *scumm, int x, int y, int w, int h);
-
-protected:
- typedef Common::String String;
-
- ScummEngine *_vm;
-
- // Query a string from the resources
- const String queryResString(int stringno);
-};
-
-// to have a base for all different Save/Load Choosers
-// currently only for SaveLoadChooser (320x200)
-// and for SaveLoadChooserEx (640x400/640x480)
-class BaseSaveLoadChooser
-{
-public:
- virtual ~BaseSaveLoadChooser() {};
-
- virtual const Common::String &getResultString() const = 0;
- virtual void setList(const Common::StringList& list) = 0;
- virtual int runModal() = 0;
-};
-
-class MainMenuDialog : public ScummDialog {
-public:
- MainMenuDialog(ScummEngine *scumm);
- ~MainMenuDialog();
- virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
-
-protected:
- GUI::Dialog *_aboutDialog;
- GUI::Dialog *_optionsDialog;
-#ifndef DISABLE_HELP
- GUI::Dialog *_helpDialog;
-#endif
- BaseSaveLoadChooser *_saveDialog;
- BaseSaveLoadChooser *_loadDialog;
-
- void save();
- void load();
-};
-
-#ifndef DISABLE_HELP
-
-class HelpDialog : public ScummDialog {
-public:
- HelpDialog(ScummEngine *scumm);
- virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
-
-protected:
- typedef Common::String String;
-
- GUI::ButtonWidget *_nextButton;
- GUI::ButtonWidget *_prevButton;
-
- GUI::StaticTextWidget *_title;
- GUI::StaticTextWidget *_key[HELP_NUM_LINES];
- GUI::StaticTextWidget *_dsc[HELP_NUM_LINES];
-
- int _page;
- int _numPages;
-
- void displayKeyBindings();
-};
-
-#endif
-
-class ConfigDialog : public GUI::OptionsDialog {
-protected:
- ScummEngine *_vm;
-#ifdef SMALL_SCREEN_DEVICE
- GUI::Dialog *_keysDialog;
-#endif
-
-public:
- ConfigDialog(ScummEngine *scumm);
- ~ConfigDialog();
-
- virtual void open();
- virtual void close();
- virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
-
-protected:
- GUI::CheckboxWidget *_subtitlesCheckbox;
- GUI::CheckboxWidget *_speechCheckbox;
-};
-
-/**
- * A dialog which displays an arbitrary message to the user and returns
- * ther users reply as its result value. More specifically, it returns
- * the ASCII code of the key used to close the dialog (0 if a mouse
- * click closed the dialog).
- */
-class InfoDialog : public ScummDialog {
-public:
- // arbitrary message
- InfoDialog(ScummEngine *scumm, const String& message);
- // from resources
- InfoDialog(ScummEngine *scumm, int res);
-
- virtual void handleMouseDown(int x, int y, int button, int clickCount) {
- setResult(0);
- close();
- }
- virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers) {
- setResult(ascii);
- close();
- }
-
-protected:
- void setInfoText (const String& message);
-};
-
-/**
- * The pause dialog, visible whenever the user activates pause mode. Goes
- * away uon any key or mouse button press.
- */
-class PauseDialog : public InfoDialog {
-public:
- PauseDialog(ScummEngine *scumm, int res);
- virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers);
-};
-
-/**
- * A simple yes/no dialog, used to ask the user whether to really
- * quit/restart ScummVM.
- */
-class ConfirmDialog : public InfoDialog {
-public:
- ConfirmDialog(ScummEngine *scumm, const String& message);
- virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers);
-};
-
-/**
- * A dialog used to display the music volume / text speed.
- * Automatically closes after a brief time passed.
- */
-class ValueDisplayDialog : public GUI::Dialog {
-public:
- ValueDisplayDialog(const Common::String& label, int minVal, int maxVal, int val, uint16 incKey, uint16 decKey);
-
- virtual void open();
- virtual void drawDialog();
- virtual void handleTickle();
- virtual void handleMouseDown(int x, int y, int button, int clickCount) {
- close();
- }
- virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers);
-
-protected:
- enum {
- kPercentBarWidth = 50,
- kBigPercentBarWidth = 75,
- kDisplayDelay = 1500
- };
- Common::String _label;
- const int _min, _max;
- const uint16 _incKey, _decKey;
- int _percentBarWidth;
- int _value;
- uint32 _timer;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/floodfill_he.cpp b/scumm/floodfill_he.cpp
deleted file mode 100644
index c7df765606..0000000000
--- a/scumm/floodfill_he.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/floodfill_he.h"
-#include "scumm/intern_he.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-static bool floodFillPixelCheck(int x, int y, const FloodFillState *ffs) {
- int diffColor = ffs->color1 - ffs->color2;
- if (x >= 0 && x < ffs->dst_w && y >= 0 && y < ffs->dst_h) {
- uint8 color = *(ffs->dst + y * ffs->dst_w + x);
- diffColor = color - ffs->color1;
- }
- return diffColor == 0;
-}
-
-static void floodFillProcessRect(FloodFillState *ffs, const Common::Rect *r) {
- Common::Rect *dr = &ffs->dstBox;
- if (dr->right >= dr->left && dr->top <= dr->bottom) {
- int rw = r->right - r->left + 1;
- int rh = r->bottom - r->top + 1;
- assert(r->top + rh <= ffs->dst_h);
- assert(r->left + rw <= ffs->dst_w);
- uint8 *dst = ffs->dst + r->top * ffs->dst_w + r->left;
- if (rw <= 1) {
- --rh;
- while (rh >= 0) {
- *dst = ffs->color2;
- dst += ffs->dst_w;
- --rh;
- }
- } else {
- --rh;
- while (rh >= 0) {
- memset(dst, ffs->color2, rw);
- dst += ffs->dst_w;
- --rh;
- }
- }
- dr->extend(*r);
- } else {
- *dr = *r;
- }
-}
-
-static void floodFillAddLine(FloodFillLine **ffl, int y, int x1, int x2, int dy) {
- (*ffl)->y = y;
- (*ffl)->x1 = x1;
- (*ffl)->x2 = x2;
- (*ffl)->inc = dy;
- (*ffl)++;
-}
-
-static void floodFillProcess(int x, int y, FloodFillState *ffs, FloodFillPixelCheckCallback pixelCheckCallback) {
- ffs->dstBox.left = ffs->dstBox.top = 12345;
- ffs->dstBox.right = ffs->dstBox.bottom = -12345;
-
- FloodFillLine **fillLineCur = &ffs->fillLineTableCur;
- FloodFillLine **fillLineEnd = &ffs->fillLineTableEnd;
-
- assert(*fillLineCur < *fillLineEnd);
- if (ffs->srcBox.top <= y + 1 && ffs->srcBox.bottom >= y + 1) {
- (*fillLineCur)->y = y;
- (*fillLineCur)->x1 = x;
- (*fillLineCur)->x2 = x;
- (*fillLineCur)->inc = 1;
- (*fillLineCur)++;
- }
-
- assert(*fillLineCur < *fillLineEnd);
- if (ffs->srcBox.top <= y && ffs->srcBox.bottom >= y) {
- (*fillLineCur)->y = y + 1;
- (*fillLineCur)->x1 = x;
- (*fillLineCur)->x2 = x;
- (*fillLineCur)->inc = -1;
- (*fillLineCur)++;
- }
-
- assert(ffs->fillLineTable <= *fillLineCur);
- FloodFillLine **fillLineStart = fillLineCur;
-
- while (ffs->fillLineTable < *fillLineStart) {
- Common::Rect r;
- int x_start;
- FloodFillLine *fflCur = --(*fillLineCur);
- int dy = fflCur->inc;
- int x_end = fflCur->x2;
- int x1 = fflCur->x1;
- int x2 = fflCur->x1 + 1;
- r.bottom = r.top = y = fflCur->y + fflCur->inc;
- r.left = x2;
- r.right = x1;
- x = x1;
- while (ffs->srcBox.left <= x) {
- if (!(*pixelCheckCallback)(x, y, ffs)) {
- break;
- }
- r.left = x;
- --x;
- }
- if (r.right >= r.left && r.top <= r.bottom) {
- floodFillProcessRect(ffs, &r);
- }
- if (x >= x1) goto skip;
- x_start = x + 1;
- if (x1 > x_start) {
- assert(*fillLineEnd > *fillLineCur);
- if (ffs->srcBox.top <= y - dy && ffs->srcBox.bottom >= y - dy) {
- --x1;
- floodFillAddLine(fillLineCur, y, x_start, x1, -dy);
- }
- }
- x = x2;
- while (x_start <= x_end) {
- r.left = x;
- r.top = y;
- r.right = x - 1;
- r.bottom = y;
- while (ffs->srcBox.right >= x) {
- if (!(*pixelCheckCallback)(x, y, ffs)) {
- break;
- }
- r.right = x;
- ++x;
- }
- if (r.right >= r.left && r.top <= r.bottom) {
- floodFillProcessRect(ffs, &r);
- }
- assert(ffs->fillLineTableCur < ffs->fillLineTableEnd);
- if (ffs->srcBox.top <= y + dy && ffs->srcBox.bottom >= y + dy) {
- floodFillAddLine(&ffs->fillLineTableCur, y, x_start, x - 1, dy);
- }
- x_start = x_end + 1;
- if (x > x_start) {
- assert(ffs->fillLineTableCur < ffs->fillLineTableEnd);
- if (ffs->srcBox.top <= y - dy && ffs->srcBox.bottom >= y - dy) {
- floodFillAddLine(&ffs->fillLineTableCur, y, x_start, x - 1, -dy);
- }
- }
-skip:
- ++x;
- while (x <= x_end) {
- if ((*pixelCheckCallback)(x, y, ffs)) {
- break;
- }
- ++x;
- }
- x_start = x;
- }
- }
-}
-
-void floodFill(FloodFillParameters *ffp, ScummEngine_v90he *vm) {
- uint8 *dst;
- VirtScreen *vs = &vm->virtscr[kMainVirtScreen];
- if (ffp->flags & 0x8000) {
- dst = vs->getBackPixels(0, vs->topline);
- } else {
- dst = vs->getPixels(0, vs->topline);
- }
- uint8 color = ffp->flags & 0xFF;
-
- Common::Rect r;
- r.left = r.top = 12345;
- r.right = r.bottom = -12345;
-
- FloodFillState *ffs = new FloodFillState;
- ffs->fillLineTableCount = vs->h * 2;
- ffs->fillLineTable = new FloodFillLine[ffs->fillLineTableCount];
- ffs->color2 = color;
- ffs->dst = dst;
- ffs->dst_w = vs->w;
- ffs->dst_h = vs->h;
- ffs->srcBox = ffp->box;
- ffs->fillLineTableCur = &ffs->fillLineTable[0];
- ffs->fillLineTableEnd = &ffs->fillLineTable[ffs->fillLineTableCount];
-
- if (ffp->x < 0 || ffp->y < 0 || ffp->x >= vs->w || ffp->y >= vs->h) {
- ffs->color1 = color;
- } else {
- ffs->color1 = *(dst + ffp->y * vs->w + ffp->x);
- }
-
- debug(5, "floodFill() x=%d y=%d color1=%d ffp->flags=0x%X", ffp->x, ffp->y, ffs->color1, ffp->flags);
- if (ffs->color1 != color) {
- floodFillProcess(ffp->x, ffp->y, ffs, floodFillPixelCheck);
- r = ffs->dstBox;
- }
- r.debugPrint(5, "floodFill() dirty_rect");
-
- delete[] ffs->fillLineTable;
- delete ffs;
-
- vm->VAR(119) = 1;
-
- if (r.left <= r.right && r.top <= r.bottom) {
- if (ffp->flags & 0x8000) {
- vm->gdi.copyVirtScreenBuffers(r);
- } else {
- ++r.bottom;
- vm->markRectAsDirty(kMainVirtScreen, r);
- }
- }
-}
-
-void Wiz::fillWizFlood(const WizParameters *params) {
- if (params->processFlags & kWPFClipBox2) {
- int px = params->box2.left;
- int py = params->box2.top;
- uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum);
- if (dataPtr) {
- int state = 0;
- if (params->processFlags & kWPFNewState) {
- state = params->img.state;
- }
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- int w = READ_LE_UINT32(wizh + 0x4);
- int h = READ_LE_UINT32(wizh + 0x8);
- assert(c == 0);
- Common::Rect imageRect(w, h);
- if (params->processFlags & kWPFClipBox) {
- if (!imageRect.intersects(params->box)) {
- return;
- }
- imageRect.clip(params->box);
- }
- uint8 color = _vm->VAR(93);
- if (params->processFlags & kWPFFillColor) {
- color = params->fillColor;
- }
- if (imageRect.contains(px, py)) {
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), dataPtr, state, 0);
- assert(wizd);
-
- FloodFillState *ffs = new FloodFillState;
- ffs->fillLineTableCount = h * 2;
- ffs->fillLineTable = new FloodFillLine[ffs->fillLineTableCount];
- ffs->color2 = color;
- ffs->dst = wizd;
- ffs->dst_w = w;
- ffs->dst_h = h;
- ffs->srcBox = imageRect;
- ffs->fillLineTableCur = &ffs->fillLineTable[0];
- ffs->fillLineTableEnd = &ffs->fillLineTable[ffs->fillLineTableCount];
-
- if (px < 0 || py < 0 || px >= w || py >= h) {
- ffs->color1 = color;
- } else {
- ffs->color1 = *(wizd + py * w + px);
- }
-
- debug(0, "floodFill() x=%d y=%d color1=%d", px, py, ffs->color1);
-
- if (ffs->color1 != color) {
- floodFillProcess(px, py, ffs, floodFillPixelCheck);
- }
-
- delete[] ffs->fillLineTable;
- delete ffs;
- }
- }
- }
- _vm->res.setModified(rtImage, params->img.resNum);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/floodfill_he.h b/scumm/floodfill_he.h
deleted file mode 100644
index 7d0fa7073f..0000000000
--- a/scumm/floodfill_he.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(FLOODFILL_HE_H) && !defined(DISABLE_HE)
-#define FLOODFILL_HE_H
-
-#include "common/rect.h"
-
-namespace Scumm {
-
-struct FloodFillParameters {
- Common::Rect box;
- int32 x;
- int32 y;
- int32 flags;
-};
-
-struct FloodFillLine {
- int y;
- int x1;
- int x2;
- int inc;
-};
-
-struct FloodFillState {
- FloodFillLine *fillLineTable;
- FloodFillLine *fillLineTableEnd;
- FloodFillLine *fillLineTableCur;
- Common::Rect dstBox;
- Common::Rect srcBox;
- uint8 *dst;
- int dst_w;
- int dst_h;
- int color1;
- int color2;
- int fillLineTableCount;
-};
-
-class ScummEngine_v90he;
-
-typedef bool (*FloodFillPixelCheckCallback)(int x, int y, const FloodFillState *ffs);
-
-void floodFill(FloodFillParameters *ffp, ScummEngine_v90he *vm);
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
deleted file mode 100644
index dc476a8f0b..0000000000
--- a/scumm/gfx.cpp
+++ /dev/null
@@ -1,3307 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/resource.h"
-#include "scumm/usage_bits.h"
-#include "scumm/wiz_he.h"
-
-namespace Scumm {
-
-static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
-static void fill(byte *dst, int dstPitch, byte color, int w, int h);
-
-static void copy8Col(byte *dst, int dstPitch, const byte *src, int height);
-static void clear8Col(byte *dst, int dstPitch, int height);
-
-
-struct StripTable {
- int offsets[160];
- int run[160];
- int color[160];
- int zoffsets[120]; // FIXME: Why only 120 here?
- int zrun[120]; // FIXME: Why only 120 here?
-};
-
-enum {
- kScrolltime = 500, // ms scrolling is supposed to take
- kPictureDelay = 20
-};
-
-#define NUM_SHAKE_POSITIONS 8
-static const int8 shake_positions[NUM_SHAKE_POSITIONS] = {
- 0, 1 * 2, 2 * 2, 1 * 2, 0 * 2, 2 * 2, 3 * 2, 1 * 2
-};
-
-/**
- * The following structs define four basic fades/transitions used by
- * transitionEffect(), each looking differently to the user.
- * Note that the stripTables contain strip numbers, and they assume
- * that the screen has 40 vertical strips (i.e. 320 pixel), and 25 horizontal
- * strips (i.e. 200 pixel). There is a hack in transitionEffect that
- * makes it work correctly in games which have a different screen height
- * (for example, 240 pixel), but nothing is done regarding the width, so this
- * code won't work correctly in COMI. Also, the number of iteration depends
- * on min(vertStrips, horizStrips}. So the 13 is derived from 25/2, rounded up.
- * And the 25 = min(25,40). Hence for Zak256 instead of 13 and 25, the values
- * 15 and 30 should be used, and for COMI probably 30 and 60.
- */
-struct TransitionEffect {
- byte numOfIterations;
- int8 deltaTable[16]; // four times l / t / r / b
- byte stripTable[16]; // ditto
-};
-
-#ifdef PALMOS_68K
-static const TransitionEffect *transitionEffects;
-#else
-static const TransitionEffect transitionEffects[6] = {
- // Iris effect (looks like an opening/closing camera iris)
- {
- 13, // Number of iterations
- {
- 1, 1, -1, 1,
- -1, 1, -1, -1,
- 1, -1, -1, -1,
- 1, 1, 1, -1
- },
- {
- 0, 0, 39, 0,
- 39, 0, 39, 24,
- 0, 24, 39, 24,
- 0, 0, 0, 24
- }
- },
-
- // Box wipe (a box expands from the upper-left corner to the lower-right corner)
- {
- 25, // Number of iterations
- {
- 0, 1, 2, 1,
- 2, 0, 2, 1,
- 2, 0, 2, 1,
- 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 1, 0, 1, 0,
- 255, 0, 0, 0
- }
- },
-
- // Box wipe (a box expands from the lower-right corner to the upper-left corner)
- {
- 25, // Number of iterations
- {
- -2, -1, 0, -1,
- -2, -1, -2, 0,
- -2, -1, -2, 0,
- 0, 0, 0, 0
- },
- {
- 39, 24, 39, 24,
- 39, 24, 39, 24,
- 38, 24, 38, 24,
- 255, 0, 0, 0
- }
- },
-
- // Inverse box wipe
- {
- 25, // Number of iterations
- {
- 0, -1, -2, -1,
- -2, 0, -2, -1,
- -2, 0, -2, -1,
- 0, 0, 0, 0
- },
- {
- 0, 24, 39, 24,
- 39, 0, 39, 24,
- 38, 0, 38, 24,
- 255, 0, 0, 0
- }
- },
-
- // Inverse iris effect, specially tailored for V1/V2 games
- {
- 9, // Number of iterations
- {
- -1, -1, 1, -1,
- -1, 1, 1, 1,
- -1, -1, -1, 1,
- 1, -1, 1, 1
- },
- {
- 7, 7, 32, 7,
- 7, 8, 32, 8,
- 7, 8, 7, 8,
- 32, 7, 32, 8
- }
- },
-
- // Horizontal wipe (a box expands from left to right side). For MM NES
- {
- 16, // Number of iterations
- {
- 2, 0, 2, 0,
- 2, 0, 2, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- },
- {
- 0, 0, 0, 15,
- 1, 0, 1, 15,
- 255, 0, 0, 0,
- 255, 0, 0, 0
- }
- }
-
-};
-#endif
-
-
-Gdi::Gdi(ScummEngine *vm) {
- memset(this, 0, sizeof(*this));
- _vm = vm;
- _paletteMod = 0;
- _roomPalette = vm->_roomPalette;
- _roomStrips = 0;
-}
-
-Gdi::~Gdi() {
- free(_roomStrips);
-}
-
-void Gdi::init() {
- _numStrips = _vm->_screenWidth / 8;
-
- // Increase the number of screen strips by one; needed for smooth scrolling
- if (_vm->_version >= 7) {
- // We now have mostly working smooth scrolling code in place for V7+ games
- // (i.e. The Dig, Full Throttle and COMI). It seems to work very well so far.
- // One area which still may need some work are the AKOS codecs (except for
- // codec 1, which I already updated): their masking code may need adjustments,
- // similar to the treatment codec 1 received.
- //
- // To understand how we achieve smooth scrolling, first note that with it, the
- // virtual screen strips don't match the display screen strips anymore. To
- // overcome that problem, we simply use a screen pitch that is 8 pixel wider
- // than the actual screen width, and always draw one strip more than needed to
- // the backbuf (of course we have to treat the right border seperately). This
- _numStrips += 1;
- }
-}
-
-void Gdi::roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor) {
- if (_vm->_version == 1) {
- if (_vm->_platform == Common::kPlatformNES) {
- decodeNESGfx(roomptr);
- } else {
- for (int i = 0; i < 4; i++){
- _C64.colors[i] = roomptr[6 + i];
- }
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _C64.charMap, 2048);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _C64.picMap, roomptr[4] * roomptr[5]);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _C64.colorMap, roomptr[4] * roomptr[5]);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _C64.maskMap, roomptr[4] * roomptr[5]);
- decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 18) + 2, _C64.maskChar, READ_LE_UINT16(roomptr + READ_LE_UINT16(roomptr + 18)));
- _objectMode = true;
- }
- } else if (_vm->_version == 2) {
- _roomStrips = generateStripTable(roomptr + IM00_offs, _vm->_roomWidth, _vm->_roomHeight, _roomStrips);
- }
-
- _transparentColor = transparentColor;
-}
-
-
-#pragma mark -
-#pragma mark --- Virtual Screens ---
-#pragma mark -
-
-
-void ScummEngine::initScreens(int b, int h) {
- int i;
- int adj = 0;
-
- for (i = 0; i < 3; i++) {
- res.nukeResource(rtBuffer, i + 1);
- res.nukeResource(rtBuffer, i + 5);
- }
-
- if (!getResourceAddress(rtBuffer, 4)) {
- // Since the size of screen 3 is fixed, there is no need to reallocate
- // it if its size changed.
- // Not sure what it is good for, though. I think it may have been used
- // in pre-V7 for the games messages (like 'Pause', Yes/No dialogs,
- // version display, etc.). I don't know about V7, maybe the same is the
- // case there. If so, we could probably just remove it completely.
- if (_version >= 7) {
- initVirtScreen(kUnkVirtScreen, (_screenHeight / 2) - 10, _screenWidth, 13, false, false);
- } else {
- initVirtScreen(kUnkVirtScreen, 80, _screenWidth, 13, false, false);
- }
- }
-
- if ((_platform == Common::kPlatformNES) && (h != _screenHeight)) {
- // This is a hack to shift the whole screen downwards to match the original.
- // Otherwise we would have to do lots of coordinate adjustments all over
- // the code.
- adj = 16;
- initVirtScreen(kUnkVirtScreen, 0, _screenWidth, adj, false, false);
- }
-
- initVirtScreen(kMainVirtScreen, b + adj, _screenWidth, h - b, true, true);
- initVirtScreen(kTextVirtScreen, adj, _screenWidth, b, false, false);
- initVirtScreen(kVerbVirtScreen, h + adj, _screenWidth, _screenHeight - h - adj, false, false);
- _screenB = b;
- _screenH = h;
-
- gdi.init();
-}
-
-void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int height, bool twobufs,
- bool scrollable) {
- VirtScreen *vs = &virtscr[slot];
- int size;
-
- assert(height >= 0);
- assert(slot >= 0 && slot < 4);
-
- if (_version >= 7) {
- if (slot == kMainVirtScreen && (_roomHeight != 0))
- height = _roomHeight;
- }
-
- vs->number = slot;
- vs->w = width;
- vs->topline = top;
- vs->h = height;
- vs->hasTwoBuffers = twobufs;
- vs->xstart = 0;
- vs->backBuf = NULL;
- vs->bytesPerPixel = 1;
- vs->pitch = width;
-
- if (_version >= 7) {
- // Increase the pitch by one; needed to accomodate the extra
- // screen strip which we use to implement smooth scrolling.
- // See Gdi::init()
- vs->pitch += 8;
- }
-
- size = vs->pitch * vs->h;
- if (scrollable) {
- // Allow enough spaces so that rooms can be up to 4 resp. 8 screens
- // wide. To achieve (horizontal!) scrolling, we use a neat trick:
- // only the offset into the screen buffer (xstart) is changed. That way
- // very little of the screen has to be redrawn, and we have a very low
- // memory overhead (namely for every pixel we want to scroll, we need
- // one additional byte in the buffer).
- if (_version >= 7) {
- size += vs->pitch * 8;
- } else {
- size += vs->pitch * 4;
- }
- }
-
- res.createResource(rtBuffer, slot + 1, size);
- vs->pixels = getResourceAddress(rtBuffer, slot + 1);
- memset(vs->pixels, 0, size); // reset background
-
- if (twobufs) {
- vs->backBuf = res.createResource(rtBuffer, slot + 5, size);
- }
-
- if (slot != 3) {
- vs->setDirtyRange(0, height);
- }
-}
-
-VirtScreen *ScummEngine::findVirtScreen(int y) {
- VirtScreen *vs = virtscr;
- int i;
-
- for (i = 0; i < 3; i++, vs++) {
- if (y >= vs->topline && y < vs->topline + vs->h) {
- return vs;
- }
- }
- return NULL;
-}
-
-void ScummEngine::markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit) {
- VirtScreen *vs = &virtscr[virt];
- int lp, rp;
-
- if (left > right || top > bottom)
- return;
- if (top > vs->h || bottom < 0)
- return;
-
- if (top < 0)
- top = 0;
- if (bottom > vs->h)
- bottom = vs->h;
-
- if (virt == kMainVirtScreen && dirtybit) {
-
- lp = left / 8 + _screenStartStrip;
- if (lp < 0)
- lp = 0;
-
- rp = (right + vs->xstart) / 8;
- if (_version >= 7) {
- if (rp > 409)
- rp = 409;
- } else {
- if (rp >= 200)
- rp = 200;
- }
- for (; lp <= rp; lp++)
- setGfxUsageBit(lp, dirtybit);
- }
-
- // The following code used to be in the separate method setVirtscreenDirty
- lp = left / 8;
- rp = right / 8;
-
- if ((lp >= gdi._numStrips) || (rp < 0))
- return;
- if (lp < 0)
- lp = 0;
- if (rp >= gdi._numStrips)
- rp = gdi._numStrips - 1;
-
- while (lp <= rp) {
- if (top < vs->tdirty[lp])
- vs->tdirty[lp] = top;
- if (bottom > vs->bdirty[lp])
- vs->bdirty[lp] = bottom;
- lp++;
- }
-}
-
-/**
- * Update all dirty screen areas. This method blits all of the internal engine
- * graphics to the actual display, as needed. In addition, the 'shaking'
- * code in the backend is controlled from here.
- */
-void ScummEngine::drawDirtyScreenParts() {
- // Update verbs
- updateDirtyScreen(kVerbVirtScreen);
-
- // Update the conversation area (at the top of the screen)
- updateDirtyScreen(kTextVirtScreen);
-
- // Update game area ("stage")
- if (camera._last.x != camera._cur.x || (_features & GF_NEW_CAMERA && (camera._cur.y != camera._last.y))) {
- // Camera moved: redraw everything
- VirtScreen *vs = &virtscr[kMainVirtScreen];
- drawStripToScreen(vs, 0, vs->w, 0, vs->h);
- vs->setDirtyRange(vs->h, 0);
- } else {
- updateDirtyScreen(kMainVirtScreen);
- }
-
- // Handle shaking
- if (_shakeEnabled) {
- _shakeFrame = (_shakeFrame + 1) % NUM_SHAKE_POSITIONS;
- _system->setShakePos(shake_positions[_shakeFrame]);
- } else if (!_shakeEnabled &&_shakeFrame != 0) {
- _shakeFrame = 0;
- _system->setShakePos(0);
- }
-}
-
-void ScummEngine_v6::drawDirtyScreenParts() {
- // For the Full Throttle credits to work properly, the blast
- // texts have to be drawn before the blast objects. Unless
- // someone can think of a better way to achieve this effect.
-
- if (_version >= 7 && VAR(VAR_BLAST_ABOVE_TEXT) == 1) {
- drawBlastTexts();
- drawBlastObjects();
- } else {
- drawBlastObjects();
- drawBlastTexts();
- }
- if (_version == 8)
- processUpperActors();
-
- // Call the original method.
- ScummEngine::drawDirtyScreenParts();
-
- // Remove all blasted objects/text again.
- removeBlastTexts();
- removeBlastObjects();
-}
-
-/**
- * Blit the dirty data from the given VirtScreen to the display. If the camera moved,
- * a full blit is done, otherwise only the visible dirty areas are updated.
- */
-void ScummEngine::updateDirtyScreen(VirtScreenNumber slot) {
- VirtScreen *vs = &virtscr[slot];
-
- // Do nothing for unused virtual screens
- if (vs->h == 0)
- return;
-
- int i;
- int w = 8;
- int start = 0;
-
- for (i = 0; i < gdi._numStrips; i++) {
- if (vs->bdirty[i]) {
- const int top = vs->tdirty[i];
- const int bottom = vs->bdirty[i];
- vs->tdirty[i] = vs->h;
- vs->bdirty[i] = 0;
- if (i != (gdi._numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
- // Simple optimizations: if two or more neighbouring strips
- // form one bigger rectangle, coalesce them.
- w += 8;
- continue;
- }
- drawStripToScreen(vs, start * 8, w, top, bottom);
- w = 8;
- }
- start = i + 1;
- }
-}
-
-/**
- * Blit the specified rectangle from the given virtual screen to the display.
- * Note: t and b are in *virtual screen* coordinates, while x is relative to
- * the *real screen*. This is due to the way tdirty/vdirty work: they are
- * arrays which map 'strips' (sections of the real screen) to dirty areas as
- * specified by top/bottom coordinate in the virtual screen.
- */
-void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom) {
-
- if (bottom <= top)
- return;
-
- if (top >= vs->h)
- return;
-
- assert(top >= 0 && bottom <= vs->h); // Paranoia checks
- assert(x >= 0 && width <= vs->pitch);
- assert(_charset->_textSurface.pixels);
- assert(_compositeBuf);
-
- if (width > vs->w - x)
- width = vs->w - x;
-
- // Clip to the visible part of the scene
- if (top < _screenTop)
- top = _screenTop;
- if (bottom > _screenTop + _screenHeight)
- bottom = _screenTop + _screenHeight;
-
- // Convert the vertical coordinates to real screen coords
- int y = vs->topline + top - _screenTop;
- int height = bottom - top;
-
- if (height <= 0 || width <= 0)
- return;
-
- // Compute screen etc. buffer pointers
- const byte *src = vs->getPixels(x, top);
- byte *dst = _compositeBuf + x + y * _screenWidth;
-
- if (_version < 7) {
- // Handle the text mask in older games; newer (V7/V8) games do not use it anymore.
- const byte *text = (byte *)_charset->_textSurface.pixels + x + y * _charset->_textSurface.pitch;
-
- // Compose the text over the game graphics
- for (int h = 0; h < height; ++h) {
- for (int w = 0; w < width; ++w) {
- if (text[w] == CHARSET_MASK_TRANSPARENCY)
- dst[w] = src[w];
- else
- dst[w] = text[w];
- }
- src += vs->pitch;
- dst += _screenWidth;
- text += _charset->_textSurface.pitch;
- }
- } else {
- // Just do a simple blit in V7/V8 games.
- blit(dst, _screenWidth, src, vs->pitch, width, height);
- }
-
- if (_renderMode == Common::kRenderCGA)
- ditherCGA(_compositeBuf + x + y * _screenWidth, _screenWidth, x, y, width, height);
-
- if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- ditherHerc(_compositeBuf + x + y * _screenWidth, _herculesBuf, _screenWidth, &x, &y, &width, &height);
- // center image on the screen
- _system->copyRectToScreen(_herculesBuf + x + y * Common::kHercW,
- Common::kHercW, x + (Common::kHercW - _screenWidth * 2) / 2, y, width, height);
- } else {
- // Finally blit the whole thing to the screen
- int x1 = x;
-
- // HACK: This is dirty hack which renders narrow NES rooms centered
- // NES can address negative number strips and that poses problem for
- // our code. So instead adding zillions of fixes and potentially break
- // other games we shift it right on rendering stage
- if ((_platform == Common::kPlatformNES) && (((_NESStartStrip > 0) && (vs->number == kMainVirtScreen)) || (vs->number == kTextVirtScreen))) {
- x += 16;
- while (x + width >= _screenWidth)
- width -= 16;
- if (width < 0)
- return;
- }
-
- _system->copyRectToScreen(_compositeBuf + x1 + y * _screenWidth, _screenWidth, x, y, width, height);
- }
-}
-
-// CGA
-// indy3 loom maniac monkey1 zak
-//
-// Herc (720x350)
-// maniac monkey1 zak
-//
-// EGA
-// monkey2 loom maniac monkey1 atlantis indy3 zak loomcd
-
-// CGA dithers 4x4 square with direct substitutes
-// Odd lines have colors swapped, so there will be checkered patterns.
-// But apparently there is a mistake for 10th color.
-void ScummEngine::ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const {
- byte *ptr;
- int idx1, idx2;
- static const byte cgaDither[2][2][16] = {
- {{0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 3, 1, 3, 2, 1, 3},
- {0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3}},
- {{0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3},
- {0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 1, 1, 3, 2, 1, 3}}};
-
- for (int y1 = 0; y1 < height; y1++) {
- ptr = dst + y1 * dstPitch;
-
- idx1 = (y + y1) % 2;
-
- if (_version == 2)
- idx1 = 0;
-
- for (int x1 = 0; x1 < width; x1++) {
- idx2 = (x + x1) % 2;
- *ptr = cgaDither[idx1][idx2][*ptr & 0xF];
- ptr++;
- }
- }
-}
-
-// Hercules dithering. It uses same dithering tables but output is 1bpp and
-// it stretches in this way:
-// aaaa0
-// aa aaaa1
-// bb bbbb0 Here 0 and 1 mean dithering table row number
-// cc --> bbbb1
-// dd cccc0
-// cccc1
-// dddd0
-void ScummEngine::ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const {
- byte *srcptr, *dstptr;
- int xo = *x, yo = *y, widtho = *width, heighto = *height;
- int idx1, idx2, dsty = 0, y1;
- static const byte cgaDither[2][2][16] = {
- {{0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 3, 1, 3, 2, 1, 3},
- {0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3}},
- {{0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3},
- {0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 1, 1, 3, 2, 1, 3}}};
-
- // calculate dsty
- for (y1 = 0; y1 < yo; y1++) {
- dsty += 2;
- if (y1 % 4 == 3)
- dsty--;
- }
- *y = dsty;
- *x *= 2;
- *width *= 2;
- *height = 0;
-
- for (y1 = 0; y1 < heighto;) {
- srcptr = src + y1 * srcPitch;
- dstptr = hercbuf + dsty * Common::kHercW + xo * 2;
-
- assert(dstptr < hercbuf + Common::kHercW * Common::kHercH + widtho * 2);
-
- idx1 = (dsty % 7) % 2;
- for (int x1 = 0; x1 < widtho; x1++) {
- idx2 = (xo + x1) % 2;
- *dstptr++ = cgaDither[idx1][idx2][*srcptr & 0xF] >> 1;
- *dstptr++ = cgaDither[idx1][idx2][*srcptr & 0xF] & 0x1;
- srcptr++;
- }
- if (idx1 || dsty % 7 == 6)
- y1++;
- dsty++;
- (*height)++;
- }
-}
-
-
-#pragma mark -
-#pragma mark --- Background buffers & charset mask ---
-#pragma mark -
-
-
-void ScummEngine::initBGBuffers(int height) {
- const byte *ptr;
- int size, itemsize, i;
- byte *room;
-
- if (_version >= 7) {
- // Resize main virtual screen in V7 games. This is necessary
- // because in V7, rooms may be higher than one screen, so we have
- // to accomodate for that.
- initVirtScreen(kMainVirtScreen, virtscr[0].topline, _screenWidth, height, true, true);
- }
-
- if (_heversion >= 70)
- room = getResourceAddress(rtRoomImage, _roomResource);
- else
- room = getResourceAddress(rtRoom, _roomResource);
-
- if (_version <= 3) {
- gdi._numZBuffer = 2;
- } else if (_features & GF_SMALL_HEADER) {
- int off;
- ptr = findResourceData(MKID('SMAP'), room);
- gdi._numZBuffer = 0;
-
- if (_features & GF_16COLOR)
- off = READ_LE_UINT16(ptr);
- else
- off = READ_LE_UINT32(ptr);
-
- while (off && gdi._numZBuffer < 4) {
- gdi._numZBuffer++;
- ptr += off;
- off = READ_LE_UINT16(ptr);
- }
- } else if (_version == 8) {
- // in V8 there is no RMIH and num z buffers is in RMHD
- ptr = findResource(MKID('RMHD'), room);
- gdi._numZBuffer = READ_LE_UINT32(ptr + 24) + 1;
- } else if (_heversion >= 70) {
- ptr = findResource(MKID('RMIH'), room);
- gdi._numZBuffer = READ_LE_UINT16(ptr + 8) + 1;
- } else {
- ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room));
- gdi._numZBuffer = READ_LE_UINT16(ptr + 8) + 1;
- }
- assert(gdi._numZBuffer >= 1 && gdi._numZBuffer <= 8);
-
- if (_version >= 7)
- itemsize = (_roomHeight + 10) * gdi._numStrips;
- else
- itemsize = (_roomHeight + 4) * gdi._numStrips;
-
-
- size = itemsize * gdi._numZBuffer;
- memset(res.createResource(rtBuffer, 9, size), 0, size);
-
- for (i = 0; i < (int)ARRAYSIZE(gdi._imgBufOffs); i++) {
- if (i < gdi._numZBuffer)
- gdi._imgBufOffs[i] = i * itemsize;
- else
- gdi._imgBufOffs[i] = (gdi._numZBuffer - 1) * itemsize;
- }
-}
-
-/**
- * Redraw background as needed, i.e. the left/right sides if scrolling took place etc.
- * Note that this only updated the virtual screen, not the actual display.
- */
-void ScummEngine::redrawBGAreas() {
- int i;
- int diff;
- int val = 0;
-
- if (!(_features & GF_NEW_CAMERA))
- if (camera._cur.x != camera._last.x && _charset->_hasMask && (_version > 3 && _gameId != GID_PASS))
- stopTalk();
-
- // Redraw parts of the background which are marked as dirty.
- if (!_fullRedraw && _bgNeedsRedraw) {
- for (i = 0; i != gdi._numStrips; i++) {
- if (testGfxUsageBit(_screenStartStrip + i, USAGE_BIT_DIRTY)) {
- redrawBGStrip(i, 1);
- }
- }
- }
-
- if (_features & GF_NEW_CAMERA) {
- diff = camera._cur.x / 8 - camera._last.x / 8;
- if (_fullRedraw || ABS(diff) >= gdi._numStrips) {
- _bgNeedsRedraw = false;
- redrawBGStrip(0, gdi._numStrips);
- } else if (diff > 0) {
- val = -diff;
- redrawBGStrip(gdi._numStrips - diff, diff);
- } else if (diff < 0) {
- val = -diff;
- redrawBGStrip(0, -diff);
- }
- } else {
- diff = camera._cur.x - camera._last.x;
- if (!_fullRedraw && diff == 8) {
- val = -1;
- redrawBGStrip(gdi._numStrips - 1, 1);
- } else if (!_fullRedraw && diff == -8) {
- val = +1;
- redrawBGStrip(0, 1);
- } else if (_fullRedraw || diff != 0) {
- _bgNeedsRedraw = false;
- _flashlight.isDrawn = false;
- redrawBGStrip(0, gdi._numStrips);
- }
- }
-
- drawRoomObjects(val);
- _bgNeedsRedraw = false;
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v71he::redrawBGAreas() {
- if (camera._cur.x != camera._last.x && _charset->_hasMask)
- stopTalk();
-
- byte *room = getResourceAddress(rtRoomImage, _roomResource) + _IM00_offs;
- if (_fullRedraw) {
- _bgNeedsRedraw = false;
- gdi.drawBMAPBg(room, &virtscr[0]);
- }
-
- drawRoomObjects(0);
- _bgNeedsRedraw = false;
-}
-
-void ScummEngine_v72he::redrawBGAreas() {
- ScummEngine_v71he::redrawBGAreas();
- _wiz->flushWizBuffer();
-}
-#endif
-
-void ScummEngine::redrawBGStrip(int start, int num) {
- byte *room;
-
- int s = _screenStartStrip + start;
-
- for (int i = 0; i < num; i++)
- setGfxUsageBit(s + i, USAGE_BIT_DIRTY);
-
- if (_heversion >= 70)
- room = getResourceAddress(rtRoomImage, _roomResource);
- else
- room = getResourceAddress(rtRoom, _roomResource);
-
- gdi.drawBitmap(room + _IM00_offs, &virtscr[0], s, 0, _roomWidth, virtscr[0].h, s, num, 0);
-}
-
-void ScummEngine::restoreBG(Common::Rect rect, byte backColor) {
- VirtScreen *vs;
- byte *screenBuf;
-
- if (rect.top < 0)
- rect.top = 0;
- if (rect.left >= rect.right || rect.top >= rect.bottom)
- return;
-
- if ((vs = findVirtScreen(rect.top)) == NULL)
- return;
-
- if (rect.left > vs->w)
- return;
-
- // Convert 'rect' to local (virtual screen) coordinates
- rect.top -= vs->topline;
- rect.bottom -= vs->topline;
-
- rect.clip(vs->w, vs->h);
-
- markRectAsDirty(vs->number, rect, USAGE_BIT_RESTORED);
-
- screenBuf = vs->getPixels(rect.left, rect.top);
-
- const int height = rect.height();
- const int width = rect.width();
-
- if (!height)
- return;
-
- if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) {
- blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height);
- if (vs->number == kMainVirtScreen && _charset->_hasMask) {
- byte *mask = (byte *)_charset->_textSurface.pixels + _charset->_textSurface.pitch * (rect.top - _screenTop) + rect.left;
- fill(mask, _charset->_textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
- }
- } else {
- fill(screenBuf, vs->pitch, backColor, width, height);
- }
-}
-
-void CharsetRenderer::restoreCharsetBg() {
- _nextLeft = _vm->_string[0].xpos;
- _nextTop = _vm->_string[0].ypos + _vm->_screenTop;
-
- if (_hasMask) {
- _hasMask = false;
- _str.left = -1;
- _left = -1;
-
- // Restore background on the whole text area. This code is based on
- // restoreBG(), but was changed to only restore those parts which are
- // currently covered by the charset mask.
-
- VirtScreen *vs = &_vm->virtscr[_textScreenID];
- if (!vs->h)
- return;
-
- _vm->markRectAsDirty(vs->number, Common::Rect(vs->w, vs->h), USAGE_BIT_RESTORED);
-
- byte *screenBuf = vs->getPixels(0, 0);
-
- if (vs->hasTwoBuffers && _vm->_currentRoom != 0 && _vm->isLightOn()) {
- if (vs->number != kMainVirtScreen) {
- // Restore from back buffer
- const byte *backBuf = vs->getBackPixels(0, 0);
- blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h);
- }
- } else {
- // Clear area
- memset(screenBuf, 0, vs->h * vs->pitch);
- }
-
- if (vs->hasTwoBuffers) {
- // Clean out the charset mask
- clearTextSurface();
- }
- }
-}
-
-void CharsetRenderer::clearCharsetMask() {
- memset(_vm->getResourceAddress(rtBuffer, 9), 0, _vm->gdi._imgBufOffs[1]);
-}
-
-void CharsetRenderer::clearTextSurface() {
- memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, _textSurface.pitch * _textSurface.h);
-}
-
-byte *ScummEngine::getMaskBuffer(int x, int y, int z) {
- return gdi.getMaskBuffer((x + virtscr[0].xstart) / 8, y, z);
-}
-
-byte *Gdi::getMaskBuffer(int x, int y, int z) {
- return _vm->getResourceAddress(rtBuffer, 9)
- + x + y * _numStrips + _imgBufOffs[z];
-}
-
-
-#pragma mark -
-#pragma mark --- Misc ---
-#pragma mark -
-
-static void blit(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
- assert(w > 0);
- assert(h > 0);
- assert(src != NULL);
- assert(dst != NULL);
-
- if (w == srcPitch && w == dstPitch) {
- memcpy(dst, src, w*h);
- } else {
- do {
- memcpy(dst, src, w);
- dst += dstPitch;
- src += srcPitch;
- } while (--h);
- }
-}
-
-static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
- assert(h > 0);
- assert(dst != NULL);
-
- if (w == dstPitch) {
- memset(dst, color, w*h);
- } else {
- do {
- memset(dst, color, w);
- dst += dstPitch;
- } while (--h);
- }
-}
-
-static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
- do {
-#if defined(SCUMM_NEED_ALIGNMENT)
- memcpy(dst, src, 8);
-#else
- ((uint32 *)dst)[0] = ((const uint32 *)src)[0];
- ((uint32 *)dst)[1] = ((const uint32 *)src)[1];
-#endif
- dst += dstPitch;
- src += dstPitch;
- } while (--height);
-}
-
-static void clear8Col(byte *dst, int dstPitch, int height) {
- do {
-#if defined(SCUMM_NEED_ALIGNMENT)
- memset(dst, 0, 8);
-#else
- ((uint32 *)dst)[0] = 0;
- ((uint32 *)dst)[1] = 0;
-#endif
- dst += dstPitch;
- } while (--height);
-}
-
-void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
- int width, height;
- VirtScreen *vs;
- byte *backbuff, *bgbuff;
-
- if ((vs = findVirtScreen(y)) == NULL)
- return;
-
- if (x > x2)
- SWAP(x, x2);
-
- if (y > y2)
- SWAP(y, y2);
-
- x2++;
- y2++;
-
- // Adjust for the topline of the VirtScreen
- y -= vs->topline;
- y2 -= vs->topline;
-
- // Clip the coordinates
- if (x < 0)
- x = 0;
- else if (x >= vs->w)
- return;
-
- if (x2 < 0)
- return;
- else if (x2 > vs->w)
- x2 = vs->w;
-
- if (y < 0)
- y = 0;
- else if (y > vs->h)
- return;
-
- if (y2 < 0)
- return;
- else if (y2 > vs->h)
- y2 = vs->h;
-
- width = x2 - x;
- height = y2 - y;
-
- // This will happen in the Sam & Max intro - see bug #1039162 - where
- // it would trigger an assertion in blit().
-
- if (width <= 0 || height <= 0)
- return;
-
- markRectAsDirty(vs->number, x, x2, y, y2);
-
- backbuff = vs->getPixels(x, y);
- bgbuff = vs->getBackPixels(x, y);
-
- if (color == -1) {
- if (vs->number != kMainVirtScreen)
- error("can only copy bg to main window");
- blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
- if (_charset->_hasMask) {
- byte *mask = (byte *)_charset->_textSurface.pixels + _charset->_textSurface.pitch * (y - _screenTop) + x;
- fill(mask, _charset->_textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
- }
- } else if (_heversion == 100) {
- // Flags are used for different methods in HE games
- int32 flags = color;
- if (flags & 0x4000000) {
- blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
- } else if (flags & 0x2000000) {
- blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height);
- } else if (flags & 0x1000000) {
- flags &= 0xFFFFFF;
- fill(backbuff, vs->pitch, flags, width, height);
- fill(bgbuff, vs->pitch, flags, width, height);
- } else {
- fill(backbuff, vs->pitch, flags, width, height);
- }
- } else {
- // Flags are used for different methods in HE games
- int16 flags = color;
- if (flags & 0x2000) {
- blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
- } else if (flags & 0x4000) {
- blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height);
- } else if (flags & 0x8000) {
- flags &= 0x7FFF;
- fill(backbuff, vs->pitch, flags, width, height);
- fill(bgbuff, vs->pitch, flags, width, height);
- } else {
- fill(backbuff, vs->pitch, flags, width, height);
- }
- }
-}
-
-void ScummEngine::drawFlashlight() {
- int i, j, x, y;
- VirtScreen *vs = &virtscr[kMainVirtScreen];
-
- // Remove the flash light first if it was previously drawn
- if (_flashlight.isDrawn) {
- markRectAsDirty(kMainVirtScreen, _flashlight.x, _flashlight.x + _flashlight.w,
- _flashlight.y, _flashlight.y + _flashlight.h, USAGE_BIT_DIRTY);
-
- if (_flashlight.buffer) {
- fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h);
- }
- _flashlight.isDrawn = false;
- }
-
- if (_flashlight.xStrips == 0 || _flashlight.yStrips == 0)
- return;
-
- // Calculate the area of the flashlight
- if (_gameId == GID_ZAK || _gameId == GID_MANIAC) {
- x = _mouse.x + vs->xstart;
- y = _mouse.y - vs->topline;
- } else {
- Actor *a = derefActor(VAR(VAR_EGO), "drawFlashlight");
- x = a->_pos.x;
- y = a->_pos.y;
- }
- _flashlight.w = _flashlight.xStrips * 8;
- _flashlight.h = _flashlight.yStrips * 8;
- _flashlight.x = x - _flashlight.w / 2 - _screenStartStrip * 8;
- _flashlight.y = y - _flashlight.h / 2;
-
- if (_gameId == GID_LOOM)
- _flashlight.y -= 12;
-
- // Clip the flashlight at the borders
- if (_flashlight.x < 0)
- _flashlight.x = 0;
- else if (_flashlight.x + _flashlight.w > gdi._numStrips * 8)
- _flashlight.x = gdi._numStrips * 8 - _flashlight.w;
- if (_flashlight.y < 0)
- _flashlight.y = 0;
- else if (_flashlight.y + _flashlight.h> vs->h)
- _flashlight.y = vs->h - _flashlight.h;
-
- // Redraw any actors "under" the flashlight
- for (i = _flashlight.x / 8; i < (_flashlight.x + _flashlight.w) / 8; i++) {
- assert(0 <= i && i < gdi._numStrips);
- setGfxUsageBit(_screenStartStrip + i, USAGE_BIT_DIRTY);
- vs->tdirty[i] = 0;
- vs->bdirty[i] = vs->h;
- }
-
- byte *bgbak;
- _flashlight.buffer = vs->getPixels(_flashlight.x, _flashlight.y);
- bgbak = vs->getBackPixels(_flashlight.x, _flashlight.y);
-
- blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h);
-
- // Round the corners. To do so, we simply hard-code a set of nicely
- // rounded corners.
- static const int corner_data[] = { 8, 6, 4, 3, 2, 2, 1, 1 };
- int minrow = 0;
- int maxcol = _flashlight.w - 1;
- int maxrow = (_flashlight.h - 1) * vs->pitch;
-
- for (i = 0; i < 8; i++, minrow += vs->pitch, maxrow -= vs->pitch) {
- int d = corner_data[i];
-
- for (j = 0; j < d; j++) {
- _flashlight.buffer[minrow + j] = 0;
- _flashlight.buffer[minrow + maxcol - j] = 0;
- _flashlight.buffer[maxrow + j] = 0;
- _flashlight.buffer[maxrow + maxcol - j] = 0;
- }
- }
-
- _flashlight.isDrawn = true;
-}
-
-bool ScummEngine::isLightOn() const {
- return (VAR_CURRENT_LIGHTS == 0xFF) || (VAR(VAR_CURRENT_LIGHTS) & LIGHTMODE_screen);
-}
-
-void ScummEngine::setShake(int mode) {
- if (_shakeEnabled != (mode != 0))
- _fullRedraw = true;
-
- _shakeEnabled = mode != 0;
- _shakeFrame = 0;
- _system->setShakePos(0);
-}
-
-#pragma mark -
-#pragma mark --- Image drawing ---
-#pragma mark -
-
-
-void Gdi::drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, int stripnr, int numstrip) {
- StripTable *table = (_objectMode ? 0 : _roomStrips);
- const int left = (stripnr * 8);
- const int right = left + (numstrip * 8);
- byte *dst;
- byte *mask_ptr;
- const byte *src;
- byte color, data = 0;
- int run;
- bool dither = false;
- byte dither_table[128];
- byte *ptr_dither_table;
- int theX, theY, maxX;
-
- memset(dither_table, 0, sizeof(dither_table));
-
- if (vs->hasTwoBuffers)
- dst = vs->backBuf + y * vs->pitch + x * 8;
- else
- dst = (byte *)vs->pixels + y * vs->pitch + x * 8;
-
- mask_ptr = getMaskBuffer(x, y, 1);
-
-
- if (table) {
- run = table->run[stripnr];
- color = table->color[stripnr];
- src = ptr + table->offsets[stripnr];
- theX = left;
- maxX = right;
- } else {
- run = 1;
- color = 0;
- src = ptr;
- theX = 0;
- maxX = width;
- }
-
- // Decode and draw the image data.
- assert(height <= 128);
- for (; theX < maxX; theX++) {
- ptr_dither_table = dither_table;
- for (theY = 0; theY < height; theY++) {
- if (--run == 0) {
- data = *src++;
- if (data & 0x80) {
- run = data & 0x7f;
- dither = true;
- } else {
- run = data >> 4;
- dither = false;
- }
- color = _roomPalette[data & 0x0f];
- if (run == 0) {
- run = *src++;
- }
- }
- if (!dither) {
- *ptr_dither_table = color;
- }
- if (left <= theX && theX < right) {
- *dst = *ptr_dither_table++;
- dst += vs->pitch;
- }
- }
- if (left <= theX && theX < right) {
- dst -= _vertStripNextInc;
- }
- }
-
-
- // Draw mask (zplane) data
- theY = 0;
-
- if (table) {
- src = ptr + table->zoffsets[stripnr];
- run = table->zrun[stripnr];
- theX = left;
- } else {
- run = *src++;
- theX = 0;
- }
- while (theX < right) {
- const byte runFlag = run & 0x80;
- if (runFlag) {
- run &= 0x7f;
- data = *src++;
- }
- do {
- if (!runFlag)
- data = *src++;
-
- if (left <= theX) {
- *mask_ptr = data;
- mask_ptr += _numStrips;
- }
- theY++;
- if (theY >= height) {
- if (left <= theX) {
- mask_ptr -= _numStrips * height - 1;
- }
- theY = 0;
- theX += 8;
- if (theX >= right)
- break;
- }
- } while (--run);
- run = *src++;
- }
-}
-
-int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage) const {
- int numzbuf;
- int i;
-
- if ((_vm->_features & GF_SMALL_HEADER) || _vm->_version == 8)
- zplane_list[0] = ptr;
- else if (bmapImage)
- zplane_list[0] = _vm->findResource(MKID('BMAP'), ptr);
- else
- zplane_list[0] = _vm->findResource(MKID('SMAP'), ptr);
-
- if (_zbufferDisabled)
- numzbuf = 0;
- else if (_numZBuffer <= 1 || (_vm->_version <= 2))
- numzbuf = _numZBuffer;
- else {
- numzbuf = _numZBuffer;
- assert(numzbuf <= 9);
-
- if (_vm->_features & GF_SMALL_HEADER) {
- if (_vm->_features & GF_16COLOR)
- zplane_list[1] = ptr + READ_LE_UINT16(ptr);
- else {
- zplane_list[1] = ptr + READ_LE_UINT32(ptr);
- if (_vm->_features & GF_OLD256) {
- if (0 == READ_LE_UINT32(zplane_list[1]))
- zplane_list[1] = 0;
- }
- }
- for (i = 2; i < numzbuf; i++) {
- zplane_list[i] = zplane_list[i-1] + READ_LE_UINT16(zplane_list[i-1]);
- }
- } else if (_vm->_version == 8) {
- // Find the OFFS chunk of the ZPLN chunk
- const byte *zplnOffsChunkStart = ptr + 24 + READ_BE_UINT32(ptr + 12);
-
- // Each ZPLN contains a WRAP chunk, which has (as always) an OFFS subchunk pointing
- // at ZSTR chunks. These once more contain a WRAP chunk which contains nothing but
- // an OFFS chunk. The content of this OFFS chunk contains the offsets to the
- // Z-planes.
- // We do not directly make use of this, but rather hard code offsets (like we do
- // for all other Scumm-versions, too). Clearly this is a bit hackish, but works
- // well enough, and there is no reason to assume that there are any cases where it
- // might fail. Still, doing this properly would have the advantage of catching
- // invalid/damaged data files, and allow us to exit gracefully instead of segfaulting.
- for (i = 1; i < numzbuf; i++) {
- zplane_list[i] = zplnOffsChunkStart + READ_LE_UINT32(zplnOffsChunkStart + 4 + i*4) + 16;
- }
- } else {
- const uint32 zplane_tags[] = {
- MKID('ZP00'),
- MKID('ZP01'),
- MKID('ZP02'),
- MKID('ZP03'),
- MKID('ZP04')
- };
-
- for (i = 1; i < numzbuf; i++) {
- zplane_list[i] = _vm->findResource(zplane_tags[i], ptr);
- }
- }
- }
-
- return numzbuf;
-}
-
-/**
- * Draw a bitmap onto a virtual screen. This is main drawing method for room backgrounds
- * and objects, used throughout all SCUMM versions.
- */
-void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
- int stripnr, int numstrip, byte flag) {
- assert(ptr);
- assert(height > 0);
- byte *dstPtr;
- const byte *smap_ptr;
- const byte *z_plane_ptr;
- byte *mask_ptr;
-
- int i;
- const byte *zplane_list[9];
-
- int bottom;
- int numzbuf;
- int sx;
- bool transpStrip = false;
-
- // Check whether lights are turned on or not
- const bool lightsOn = _vm->isLightOn();
-
- _objectMode = (flag & dbObjectMode) == dbObjectMode;
-
- if (_objectMode && _vm->_version == 1) {
- if (_vm->_platform == Common::kPlatformNES) {
- decodeNESObject(ptr, x, y, width, height);
- } else {
- decodeC64Gfx(ptr, _C64.objectMap, (width / 8) * (height / 8) * 3);
- }
- }
-
- CHECK_HEAP;
- if (_vm->_features & GF_SMALL_HEADER) {
- smap_ptr = ptr;
- } else if (_vm->_version == 8) {
- // Skip to the BSTR->WRAP->OFFS chunk
- smap_ptr = ptr + 24;
- } else
- smap_ptr = _vm->findResource(MKID('SMAP'), ptr);
-
- assert(smap_ptr);
-
- numzbuf = getZPlanes(ptr, zplane_list, false);
-
- const byte *tmsk_ptr = NULL;
- if (_vm->_heversion >= 72) {
- tmsk_ptr = _vm->findResource(MKID('TMSK'), ptr);
- }
-
- bottom = y + height;
- if (bottom > vs->h) {
- warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", bottom, vs->h);
- }
-
- _vertStripNextInc = height * vs->pitch - 1;
-
- //
- // Since V3, all graphics data was encoded in strips, which is very efficient
- // for redrawing only parts of the screen. However, V2 is different: here
- // the whole graphics are encoded as one big chunk. That makes it rather
- // dificult to draw only parts of a room/object. We handle the V2 graphics
- // differently from all other (newer) graphic formats for this reason.
- //
- if (_vm->_version == 2)
- drawBitmapV2Helper(ptr, vs, x, y, width, height, stripnr, numstrip);
-
- sx = x - vs->xstart / 8;
- if (sx < 0) {
- numstrip -= -sx;
- x += -sx;
- stripnr += -sx;
- sx = 0;
- }
-
- //if (_vm->_NESStartStrip > 0)
- // stripnr -= _vm->_NESStartStrip;
-
- // Compute the number of strips we have to iterate over.
- // TODO/FIXME: The computation of its initial value looks very fishy.
- // It was added as a kind of hack to fix some corner cases, but it compares
- // the room width to the virtual screen width; but the former should always
- // be bigger than the latter (except for MM NES, maybe)... strange
- int limit = MAX(_vm->_roomWidth, (int) vs->w) / 8 - x;
- if (limit > numstrip)
- limit = numstrip;
- if (limit > _numStrips - sx)
- limit = _numStrips - sx;
- for (int k = 0; k < limit; ++k, ++stripnr) {
- CHECK_HEAP;
-
- if (y < vs->tdirty[sx + k])
- vs->tdirty[sx + k] = y;
-
- if (bottom > vs->bdirty[sx + k])
- vs->bdirty[sx + k] = bottom;
-
- // In the case of a double buffered virtual screen, we draw to
- // the backbuffer, otherwise to the primary surface memory.
- if (vs->hasTwoBuffers)
- dstPtr = vs->backBuf + y * vs->pitch + (x + k) * 8;
- else
- dstPtr = (byte *)vs->pixels + y * vs->pitch + (x + k) * 8;
-
- if (_vm->_version == 1) {
- if (_vm->_platform == Common::kPlatformNES) {
- mask_ptr = getMaskBuffer(x + k, y, 1);
- drawStripNES(dstPtr, mask_ptr, vs->pitch, stripnr, y, height);
- }
- else if (_objectMode)
- drawStripC64Object(dstPtr, vs->pitch, stripnr, width, height);
- else
- drawStripC64Background(dstPtr, vs->pitch, stripnr, height);
- } else if (_vm->_version == 2) {
- // Do nothing here for V2 games - drawing was already handled.
- } else {
- // Do some input verification and make sure the strip/strip offset
- // are actually valid. Normally, this should never be a problem,
- // but if e.g. a savegame gets corrupted, we can easily get into
- // trouble here. See also bug #795214.
- int offset = -1, smapLen;
- if (_vm->_features & GF_16COLOR) {
- smapLen = READ_LE_UINT16(smap_ptr);
- if (stripnr * 2 + 2 < smapLen)
- offset = READ_LE_UINT16(smap_ptr + stripnr * 2 + 2);
- } else if (_vm->_features & GF_SMALL_HEADER) {
- smapLen = READ_LE_UINT32(smap_ptr);
- if (stripnr * 4 + 4 < smapLen)
- offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 4);
- } else {
- smapLen = READ_BE_UINT32(smap_ptr);
- if (stripnr * 4 + 8 < smapLen)
- offset = READ_LE_UINT32(smap_ptr + stripnr * 4 + 8);
- }
- if (offset < 0 || offset >= smapLen) {
- error("drawBitmap: Trying to draw a non-existant strip");
- return;
- }
- transpStrip = decompressBitmap(dstPtr, vs->pitch, smap_ptr + offset, height);
- }
-
- CHECK_HEAP;
- if (vs->hasTwoBuffers) {
- byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x + k) * 8;
- if (lightsOn)
- copy8Col(frontBuf, vs->pitch, dstPtr, height);
- else
- clear8Col(frontBuf, vs->pitch, height);
- }
- CHECK_HEAP;
-
- // COMI and HE games only uses flag value
- if (_vm->_version == 8 || _vm->_heversion >= 60)
- transpStrip = true;
-
- if (_vm->_version == 1) {
- mask_ptr = getMaskBuffer(x + k, y, 1);
- if (_vm->_platform == Common::kPlatformNES) {
- drawStripNESMask(mask_ptr, stripnr, y, height);
- } else {
- drawStripC64Mask(mask_ptr, stripnr, width, height);
- }
- } else if (_vm->_version == 2) {
- // Do nothing here for V2 games - zplane was already handled.
- } else if (flag & dbDrawMaskOnAll) {
- // Sam & Max uses dbDrawMaskOnAll for things like the inventory
- // box and the speech icons. While these objects only have one
- // mask, it should be applied to all the Z-planes in the room,
- // i.e. they should mask every actor.
- //
- // This flag used to be called dbDrawMaskOnBoth, and all it
- // would do was to mask Z-plane 0. (Z-plane 1 would also be
- // masked, because what is now the else-clause used to be run
- // always.) While this seems to be the only way there is to
- // mask Z-plane 0, this wasn't good enough since actors in
- // Z-planes >= 2 would not be masked.
- //
- // The flag is also used by The Dig and Full Throttle, but I
- // don't know what for. At the time of writing, these games
- // are still too unstable for me to investigate.
-
- if (_vm->_version == 8)
- z_plane_ptr = zplane_list[1] + READ_LE_UINT32(zplane_list[1] + stripnr * 4 + 8);
- else
- z_plane_ptr = zplane_list[1] + READ_LE_UINT16(zplane_list[1] + stripnr * 2 + 8);
- for (i = 0; i < numzbuf; i++) {
- mask_ptr = getMaskBuffer(x + k, y, i);
- if (transpStrip && (flag & dbAllowMaskOr))
- decompressMaskImgOr(mask_ptr, z_plane_ptr, height);
- else
- decompressMaskImg(mask_ptr, z_plane_ptr, height);
- }
- } else {
- for (i = 1; i < numzbuf; i++) {
- uint32 offs;
-
- if (!zplane_list[i])
- continue;
-
- if (_vm->_features & GF_OLD_BUNDLE)
- offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2);
- else if (_vm->_features & GF_OLD256)
- offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2 + 4);
- else if (_vm->_features & GF_SMALL_HEADER)
- offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2 + 2);
- else if (_vm->_version == 8)
- offs = READ_LE_UINT32(zplane_list[i] + stripnr * 4 + 8);
- else
- offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2 + 8);
-
- mask_ptr = getMaskBuffer(x + k, y, i);
-
- if (offs) {
- z_plane_ptr = zplane_list[i] + offs;
-
- if (tmsk_ptr) {
- const byte *tmsk = tmsk_ptr + READ_LE_UINT16(tmsk_ptr + 8);
- decompressTMSK(mask_ptr, tmsk, z_plane_ptr, height);
- } else if (transpStrip && (flag & dbAllowMaskOr)) {
- decompressMaskImgOr(mask_ptr, z_plane_ptr, height);
- } else {
- decompressMaskImg(mask_ptr, z_plane_ptr, height);
- }
-
- } else {
- if (!(transpStrip && (flag & dbAllowMaskOr)))
- for (int h = 0; h < height; h++)
- mask_ptr[h * _numStrips] = 0;
- // FIXME: needs better abstraction
- }
- }
- }
- }
-}
-
-/**
- * Draw a bitmap onto a virtual screen. This is main drawing method for room backgrounds
- * used throughout in 7.2+ HE versions.
- *
- * @note This function essentially is a stripped down & special cased version of
- * the generic Gdi::drawBitmap() method.
- */
-void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) {
- const byte *z_plane_ptr;
- byte *mask_ptr;
- const byte *zplane_list[9];
-
- const byte *bmap_ptr = _vm->findResourceData(MKID('BMAP'), ptr);
- assert(bmap_ptr);
-
- byte code = *bmap_ptr++;
- int scrX = _vm->_screenStartStrip * 8;
- byte *dst = (byte *)_vm->virtscr[0].backBuf + scrX;
-
- // The following few lines more or less duplicate decompressBitmap(), only
- // for an area spanning multiple strips. In particular, the codecs 13 & 14
- // in decompressBitmap call drawStripHE()
- _decomp_shr = code % 10;
- _decomp_mask = 0xFF >> (8 - _decomp_shr);
-
- switch (code) {
- case 134:
- case 135:
- case 136:
- case 137:
- case 138:
- drawStripHE(dst, vs->pitch, bmap_ptr, vs->w, vs->h, false);
- break;
- case 144:
- case 145:
- case 146:
- case 147:
- case 148:
- drawStripHE(dst, vs->pitch, bmap_ptr, vs->w, vs->h, true);
- break;
- case 150:
- fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h);
- break;
- default:
- // Alternative russian freddi3 uses badly formatted bitmaps
- debug(0, "Gdi::drawBMAPBg: default case %d", code);
- }
-
- copyVirtScreenBuffers(Common::Rect(vs->w, vs->h));
-
- int numzbuf = getZPlanes(ptr, zplane_list, true);
- if (numzbuf <= 1)
- return;
-
- uint32 offs;
- for (int stripnr = 0; stripnr < _numStrips; stripnr++)
- for (int i = 1; i < numzbuf; i++) {
- if (!zplane_list[i])
- continue;
-
- offs = READ_LE_UINT16(zplane_list[i] + stripnr * 2 + 8);
- mask_ptr = getMaskBuffer(stripnr, 0, i);
-
- if (offs) {
- z_plane_ptr = zplane_list[i] + offs;
- decompressMaskImg(mask_ptr, z_plane_ptr, vs->h);
- }
- }
-}
-
-void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h) {
-#ifndef DISABLE_HE
- const byte *bmap_ptr = _vm->findResourceData(MKID('BMAP'), ptr);
- assert(bmap_ptr);
-
- byte code = *bmap_ptr++;
- int scrX = _vm->_screenStartStrip * 8;
-
- if (code == 8 || code == 9) {
- Common::Rect rScreen(0, 0, vs->w, vs->h);
- byte *dst = (byte *)_vm->virtscr[0].backBuf + scrX;
- Wiz::copyWizImage(dst, bmap_ptr, vs->w, vs->h, x - scrX, y, w, h, &rScreen);
- }
-
- Common::Rect rect1(x, y, x + w, y + h);
- Common::Rect rect2(scrX, 0, vs->w + scrX, vs->h);
-
- if (rect1.intersects(rect2)) {
- rect1.clip(rect2);
- rect1.left -= rect2.left;
- rect1.right -= rect2.left;
- rect1.top -= rect2.top;
- rect1.bottom -= rect2.top;
-
- copyVirtScreenBuffers(rect1);
- }
-#endif
-}
-
-void Gdi::copyVirtScreenBuffers(Common::Rect rect, int dirtybit) {
- byte *src, *dst;
- VirtScreen *vs = &_vm->virtscr[0];
-
- debug(1,"copyVirtScreenBuffers: Left %d Right %d Top %d Bottom %d", rect.left, rect.right, rect.top, rect.bottom);
-
- if (rect.top > vs->h || rect.bottom < 0)
- return;
-
- if (rect.left > vs->w || rect.right < 0)
- return;
-
- rect.left = MAX(0, (int)rect.left);
- rect.left = MIN((int)rect.left, (int)vs->w - 1);
-
- rect.right = MAX(0, (int)rect.right);
- rect.right = MIN((int)rect.right, (int)vs->w);
-
- rect.top = MAX(0, (int)rect.top);
- rect.top = MIN((int)rect.top, (int)vs->h - 1);
-
- rect.bottom = MAX(0, (int)rect.bottom);
- rect.bottom = MIN((int)rect.bottom, (int)vs->h);
-
- const int rw = rect.width();
- const int rh = rect.height();
-
- if (rw == 0 || rh == 0)
- return;
-
- src = _vm->virtscr[0].getBackPixels(rect.left, rect.top);
- dst = _vm->virtscr[0].getPixels(rect.left, rect.top);
-
- assert(rw <= _vm->_screenWidth && rw > 0);
- assert(rh <= _vm->_screenHeight && rh > 0);
- blit(dst, _vm->virtscr[0].pitch, src, _vm->virtscr[0].pitch, rw, rh);
- _vm->markRectAsDirty(kMainVirtScreen, rect, dirtybit);
-}
-
-/**
- * Reset the background behind an actor or blast object.
- */
-void Gdi::resetBackground(int top, int bottom, int strip) {
- VirtScreen *vs = &_vm->virtscr[0];
- byte *backbuff_ptr, *bgbak_ptr;
- int numLinesToProcess;
-
- if (top < 0)
- top = 0;
-
- if (bottom > vs->h)
- bottom = vs->h;
-
- if (top >= bottom)
- return;
-
- assert(0 <= strip && strip < _numStrips);
-
- if (top < vs->tdirty[strip])
- vs->tdirty[strip] = top;
-
- if (bottom > vs->bdirty[strip])
- vs->bdirty[strip] = bottom;
-
- bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8;
- backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8;
-
- numLinesToProcess = bottom - top;
- if (numLinesToProcess) {
- if (_vm->isLightOn()) {
- copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess);
- } else {
- clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess);
- }
- }
-}
-
-bool Gdi::decompressBitmap(byte *dst, int dstPitch, const byte *src, int numLinesToProcess) {
- assert(numLinesToProcess);
-
- if (_vm->_features & GF_16COLOR) {
- drawStripEGA(dst, dstPitch, src, numLinesToProcess);
- return false;
- }
-
- if ((_vm->_platform == Common::kPlatformAmiga) && (_vm->_version >= 4))
- _paletteMod = 16;
- else
- _paletteMod = 0;
-
- byte code = *src++;
- bool transpStrip = false;
- _decomp_shr = code % 10;
- _decomp_mask = 0xFF >> (8 - _decomp_shr);
-
- switch (code) {
- case 1:
- drawStripRaw(dst, dstPitch, src, numLinesToProcess, false);
- break;
-
- case 2:
- unkDecode8(dst, dstPitch, src, numLinesToProcess); /* Ender - Zak256/Indy256 */
- break;
-
- case 3:
- unkDecode9(dst, dstPitch, src, numLinesToProcess); /* Ender - Zak256/Indy256 */
- break;
-
- case 4:
- unkDecode10(dst, dstPitch, src, numLinesToProcess); /* Ender - Zak256/Indy256 */
- break;
-
- case 7:
- unkDecode11(dst, dstPitch, src, numLinesToProcess); /* Ender - Zak256/Indy256 */
- break;
-
- case 8:
- // Used in 3DO versions of HE games
- transpStrip = true;
- drawStrip3DO(dst, dstPitch, src, numLinesToProcess, true);
- break;
-
- case 9:
- drawStrip3DO(dst, dstPitch, src, numLinesToProcess, false);
- break;
-
- case 10:
- // Used in Amiga version of Monkey Island 1
- drawStripEGA(dst, dstPitch, src, numLinesToProcess);
- break;
-
- case 14:
- case 15:
- case 16:
- case 17:
- case 18:
- drawStripBasicV(dst, dstPitch, src, numLinesToProcess, false);
- break;
-
- case 24:
- case 25:
- case 26:
- case 27:
- case 28:
- drawStripBasicH(dst, dstPitch, src, numLinesToProcess, false);
- break;
-
- case 34:
- case 35:
- case 36:
- case 37:
- case 38:
- transpStrip = true;
- drawStripBasicV(dst, dstPitch, src, numLinesToProcess, true);
- break;
-
- case 44:
- case 45:
- case 46:
- case 47:
- case 48:
- transpStrip = true;
- drawStripBasicH(dst, dstPitch, src, numLinesToProcess, true);
- break;
-
- case 64:
- case 65:
- case 66:
- case 67:
- case 68:
- case 104:
- case 105:
- case 106:
- case 107:
- case 108:
- drawStripComplex(dst, dstPitch, src, numLinesToProcess, false);
- break;
-
- case 84:
- case 85:
- case 86:
- case 87:
- case 88:
- case 124:
- case 125:
- case 126:
- case 127:
- case 128:
- transpStrip = true;
- drawStripComplex(dst, dstPitch, src, numLinesToProcess, true);
- break;
-
- case 134:
- case 135:
- case 136:
- case 137:
- case 138:
- drawStripHE(dst, dstPitch, src, 8, numLinesToProcess, false);
- break;
-
- case 143: // Triggered by Russian water
- case 144:
- case 145:
- case 146:
- case 147:
- case 148:
- transpStrip = true;
- drawStripHE(dst, dstPitch, src, 8, numLinesToProcess, true);
- break;
-
- case 149:
- drawStripRaw(dst, dstPitch, src, numLinesToProcess, true);
- break;
-
- default:
- error("Gdi::decompressBitmap: default case %d", code);
- }
-
- return transpStrip;
-}
-
-void Gdi::decompressMaskImg(byte *dst, const byte *src, int height) const {
- byte b, c;
-
- while (height) {
- b = *src++;
-
- if (b & 0x80) {
- b &= 0x7F;
- c = *src++;
-
- do {
- *dst = c;
- dst += _numStrips;
- --height;
- } while (--b && height);
- } else {
- do {
- *dst = *src++;
- dst += _numStrips;
- --height;
- } while (--b && height);
- }
- }
-}
-
-void Gdi::decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const {
- byte srcbits = 0;
- byte srcFlag = 0;
- byte maskFlag = 0;
-
- byte srcCount = 0;
- byte maskCount = 0;
- byte maskbits = 0;
-
- while (height) {
- if (srcCount == 0) {
- srcCount = *src++;
- srcFlag = srcCount & 0x80;
- if (srcFlag) {
- srcCount &= 0x7F;
- srcbits = *src++;
- }
- }
-
- if (srcFlag == 0) {
- srcbits = *src++;
- }
-
- srcCount--;
-
- if (maskCount == 0) {
- maskCount = *tmsk++;
- maskFlag = maskCount & 0x80;
- if (maskFlag) {
- maskCount &= 0x7F;
- maskbits = *tmsk++;
- }
- }
-
- if (maskFlag == 0) {
- maskbits = *tmsk++;
- }
-
- maskCount--;
-
- *dst |= srcbits;
- *dst &= ~maskbits;
-
- dst += _numStrips;
- height--;
- }
-}
-
-void Gdi::decompressMaskImgOr(byte *dst, const byte *src, int height) const {
- byte b, c;
-
- while (height) {
- b = *src++;
-
- if (b & 0x80) {
- b &= 0x7F;
- c = *src++;
-
- do {
- *dst |= c;
- dst += _numStrips;
- --height;
- } while (--b && height);
- } else {
- do {
- *dst |= *src++;
- dst += _numStrips;
- --height;
- } while (--b && height);
- }
- }
-}
-
-void decodeNESTileData(const byte *src, byte *dest) {
- int len = READ_LE_UINT16(src); src += 2;
- const byte *end = src + len;
- src++; // skip number-of-tiles byte, assume it is correct
- while (src < end) {
- byte data = *src++;
- for (int j = 0; j < (data & 0x7F); j++)
- *dest++ = (data & 0x80) ? (*src++) : (*src);
- if (!(data & 0x80))
- src++;
- }
-}
-
-void ScummEngine::decodeNESBaseTiles() {
- byte *basetiles = getResourceAddress(rtCostume, 37);
- _NESBaseTiles = basetiles[2];
- decodeNESTileData(basetiles, _NESPatTable[1]);
-}
-
-static const int v1MMNEScostTables[2][6] = {
- /* desc lens offs data gfx pal */
- { 25, 27, 29, 31, 33, 35},
- { 26, 28, 30, 32, 34, 36}
-};
-void ScummEngine::NES_loadCostumeSet(int n) {
- int i;
- _NESCostumeSet = n;
-
- _NEScostdesc = getResourceAddress(rtCostume, v1MMNEScostTables[n][0]) + 2;
- _NEScostlens = getResourceAddress(rtCostume, v1MMNEScostTables[n][1]) + 2;
- _NEScostoffs = getResourceAddress(rtCostume, v1MMNEScostTables[n][2]) + 2;
- _NEScostdata = getResourceAddress(rtCostume, v1MMNEScostTables[n][3]) + 2;
- decodeNESTileData(getResourceAddress(rtCostume, v1MMNEScostTables[n][4]), _NESPatTable[0]);
- byte *palette = getResourceAddress(rtCostume, v1MMNEScostTables[n][5]) + 2;
- for (i = 0; i < 16; i++) {
- byte c = *palette++;
- if (c == 0x1D) // HACK - switch around colors 0x00 and 0x1D
- c = 0; // so we don't need a zillion extra checks
- else if (c == 0)// for determining the proper background color
- c = 0x1D;
- _NESPalette[1][i] = c;
- }
-
-}
-
-void Gdi::decodeNESGfx(const byte *room) {
- const byte *gdata = room + READ_LE_UINT16(room + 0x0A);
- int tileset = *gdata++;
- int width = READ_LE_UINT16(room + 0x04);
- // int height = READ_LE_UINT16(room + 0x06);
- int i, j, n;
-
- // We have narrow room. so expand it
- if (width < 32) {
- _vm->_NESStartStrip = (32 - width) >> 1;
- } else {
- _vm->_NESStartStrip = 0;
- }
-
- decodeNESTileData(_vm->getResourceAddress(rtCostume, 37 + tileset), _vm->_NESPatTable[1] + _vm->_NESBaseTiles * 16);
- for (i = 0; i < 16; i++) {
- byte c = *gdata++;
- if (c == 0x0D)
- c = 0x1D;
-
- if (c == 0x1D) // HACK - switch around colors 0x00 and 0x1D
- c = 0; // so we don't need a zillion extra checks
- else if (c == 0) // for determining the proper background color
- c = 0x1D;
-
- _vm->_NESPalette[0][i] = c;
- }
- for (i = 0; i < 16; i++) {
- _NES.nametable[i][0] = _NES.nametable[i][1] = 0;
- n = 0;
- while (n < width) {
- byte data = *gdata++;
- for (j = 0; j < (data & 0x7F); j++)
- _NES.nametable[i][2 + n++] = (data & 0x80) ? (*gdata++) : (*gdata);
- if (!(data & 0x80))
- gdata++;
- }
- _NES.nametable[i][width+2] = _NES.nametable[i][width+3] = 0;
- }
- memcpy(_NES.nametableObj,_NES.nametable, 16*64);
-
- const byte *adata = room + READ_LE_UINT16(room + 0x0C);
- for (n = 0; n < 64;) {
- byte data = *adata++;
- for (j = 0; j < (data & 0x7F); j++)
- _NES.attributes[n++] = (data & 0x80) ? (*adata++) : (*adata);
- if (!(n & 7) && (width == 0x1C))
- n += 8;
- if (!(data & 0x80))
- adata++;
- }
- memcpy(_NES.attributesObj, _NES.attributes, 64);
-
- const byte *mdata = room + READ_LE_UINT16(room + 0x0E);
- int mask = *mdata++;
- if (mask == 0) {
- _NES.hasmask = false;
- return;
- }
- _NES.hasmask = true;
- if (mask != 1)
- debug(0,"NES room %i has irregular mask count %i!",_vm->_currentRoom,mask);
- int mwidth = *mdata++;
- for (i = 0; i < 16; i++) {
- n = 0;
- while (n < mwidth) {
- byte data = *mdata++;
- for (j = 0; j < (data & 0x7F); j++)
- _NES.masktable[i][n++] = (data & 0x80) ? (*mdata++) : (*mdata);
- if (!(data & 0x80))
- mdata++;
- }
- }
- memcpy(_NES.masktableObj, _NES.masktable, 16*8);
-}
-
-void Gdi::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height) {
- int x, y;
-
- _NES.objX = xpos;
-
- // decode tile update data
- width /= 8;
- ypos /= 8;
- height /= 8;
-
- for (y = ypos; y < ypos + height; y++) {
- x = xpos;
- while (x < xpos + width) {
- byte len = *ptr++;
- for (int i = 0; i < (len & 0x7F); i++)
- _NES.nametableObj[y][2 + x++] = (len & 0x80) ? (*ptr++) : (*ptr);
- if (!(len & 0x80))
- ptr++;
- }
- }
-
- int ax, ay;
- // decode attribute update data
- y = height / 2;
- ay = ypos;
- while (y) {
- ax = xpos + 2;
- x = 0;
- int adata = 0;
- while (x < (width >> 1)) {
- if (!(x & 3))
- adata = *ptr++;
- byte *dest = &_NES.attributesObj[((ay << 2) & 0x30) | ((ax >> 2) & 0xF)];
-
- int aand = 3;
- int aor = adata & 3;
- if (ay & 0x02) {
- aand <<= 4;
- aor <<= 4;
- }
- if (ax & 0x02) {
- aand <<= 2;
- aor <<= 2;
- }
- *dest = ((~aand) & *dest) | aor;
-
- adata >>= 2;
- ax += 2;
- x++;
- }
- ay += 2;
- y--;
- }
-
- // decode mask update data
- if (!_NES.hasmask)
- return;
- int mx, mwidth;
- int lmask, rmask;
- mx = *ptr++;
- mwidth = *ptr++;
- lmask = *ptr++;
- rmask = *ptr++;
-
- y = 0;
- do {
- byte *dest = &_NES.masktableObj[y + ypos][mx];
- *dest = (*dest & lmask) | *ptr++;
- dest++;
- for (x = 1; x < mwidth; x++) {
- if (x + 1 == mwidth)
- *dest = (*dest & rmask) | *ptr++;
- else
- *dest = *ptr++;
- dest++;
- }
- y++;
- } while (y < height);
-}
-
-void Gdi::drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height) {
- top /= 8;
- height /= 8;
- int x = stripnr + 2; // NES version has a 2 tile gap on each edge
-
- if (_objectMode)
- x += _NES.objX; // for objects, need to start at the left edge of the object, not the screen
- if (x > 63) {
- debug(0,"NES tried to render invalid strip %i",stripnr);
- return;
- }
- for (int y = top; y < top + height; y++) {
- int palette = ((_objectMode ? _NES.attributesObj : _NES.attributes)[((y << 2) & 0x30) | ((x >> 2) & 0xF)] >> (((y & 2) << 1) | (x & 2))) & 0x3;
- int tile = (_objectMode ? _NES.nametableObj : _NES.nametable)[y][x];
-
- for (int i = 0; i < 8; i++) {
- byte c0 = _vm->_NESPatTable[1][tile * 16 + i];
- byte c1 = _vm->_NESPatTable[1][tile * 16 + i + 8];
- for (int j = 0; j < 8; j++)
- dst[j] = _vm->_NESPalette[0][((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | (palette << 2)];
- dst += dstPitch;
- *mask = c0 | c1;
- mask += _numStrips;
- }
- }
-}
-
-void Gdi::drawStripNESMask(byte *dst, int stripnr, int top, int height) const {
- top /= 8;
- height /= 8;
- int x = stripnr; // masks, unlike room graphics, should NOT be adjusted
-
- if (_objectMode)
- x += _NES.objX; // for objects, need to start at the left edge of the object, not the screen
- if (x > 63) {
- debug(0,"NES tried to mask invalid strip %i",stripnr);
- return;
- }
- for (int y = top; y < top + height; y++) {
- byte c;
- if (_NES.hasmask)
- c = (((_objectMode ? _NES.masktableObj : _NES.masktable)[y][x >> 3] >> (x & 7)) & 1) ? 0xFF : 0x00;
- else
- c = 0;
-
- for (int i = 0; i < 8; i++) {
- *dst &= c;
- dst += _numStrips;
- }
- }
-}
-
-void Gdi::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) {
- int charIdx;
- height /= 8;
- for (int y = 0; y < height; y++) {
- _C64.colors[3] = (_C64.colorMap[y + stripnr * height] & 7);
- // Check for room color change in V1 zak
- if (_roomPalette[0] == 255) {
- _C64.colors[2] = _roomPalette[2];
- _C64.colors[1] = _roomPalette[1];
- }
-
- charIdx = _C64.picMap[y + stripnr * height] * 8;
- for (int i = 0; i < 8; i++) {
- byte c = _C64.charMap[charIdx + i];
- dst[0] = dst[1] = _C64.colors[(c >> 6) & 3];
- dst[2] = dst[3] = _C64.colors[(c >> 4) & 3];
- dst[4] = dst[5] = _C64.colors[(c >> 2) & 3];
- dst[6] = dst[7] = _C64.colors[(c >> 0) & 3];
- dst += dstPitch;
- }
- }
-}
-
-void Gdi::drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height) {
- int charIdx;
- height /= 8;
- width /= 8;
- for (int y = 0; y < height; y++) {
- _C64.colors[3] = (_C64.objectMap[(y + height) * width + stripnr] & 7);
- charIdx = _C64.objectMap[y * width + stripnr] * 8;
- for (int i = 0; i < 8; i++) {
- byte c = _C64.charMap[charIdx + i];
- dst[0] = dst[1] = _C64.colors[(c >> 6) & 3];
- dst[2] = dst[3] = _C64.colors[(c >> 4) & 3];
- dst[4] = dst[5] = _C64.colors[(c >> 2) & 3];
- dst[6] = dst[7] = _C64.colors[(c >> 0) & 3];
- dst += dstPitch;
- }
- }
-}
-
-void Gdi::drawStripC64Mask(byte *dst, int stripnr, int width, int height) const {
- int maskIdx;
- height /= 8;
- width /= 8;
- for (int y = 0; y < height; y++) {
- if (_objectMode)
- maskIdx = _C64.objectMap[(y + 2 * height) * width + stripnr] * 8;
- else
- maskIdx = _C64.maskMap[y + stripnr * height] * 8;
- for (int i = 0; i < 8; i++) {
- byte c = _C64.maskChar[maskIdx + i];
-
- // V1/C64 masks are inverted compared to what ScummVM expects
- *dst = c ^ 0xFF;
- dst += _numStrips;
- }
- }
-}
-
-void Gdi::decodeC64Gfx(const byte *src, byte *dst, int size) const {
- int x, z;
- byte color, run, common[4];
-
- for (z = 0; z < 4; z++) {
- common[z] = *src++;
- }
-
- x = 0;
- while (x < size) {
- run = *src++;
- if (run & 0x80) {
- color = common[(run >> 5) & 3];
- run &= 0x1F;
- for (z = 0; z <= run; z++) {
- dst[x++] = color;
- }
- } else if (run & 0x40) {
- run &= 0x3F;
- color = *src++;
- for (z = 0; z <= run; z++) {
- dst[x++] = color;
- }
- } else {
- for (z = 0; z <= run; z++) {
- dst[x++] = *src++;
- }
- }
- }
-}
-
-/**
- * Create and fill a table with offsets to the graphic and mask strips in the
- * given V2 EGA bitmap.
- * @param src the V2 EGA bitmap
- * @param width the width of the bitmap
- * @param height the height of the bitmap
- * @param table the strip table to fill
- * @return filled strip table
- */
-StripTable *Gdi::generateStripTable(const byte *src, int width, int height, StripTable *table) const {
-
- // If no strip table was given to use, allocate a new one
- if (table == 0)
- table = (StripTable *)calloc(1, sizeof(StripTable));
-
- const byte *bitmapStart = src;
- byte color = 0, data = 0;
- int x, y, length = 0;
- byte run = 1;
-
- // Decode the graphics strips, and memorize the run/color values
- // as well as the byte offset.
- for (x = 0 ; x < width; x++) {
-
- if ((x % 8) == 0) {
- assert(x / 8 < 160);
- table->run[x / 8] = run;
- table->color[x / 8] = color;
- table->offsets[x / 8] = src - bitmapStart;
- }
-
- for (y = 0; y < height; y++) {
- if (--run == 0) {
- data = *src++;
- if (data & 0x80) {
- run = data & 0x7f;
- } else {
- run = data >> 4;
- }
- if (run == 0) {
- run = *src++;
- }
- color = data & 0x0f;
- }
- }
- }
-
- // The mask data follows immediately after the graphics.
- x = 0;
- y = height;
- width /= 8;
-
- for (;;) {
- length = *src++;
- const byte runFlag = length & 0x80;
- if (runFlag) {
- length &= 0x7f;
- data = *src++;
- }
- do {
- if (!runFlag)
- data = *src++;
- if (y == height) {
- assert(x < 120);
- table->zoffsets[x] = src - bitmapStart - 1;
- table->zrun[x] = length | runFlag;
- }
- if (--y == 0) {
- if (--width == 0)
- return table;
- x++;
- y = height;
- }
- } while (--length);
- }
-
- return table;
-}
-
-void Gdi::drawStripEGA(byte *dst, int dstPitch, const byte *src, int height) const {
- byte color = 0;
- int run = 0, x = 0, y = 0, z;
-
- while (x < 8) {
- color = *src++;
-
- if (color & 0x80) {
- run = color & 0x3f;
-
- if (color & 0x40) {
- color = *src++;
-
- if (run == 0) {
- run = *src++;
- }
- for (z = 0; z < run; z++) {
- *(dst + y * dstPitch + x) = (z & 1) ? _roomPalette[color & 0xf] + _paletteMod : _roomPalette[color >> 4] + _paletteMod;
-
- y++;
- if (y >= height) {
- y = 0;
- x++;
- }
- }
- } else {
- if (run == 0) {
- run = *src++;
- }
-
- for (z = 0; z < run; z++) {
- *(dst + y * dstPitch + x) = *(dst + y * dstPitch + x - 1);
-
- y++;
- if (y >= height) {
- y = 0;
- x++;
- }
- }
- }
- } else {
- run = color >> 4;
- if (run == 0) {
- run = *src++;
- }
-
- for (z = 0; z < run; z++) {
- *(dst + y * dstPitch + x) = _roomPalette[color & 0xf] + _paletteMod;
-
- y++;
- if (y >= height) {
- y = 0;
- x++;
- }
- }
- }
- }
-}
-
-#define READ_BIT (shift--, dataBit = data & 1, data >>= 1, dataBit)
-#define FILL_BITS(n) do { \
- if (shift < n) { \
- data |= *src++ << shift; \
- shift += 8; \
- } \
- } while (0)
-
-// NOTE: drawStripHE is actually very similar to drawStripComplex
-void Gdi::drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int height, const bool transpCheck) const {
- static const int delta_color[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
- uint32 dataBit, data;
- byte color;
- int shift;
-
- color = *src++;
- data = READ_LE_UINT24(src);
- src += 3;
- shift = 24;
-
- int x = width;
- while (1) {
- if (!transpCheck || color != _transparentColor)
- *dst = _roomPalette[color];
- dst++;
- --x;
- if (x == 0) {
- x = width;
- dst += dstPitch - width;
- --height;
- if (height == 0)
- return;
- }
- FILL_BITS(1);
- if (READ_BIT) {
- FILL_BITS(1);
- if (READ_BIT) {
- FILL_BITS(3);
- color += delta_color[data & 7];
- shift -= 3;
- data >>= 3;
- } else {
- FILL_BITS(_decomp_shr);
- color = data & _decomp_mask;
- shift -= _decomp_shr;
- data >>= _decomp_shr;
- }
- }
- }
-}
-
-#undef READ_BIT
-#undef FILL_BITS
-
-
-void Gdi::drawStrip3DO(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const {
- if (height == 0)
- return;
-
- int decSize = height * 8;
- int curSize = 0;
-
- do {
- uint8 data = *src++;
- uint8 rle = data & 1;
- int len = (data >> 1) + 1;
-
- len = MIN(decSize, len);
- decSize -= len;
-
- if (!rle) {
- for (; len > 0; len--, src++, dst++) {
- if (!transpCheck || *src != _transparentColor)
- *dst = _roomPalette[*src];
- curSize++;
- if (!(curSize & 7))
- dst += dstPitch - 8; // Next row
- }
- } else {
- byte color = *src++;
- for (; len > 0; len--, dst++) {
- if (!transpCheck || color != _transparentColor)
- *dst = _roomPalette[color];
- curSize++;
- if (!(curSize & 7))
- dst += dstPitch - 8; // Next row
- }
- }
- } while (decSize > 0);
-}
-
-
-#define READ_BIT (cl--, bit = bits & 1, bits >>= 1, bit)
-#define FILL_BITS do { \
- if (cl <= 8) { \
- bits |= (*src++ << cl); \
- cl += 8; \
- } \
- } while (0)
-
-void Gdi::drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const {
- byte color = *src++;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
- byte incm, reps;
-
- do {
- int x = 8;
- do {
- FILL_BITS;
- if (!transpCheck || color != _transparentColor)
- *dst = _roomPalette[color] + _paletteMod;
- dst++;
-
- againPos:
- if (!READ_BIT) {
- } else if (!READ_BIT) {
- FILL_BITS;
- color = bits & _decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- } else {
- incm = (bits & 7) - 4;
- cl -= 3;
- bits >>= 3;
- if (incm) {
- color += incm;
- } else {
- FILL_BITS;
- reps = bits & 0xFF;
- do {
- if (!--x) {
- x = 8;
- dst += dstPitch - 8;
- if (!--height)
- return;
- }
- if (!transpCheck || color != _transparentColor)
- *dst = _roomPalette[color] + _paletteMod;
- dst++;
- } while (--reps);
- bits >>= 8;
- bits |= (*src++) << (cl - 8);
- goto againPos;
- }
- }
- } while (--x);
- dst += dstPitch - 8;
- } while (--height);
-}
-
-void Gdi::drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const {
- byte color = *src++;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
- int8 inc = -1;
-
- do {
- int x = 8;
- do {
- FILL_BITS;
- if (!transpCheck || color != _transparentColor)
- *dst = _roomPalette[color] + _paletteMod;
- dst++;
- if (!READ_BIT) {
- } else if (!READ_BIT) {
- FILL_BITS;
- color = bits & _decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- inc = -1;
- } else if (!READ_BIT) {
- color += inc;
- } else {
- inc = -inc;
- color += inc;
- }
- } while (--x);
- dst += dstPitch - 8;
- } while (--height);
-}
-
-void Gdi::drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const {
- byte color = *src++;
- uint bits = *src++;
- byte cl = 8;
- byte bit;
- int8 inc = -1;
-
- int x = 8;
- do {
- int h = height;
- do {
- FILL_BITS;
- if (!transpCheck || color != _transparentColor)
- *dst = _roomPalette[color] + _paletteMod;
- dst += dstPitch;
- if (!READ_BIT) {
- } else if (!READ_BIT) {
- FILL_BITS;
- color = bits & _decomp_mask;
- bits >>= _decomp_shr;
- cl -= _decomp_shr;
- inc = -1;
- } else if (!READ_BIT) {
- color += inc;
- } else {
- inc = -inc;
- color += inc;
- }
- } while (--h);
- dst -= _vertStripNextInc;
- } while (--x);
-}
-
-#undef READ_BIT
-#undef FILL_BITS
-
-/* Ender - Zak256/Indy256 decoders */
-#define READ_BIT_256 \
- do { \
- if ((mask <<= 1) == 256) { \
- buffer = *src++; \
- mask = 1; \
- } \
- bits = ((buffer & mask) != 0); \
- } while (0)
-
-#define READ_N_BITS(n, c) \
- do { \
- c = 0; \
- for (int b = 0; b < n; b++) { \
- READ_BIT_256; \
- c += (bits << b); \
- } \
- } while (0)
-
-#define NEXT_ROW \
- do { \
- dst += dstPitch; \
- if (--h == 0) { \
- if (!--x) \
- return; \
- dst -= _vertStripNextInc; \
- h = height; \
- } \
- } while (0)
-
-void Gdi::drawStripRaw(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const {
- int x;
-
- if (_vm->_features & GF_OLD256) {
- uint h = height;
- x = 8;
- for (;;) {
- *dst = *src++;
- NEXT_ROW;
- }
- } else {
- do {
- for (x = 0; x < 8; x ++) {
- byte color = *src++;
- if (!transpCheck || color != _transparentColor)
- dst[x] = _roomPalette[color] + _paletteMod;
- }
- dst += dstPitch;
- } while (--height);
- }
-}
-
-void Gdi::unkDecode8(byte *dst, int dstPitch, const byte *src, int height) const {
- uint h = height;
-
- int x = 8;
- for (;;) {
- uint run = (*src++) + 1;
- byte color = *src++;
-
- do {
- *dst = _roomPalette[color];
- NEXT_ROW;
- } while (--run);
- }
-}
-
-void Gdi::unkDecode9(byte *dst, int dstPitch, const byte *src, int height) const {
- byte c, bits, color, run;
- int i;
- uint buffer = 0, mask = 128;
- int h = height;
- i = run = 0;
-
- int x = 8;
- for (;;) {
- READ_N_BITS(4, c);
-
- switch (c >> 2) {
- case 0:
- READ_N_BITS(4, color);
- for (i = 0; i < ((c & 3) + 2); i++) {
- *dst = _roomPalette[run * 16 + color];
- NEXT_ROW;
- }
- break;
-
- case 1:
- for (i = 0; i < ((c & 3) + 1); i++) {
- READ_N_BITS(4, color);
- *dst = _roomPalette[run * 16 + color];
- NEXT_ROW;
- }
- break;
-
- case 2:
- READ_N_BITS(4, run);
- break;
- }
- }
-}
-
-void Gdi::unkDecode10(byte *dst, int dstPitch, const byte *src, int height) const {
- int i;
- byte local_palette[256], numcolors = *src++;
- uint h = height;
-
- for (i = 0; i < numcolors; i++)
- local_palette[i] = *src++;
-
- int x = 8;
-
- for (;;) {
- byte color = *src++;
- if (color < numcolors) {
- *dst = _roomPalette[local_palette[color]];
- NEXT_ROW;
- } else {
- uint run = color - numcolors + 1;
- color = *src++;
- do {
- *dst = _roomPalette[color];
- NEXT_ROW;
- } while (--run);
- }
- }
-}
-
-
-void Gdi::unkDecode11(byte *dst, int dstPitch, const byte *src, int height) const {
- int bits, i;
- uint buffer = 0, mask = 128;
- byte inc = 1, color = *src++;
-
- int x = 8;
- do {
- int h = height;
- do {
- *dst = _roomPalette[color];
- dst += dstPitch;
- for (i = 0; i < 3; i++) {
- READ_BIT_256;
- if (!bits)
- break;
- }
- switch (i) {
- case 1:
- inc = -inc;
- color -= inc;
- break;
-
- case 2:
- color -= inc;
- break;
-
- case 3:
- inc = 1;
- READ_N_BITS(8, color);
- break;
- }
- } while (--h);
- dst -= _vertStripNextInc;
- } while (--x);
-}
-
-#undef NEXT_ROW
-#undef READ_BIT_256
-
-
-#pragma mark -
-#pragma mark --- Transition effects ---
-#pragma mark -
-
-void ScummEngine::fadeIn(int effect) {
- updatePalette();
-
- switch (effect) {
- case 0:
- // seems to do nothing
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- // Some of the transition effects won't work properly unless
- // the screen is marked as clean first. At first I thought I
- // could safely do this every time fadeIn() was called, but
- // that broke the FOA intro. Probably other things as well.
- //
- // Hopefully it's safe to do it at this point, at least.
- virtscr[0].setDirtyRange(0, 0);
- transitionEffect(effect - 1);
- break;
- case 128:
- unkScreenEffect6();
- break;
- case 129:
- break;
- case 130:
- case 131:
- case 132:
- case 133:
- scrollEffect(133 - effect);
- break;
- case 134:
- dissolveEffect(1, 1);
- break;
- case 135:
- dissolveEffect(1, virtscr[0].h);
- break;
- default:
- error("Unknown screen effect, %d", effect);
- }
- _screenEffectFlag = true;
-}
-
-void ScummEngine::fadeOut(int effect) {
- VirtScreen *vs = &virtscr[0];
-
- vs->setDirtyRange(0, 0);
- if (!(_features & GF_NEW_CAMERA))
- camera._last.x = camera._cur.x;
-
- if (_switchRoomEffect >= 130 && _switchRoomEffect <= 133) {
- // We're going to use scrollEffect(), so we'll need a copy of
- // the current VirtScreen zero.
-
- free(_scrollBuffer);
- _scrollBuffer = (byte *) malloc(vs->h * vs->pitch);
- memcpy(_scrollBuffer, vs->getPixels(0, 0), vs->h * vs->pitch);
- }
-
-
- if (_screenEffectFlag && effect != 0) {
-
- // Fill screen 0 with black
- memset(vs->getPixels(0, 0), 0, vs->pitch * vs->h);
-
- // Fade to black with the specified effect, if any.
- switch (effect) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- transitionEffect(effect - 1);
- break;
- case 128:
- unkScreenEffect6();
- break;
- case 129:
- // Just blit screen 0 to the display (i.e. display will be black)
- vs->setDirtyRange(0, vs->h);
- updateDirtyScreen(kMainVirtScreen);
- break;
- case 134:
- dissolveEffect(1, 1);
- break;
- case 135:
- dissolveEffect(1, virtscr[0].h);
- break;
- default:
- error("fadeOut: default case %d", effect);
- }
- }
-
- // Update the palette at the end (once we faded to black) to avoid
- // some nasty effects when the palette is changed
- updatePalette();
-
- _screenEffectFlag = false;
-}
-
-/**
- * Perform a transition effect. There are four different effects possible:
- * 0: Iris effect
- * 1: Box wipe (a black box expands from the upper-left corner to the lower-right corner)
- * 2: Box wipe (a black box expands from the lower-right corner to the upper-left corner)
- * 3: Inverse box wipe
- * All effects operate on 8x8 blocks of the screen. These blocks are updated
- * in a certain order; the exact order determines how the effect appears to the user.
- * @param a the transition effect to perform
- */
-void ScummEngine::transitionEffect(int a) {
- int delta[16]; // Offset applied during each iteration
- int tab_2[16];
- int i, j;
- int bottom;
- int l, t, r, b;
- const int height = MIN((int)virtscr[0].h, _screenHeight);
-
- for (i = 0; i < 16; i++) {
- delta[i] = transitionEffects[a].deltaTable[i];
- j = transitionEffects[a].stripTable[i];
- if (j == 24)
- j = height / 8 - 1;
- tab_2[i] = j;
- }
-
- bottom = height / 8;
- for (j = 0; j < transitionEffects[a].numOfIterations; j++) {
- for (i = 0; i < 4; i++) {
- l = tab_2[i * 4];
- t = tab_2[i * 4 + 1];
- r = tab_2[i * 4 + 2];
- b = tab_2[i * 4 + 3];
-
- if (t == b) {
- while (l <= r) {
- if (l >= 0 && l < gdi._numStrips && t < bottom) {
- virtscr[0].tdirty[l] = _screenTop + t * 8;
- virtscr[0].bdirty[l] = _screenTop + (b + 1) * 8;
- }
- l++;
- }
- } else {
- if (l < 0 || l >= gdi._numStrips || b <= t)
- continue;
- if (b > bottom)
- b = bottom;
- if (t < 0)
- t = 0;
- virtscr[0].tdirty[l] = _screenTop + t * 8;
- virtscr[0].bdirty[l] = _screenTop + (b + 1) * 8;
- }
- updateDirtyScreen(kMainVirtScreen);
- }
-
- for (i = 0; i < 16; i++)
- tab_2[i] += delta[i];
-
- // Draw the current state to the screen and wait half a sec so the user
- // can watch the effect taking place.
- _system->updateScreen();
- waitForTimer(30);
- }
-}
-
-/**
- * Update width*height areas of the screen, in random order, until the whole
- * screen has been updated. For instance:
- *
- * dissolveEffect(1, 1) produces a pixel-by-pixel dissolve
- * dissolveEffect(8, 8) produces a square-by-square dissolve
- * dissolveEffect(virtsrc[0].width, 1) produces a line-by-line dissolve
- */
-void ScummEngine::dissolveEffect(int width, int height) {
-#ifdef PALMOS_68K
- // Remove this dissolve effect for now on PalmOS since it is a bit
- // too slow using 68k emulation
- if (width == 1 && height == 1) {
- waitForTimer(30);
- return;
- }
-#endif
-
- VirtScreen *vs = &virtscr[0];
- int *offsets;
- int blits_before_refresh, blits;
- int x, y;
- int w, h;
- int i;
-
- // There's probably some less memory-hungry way of doing this. But
- // since we're only dealing with relatively small images, it shouldn't
- // be too bad.
-
- w = vs->w / width;
- h = vs->h / height;
-
- // When used correctly, vs->width % width and vs->height % height
- // should both be zero, but just to be safe...
-
- if (vs->w % width)
- w++;
-
- if (vs->h % height)
- h++;
-
- offsets = (int *) malloc(w * h * sizeof(int));
- if (offsets == NULL)
- error("dissolveEffect: out of memory");
-
- // Create a permutation of offsets into the frame buffer
-
- if (width == 1 && height == 1) {
- // Optimized case for pixel-by-pixel dissolve
-
- for (i = 0; i < vs->w * vs->h; i++)
- offsets[i] = i;
-
- for (i = 1; i < w * h; i++) {
- int j;
-
- j = _rnd.getRandomNumber(i - 1);
- offsets[i] = offsets[j];
- offsets[j] = i;
- }
- } else {
- int *offsets2;
-
- for (i = 0, x = 0; x < vs->w; x += width)
- for (y = 0; y < vs->h; y += height)
- offsets[i++] = y * vs->pitch + x;
-
- offsets2 = (int *) malloc(w * h * sizeof(int));
- if (offsets2 == NULL)
- error("dissolveEffect: out of memory");
-
- memcpy(offsets2, offsets, w * h * sizeof(int));
-
- for (i = 1; i < w * h; i++) {
- int j;
-
- j = _rnd.getRandomNumber(i - 1);
- offsets[i] = offsets[j];
- offsets[j] = offsets2[i];
- }
-
- free(offsets2);
- }
-
- // Blit the image piece by piece to the screen. The idea here is that
- // the whole update should take about a quarter of a second, assuming
- // most of the time is spent in waitForTimer(). It looks good to me,
- // but might still need some tuning.
-
- blits = 0;
- blits_before_refresh = (3 * w * h) / 25;
-
- // Speed up the effect for CD Loom since it uses it so often. I don't
- // think the original had any delay at all, so on modern hardware it
- // wasn't even noticeable.
- if (_gameId == GID_LOOM && (_version == 4))
- blits_before_refresh *= 2;
-
- for (i = 0; i < w * h; i++) {
- x = offsets[i] % vs->pitch;
- y = offsets[i] / vs->pitch;
- _system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
-
- if (++blits >= blits_before_refresh) {
- blits = 0;
- _system->updateScreen();
- waitForTimer(30);
- }
- }
-
- free(offsets);
-
- if (blits != 0) {
- _system->updateScreen();
- waitForTimer(30);
- }
-}
-
-void ScummEngine::scrollEffect(int dir) {
- // It is at least technically possible that this function will be
- // called without _scrollBuffer having been set up, but will it ever
- // happen? I don't know.
- if (!_scrollBuffer)
- warning("scrollEffect: No scroll buffer. This may look bad");
-
- VirtScreen *vs = &virtscr[0];
-
- int x, y;
- int step;
-
- if ((dir == 0) || (dir == 1))
- step = vs->h;
- else
- step = vs->w;
-
- step = (step * kPictureDelay) / kScrolltime;
-
- switch (dir) {
- case 0:
- //up
- y = step;
- while (y < vs->h) {
- _system->copyRectToScreen(vs->getPixels(0, 0),
- vs->pitch,
- 0, vs->h - y,
- vs->w, y);
- if (_scrollBuffer)
- _system->copyRectToScreen(_scrollBuffer + y * vs->w,
- vs->pitch,
- 0, 0,
- vs->w, vs->h - y);
- _system->updateScreen();
- waitForTimer(kPictureDelay);
-
- y += step;
- }
- break;
- case 1:
- // down
- y = step;
- while (y < vs->h) {
- _system->copyRectToScreen(vs->getPixels(0, vs->h - y),
- vs->pitch,
- 0, 0,
- vs->w, y);
- if (_scrollBuffer)
- _system->copyRectToScreen(_scrollBuffer,
- vs->pitch,
- 0, y,
- vs->w, vs->h - y);
- _system->updateScreen();
- waitForTimer(kPictureDelay);
-
- y += step;
- }
- break;
- case 2:
- // left
- x = step;
- while (x < vs->w) {
- _system->copyRectToScreen(vs->getPixels(0, 0),
- vs->pitch,
- vs->w - x, 0,
- x, vs->h);
- if (_scrollBuffer)
- _system->copyRectToScreen(_scrollBuffer + x,
- vs->pitch,
- 0, 0,
- vs->w - x, vs->h);
- _system->updateScreen();
- waitForTimer(kPictureDelay);
-
- x += step;
- }
- break;
- case 3:
- // right
- x = step;
- while (x < vs->w) {
- _system->copyRectToScreen(vs->getPixels(vs->w - x, 0),
- vs->pitch,
- 0, 0,
- x, vs->h);
- if (_scrollBuffer)
- _system->copyRectToScreen(_scrollBuffer,
- vs->pitch,
- x, 0,
- vs->w - x, vs->h);
- _system->updateScreen();
- waitForTimer(kPictureDelay);
-
- x += step;
- }
- break;
- }
-
- free(_scrollBuffer);
- _scrollBuffer = NULL;
-}
-
-void ScummEngine::unkScreenEffect6() {
- // CD Loom (but not EGA Loom!) uses a more fine-grained dissolve
- if (_gameId == GID_LOOM && (_version == 4))
- dissolveEffect(1, 1);
- else
- dissolveEffect(8, 4);
-}
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Gfx)
-_GSETPTR(Scumm::transitionEffects, GBVARS_TRANSITIONEFFECTS_INDEX, Scumm::TransitionEffect, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Gfx)
-_GRELEASEPTR(GBVARS_TRANSITIONEFFECTS_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/gfx.h b/scumm/gfx.h
deleted file mode 100644
index 9aa8461c2c..0000000000
--- a/scumm/gfx.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef GFX_H
-#define GFX_H
-
-#include "graphics/surface.h"
-
-namespace Scumm {
-
-class ScummEngine;
-
-/** Camera modes */
-enum {
- kNormalCameraMode = 1,
- kFollowActorCameraMode = 2,
- kPanningCameraMode = 3
-};
-
-/** Camera state data */
-struct CameraData {
- Common::Point _cur;
- Common::Point _dest;
- Common::Point _accel;
- Common::Point _last;
- int _leftTrigger, _rightTrigger;
- byte _follows, _mode;
- bool _movingToActor;
-};
-
-/** Virtual screen identifiers */
-enum VirtScreenNumber {
- kMainVirtScreen = 0, // The 'stage'
- kTextVirtScreen = 1, // In V1-V3 games: the area where text is printed
- kVerbVirtScreen = 2, // The verb area
- kUnkVirtScreen = 3 // ?? Not sure what this one is good for...
-};
-
-/**
- * In all Scumm games, one to four virtual screen (or 'windows') together make
- * up the content of the actual screen. Thinking of virtual screens as fixed
- * size, fixed location windows might help understanding them. Typical, in all
- * scumm games there is either one single virtual screen covering the entire
- * real screen (mostly in all newer games, e.g. Sam & Max, and all V7+ games).
- * The classic setup consists of three virtual screens: one at the top of the
- * screen, where all conversation texts are printed; then the main one (which
- * I like calling 'the stage', since all the actors are doing their stuff
- * there), and finally the lower part of the real screen is taken up by the
- * verb area.
- * Finally, in V5 games and some V6 games, it's almost the same as in the
- * original games, except that there is no separate conversation area.
- *
- * If you now wonder what the last screen is/was good for: I am not 100% sure,
- * but it appears that it was used by the original engine to display stuff
- * like the pause message, or questions ("Do you really want to restart?").
- * It seems that it is not used at all by ScummVM, so we probably could just
- * get rid of it and save a couple kilobytes of RAM.
- *
- * Each of these virtual screens has a fixed number or id (see also
- * \ref VirtScreenNumber).
- */
-struct VirtScreen : Graphics::Surface {
- /**
- * The unique id of this screen (corresponds to its position in the
- * ScummEngine:virtscr array).
- */
- VirtScreenNumber number;
-
- /**
- * Vertical position of the virtual screen. Tells how much the virtual
- * screen is shifted along the y axis relative to the real screen.
- */
- uint16 topline;
-
- /**
- * Horizontal scroll offset, tells how far the screen is scrolled to the
- * right. Only used for the main screen. After all, verbs and the
- * conversation text box don't have to scroll.
- */
- uint16 xstart;
-
- /**
- * Flag indicating whether this screen has a back buffer or not. This is
- * yet another feature which is only used by the main screen.
- * Strictly spoken one could remove this variable and replace checks
- * on it with checks on backBuf. But since some code needs to temporarily
- * disable the backBuf (so it can abuse drawBitmap; see drawVerbBitmap()
- * and useIm01Cursor()), we keep it (at least for now).
- */
- bool hasTwoBuffers;
-
- /**
- * Pointer to the screen's back buffer, if it has one (see also
- * the hasTwoBuffers member).
- * The backBuf is used by drawBitmap to store the background graphics of
- * the active room. This eases redrawing: whenever a portion of the screen
- * has to be redrawn, first a copy from the backBuf content to screenPtr is
- * performed. Then, any objects/actors in that area are redrawn atop that.
- */
- byte *backBuf;
-
- /**
- * Array containing for each visible strip of this virtual screen the
- * coordinate at which the dirty region of that strip starts.
- * 't' stands for 'top' - the top coordinate of the dirty region.
- * This together with bdirty is used to do efficient redrawing of
- * the screen.
- */
- uint16 tdirty[80 + 1];
-
- /**
- * Array containing for each visible strip of this virtual screen the
- * coordinate at which the dirty region of that strip end.
- * 'b' stands for 'bottom' - the bottom coordinate of the dirty region.
- * This together with tdirty is used to do efficient redrawing of
- * the screen.
- */
- uint16 bdirty[80 + 1];
-
- /**
- * Convenience method to set the whole tdirty and bdirty arrays to one
- * specific value each. This is mostly used to mark every as dirty in
- * a single step, like so:
- * vs->setDirtyRange(0, vs->height);
- * or to mark everything as clean, like so:
- * vs->setDirtyRange(0, 0);
- */
- void setDirtyRange(int top, int bottom) {
- for (int i = 0; i < 80 + 1; i++) {
- tdirty[i] = top;
- bdirty[i] = bottom;
- }
- }
-
- byte *getPixels(int x, int y) const {
- return (byte *)pixels + xstart + y * pitch + x;
- }
-
- byte *getBackPixels(int x, int y) const {
- return (byte *)backBuf + xstart + y * pitch + x;
- }
-};
-
-/** Palette cycles */
-struct ColorCycle {
- uint16 delay;
- uint16 counter;
- uint16 flags;
- byte start;
- byte end;
-};
-
-/** Bomp graphics data, used as parameter to ScummEngine::drawBomp. */
-struct BompDrawData {
- Graphics::Surface dst;
-
- int x, y;
- byte scale_x, scale_y;
- const byte *dataptr;
- int srcwidth, srcheight;
- uint16 shadowMode;
-
- byte *maskPtr;
-
- BompDrawData() { memset(this, 0, sizeof(*this)); }
-};
-
-struct StripTable;
-
-#define CHARSET_MASK_TRANSPARENCY 253
-
-class Gdi {
- ScummEngine *_vm;
-
-public:
- int _numZBuffer;
- int _imgBufOffs[8];
- int32 _numStrips;
-
- Gdi(ScummEngine *vm);
- ~Gdi();
-
-protected:
- byte _paletteMod;
- byte *_roomPalette;
- byte _transparentColor;
- byte _decomp_shr, _decomp_mask;
- uint32 _vertStripNextInc;
-
- bool _zbufferDisabled;
-
- /** Flag which is true when an object is being rendered, false otherwise. */
- bool _objectMode;
-
- /** Render settings which are specific to the C64 graphic decoders. */
- struct {
- byte colors[4];
- byte charMap[2048], objectMap[2048], picMap[4096], colorMap[4096];
- byte maskMap[4096], maskChar[4096];
- } _C64;
-
- struct {
- byte nametable[16][64], nametableObj[16][64];
- byte attributes[64], attributesObj[64];
- byte masktable[16][8], masktableObj[16][8];
- int objX;
- bool hasmask;
- } _NES;
-
- /** For V2 games, we cache offsets into the room graphics, to speed up things. */
- StripTable *_roomStrips;
-
- /* Bitmap decompressors */
- bool decompressBitmap(byte *dst, int dstPitch, const byte *src, int numLinesToProcess);
-
- void drawStripEGA(byte *dst, int dstPitch, const byte *src, int height) const;
- void drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height);
- void drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height);
- void drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height);
-
- void drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
- void drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
- void drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
-
- void drawStripRaw(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
- void unkDecode8(byte *dst, int dstPitch, const byte *src, int height) const;
- void unkDecode9(byte *dst, int dstPitch, const byte *src, int height) const;
- void unkDecode10(byte *dst, int dstPitch, const byte *src, int height) const;
- void unkDecode11(byte *dst, int dstPitch, const byte *src, int height) const;
- void drawStrip3DO(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
-
- void drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int height, const bool transpCheck) const;
-
- /* Mask decompressors */
- void drawStripC64Mask(byte *dst, int stripnr, int width, int height) const;
- void drawStripNESMask(byte *dst, int stripnr, int top, int height) const;
- void decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const;
- void decompressMaskImgOr(byte *dst, const byte *src, int height) const;
- void decompressMaskImg(byte *dst, const byte *src, int height) const;
-
- /* Misc */
- void decodeC64Gfx(const byte *src, byte *dst, int size) const;
-
- int getZPlanes(const byte *smap_ptr, const byte *zplane_list[9], bool bmapImage) const;
-
- StripTable *generateStripTable(const byte *src, int width, int height, StripTable *table) const;
- void drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
- int stripnr, int numstrip);
-
-public:
- void init();
- void roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor);
-
- void drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
- int stripnr, int numstrip, byte flag);
-
- void decodeNESGfx(const byte *room);
- void decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height);
-
- void drawBMAPBg(const byte *ptr, VirtScreen *vs);
- void drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h);
-
- void copyVirtScreenBuffers(Common::Rect rect, int dirtybit = 0);
-
- byte *getMaskBuffer(int x, int y, int z);
- void disableZBuffer() { _zbufferDisabled = true; }
- void enableZBuffer() { _zbufferDisabled = false; }
-
- void resetBackground(int top, int bottom, int strip);
-
- enum DrawBitmapFlags {
- dbAllowMaskOr = 1 << 0,
- dbDrawMaskOnAll = 1 << 1,
- dbObjectMode = 2 << 2
- };
-};
-
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/help.cpp b/scumm/help.cpp
deleted file mode 100644
index acc9e67a6d..0000000000
--- a/scumm/help.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/str.h"
-#include "common/util.h"
-
-#include "scumm/help.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-int ScummHelp::numPages(byte gameId) {
- switch (gameId) {
- case GID_MANIAC:
- case GID_ZAK:
- return 4;
- break;
- case GID_INDY3:
- return 6;
- break;
- case GID_LOOM:
- case GID_MONKEY_EGA:
- case GID_MONKEY_VGA:
- case GID_MONKEY:
- case GID_MONKEY2:
- case GID_INDY4:
- case GID_TENTACLE:
- case GID_SAMNMAX:
- case GID_DIG:
- case GID_FT:
- case GID_CMI:
- return 3;
- break;
-/* TODO - I don't know the controls for these games
- case GID_PUTTDEMO:
- case GID_PUTTPUTT:
-*/
- default:
- return 2;
- }
-}
-
-#define ADD_BIND(k,d) do { key[i] = k; dsc[i] = d; i++; } while (0)
-#define ADD_TEXT(d) ADD_BIND("",d)
-#define ADD_LINE ADD_BIND("","")
-
-void ScummHelp::updateStrings(byte gameId, byte version, Common::Platform platform,
- int page, String &title, String *&key, String *&dsc) {
- key = new String[HELP_NUM_LINES];
- dsc = new String[HELP_NUM_LINES];
- int i = 0;
- switch (page) {
- case 1:
- title = "Common keyboard commands:";
- ADD_BIND("F5", "Save / Load dialog");
- if (version >= 5)
- ADD_BIND(".", "Skip line of text");
- ADD_BIND("Esc", "Skip cutscene");
- ADD_BIND("Space", "Pause game");
- ADD_BIND("Ctrl 0-9", "Load game state 1-10");
- ADD_BIND("Alt 0-9", "Save game state 1-10");
-#ifdef MACOSX
- ADD_BIND("Cmd q", "Quit");
-#else
- ADD_BIND("Alt x, Ctrl z", "Quit");
-#endif
- ADD_BIND("Alt Enter", "Toggle fullscreen");
- ADD_BIND("[, ]", "Music volume up / down");
- ADD_BIND("-, +", "Text speed slower / faster");
- ADD_BIND("Enter", "Simulate left mouse button");
- ADD_BIND("Tab", "Simulate right mouse button");
- break;
- case 2:
- title = "Special keyboard commands:";
- ADD_BIND("~, #", "Show / Hide console");
- ADD_BIND("Ctrl d", "Start the debugger");
- ADD_BIND("Ctrl s", "Show memory consumption");
- ADD_BIND("Ctrl f", "Run in fast mode (*)");
- ADD_BIND("Ctrl g", "Run in really fast mode (*)");
- ADD_BIND("Ctrl m", "Toggle mouse capture");
- ADD_BIND("Ctrl Alt 1-8", "Switch between graphics filters");
- ADD_BIND("Ctrl Alt +, -", "Increase / Decrease scale factor");
- ADD_BIND("Ctrl Alt a", "Toggle aspect-ratio correction");
- ADD_LINE;
- ADD_LINE;
- // FIXME: This should use word-wrapping, and should not assume
- // that the font is mono-spaced.
- ADD_TEXT("* Note that using ctrl-f and");
- ADD_TEXT(" ctrl-g are not recommended");
- ADD_TEXT(" since they may cause crashes");
- ADD_TEXT(" or incorrect game behaviour.");
- break;
- case 3:
- if (gameId == GID_LOOM)
- title = "Spinning drafts on the keyboard:";
- else
- title = "Main game controls:";
- switch (gameId) {
- case GID_ZAK:
- case GID_MANIAC:
- // HACK. I know use of g_scumm here is evil, however,
- // introducing new GID and putting it everywhere will
- // pollute code much more that this single instance
- if (g_scumm->_platform == Common::kPlatformNES) {
- ADD_BIND("q", "Push");
- ADD_BIND("a", "Pull");
- ADD_BIND("z", "Give");
- ADD_BIND("w", "Open");
- ADD_BIND("s", "Close");
- ADD_BIND("x", "Go to");
- ADD_BIND("e", "Get");
- ADD_BIND("d", "Use");
- ADD_BIND("c", "Read");
- ADD_BIND("r", "New kid");
- ADD_BIND("f", "Turn on");
- ADD_BIND("v", "Turn off");
- break;
- }
-
- ADD_BIND("q", "Push");
- ADD_BIND("a", "Pull");
- ADD_BIND("z", "Give");
- ADD_BIND("w", "Open");
- ADD_BIND("s", "Close");
- ADD_BIND("x", "Read");
- ADD_BIND("e", "Walk to");
- ADD_BIND("d", "Pick up");
- ADD_BIND("c", "What is");
- if (gameId == GID_MANIAC) {
- ADD_BIND("r", "Unlock");
- ADD_BIND("f", "New kid");
- } else {
- ADD_BIND("r", "Put on");
- ADD_BIND("f", "Take off");
- }
- ADD_BIND("v", "Use");
- ADD_BIND("t", "Turn on");
- ADD_BIND("g", "Turn off");
- if (gameId == GID_MANIAC)
- ADD_BIND("b", "Fix");
- else
- ADD_BIND("b", "Switch");
- break;
- case GID_INDY3:
- ADD_BIND("q", "Push");
- ADD_BIND("a", "Pull");
- ADD_BIND("z", "Give");
- ADD_BIND("w", "Open");
- ADD_BIND("s", "Close");
- ADD_BIND("x", "Look");
- ADD_BIND("e", "Walk to");
- ADD_BIND("d", "Pick up");
- ADD_BIND("c", "What is");
- ADD_BIND("r", "Use");
- ADD_BIND("f", "Turn on");
- ADD_BIND("v", "Turn off");
- ADD_BIND("t", "Talk");
- ADD_BIND("g", "Travel");
- ADD_BIND("b", "To Henry / To Indy");
- break;
- case GID_LOOM:
- ADD_BIND("q, c", "play C minor on distaff");
- ADD_BIND("w, d", "play D on distaff");
- ADD_BIND("e, e", "play E on distaff");
- ADD_BIND("r, f", "play F on distaff");
- ADD_BIND("t, g", "play G on distaff");
- ADD_BIND("y, a", "play A on distaff");
- ADD_BIND("u, b", "play B on distaff");
- ADD_BIND("i, C", "play C major on distaff");
- break;
- case GID_MONKEY_EGA:
- case GID_MONKEY_VGA:
- ADD_BIND("o", "Open");
- ADD_BIND("c", "Close");
- ADD_BIND("s", "puSh");
- ADD_BIND("y", "pull (Yank)");
- ADD_BIND("w", "Walk to");
- ADD_BIND("p", "Pick up");
- ADD_BIND("t", "Talk to");
- ADD_BIND("g", "Give");
- ADD_BIND("u", "Use");
- ADD_BIND("l", "Look at");
- ADD_BIND("n", "turn oN");
- ADD_BIND("f", "turn oFf");
- break;
- case GID_MONKEY:
- case GID_MONKEY2:
- case GID_INDY4:
- case GID_TENTACLE:
- ADD_BIND("g", "Give");
- ADD_BIND("o", "Open");
- ADD_BIND("c", "Close");
- ADD_BIND("p", "Pick up");
- ADD_BIND("l", "Look at");
- ADD_BIND("t", "Talk to");
- ADD_BIND("u", "Use");
- ADD_BIND("s", "puSh");
- ADD_BIND("y", "pull (Yank)");
- if (platform == Common::kPlatformSegaCD) {
- // FIXME look at scripts to figure all options out...
- // keys 1->4 seem to do something as well
- ADD_BIND("6", "Highlight prev dialogue");
- ADD_BIND("7", "Highlight next dialogue");
- }
- break;
- case GID_SAMNMAX:
- ADD_BIND("w", "Walk");
- ADD_BIND("t", "Talk");
- ADD_BIND("u", "Use");
- ADD_BIND("i", "Inventory");
- ADD_BIND("o", "Object");
- ADD_BIND("p", "Pick up");
- ADD_BIND("l", "Look");
- ADD_BIND("b", "Black and White / Color");
- break;
- case GID_FT:
- ADD_BIND("e", "Eyes");
- ADD_BIND("t", "Tongue");
- ADD_BIND("i", "Inventory");
- ADD_BIND("p", "Punch");
- ADD_BIND("k", "Kick");
- break;
- case GID_DIG:
- ADD_BIND("e", "Examine");
- ADD_BIND("t", "Regular cursor");
- ADD_BIND("i", "Inventory");
- ADD_BIND("c", "Comm");
- break;
- case GID_CMI:
- ADD_BIND("F1", "Save / Load / Options");
- ADD_BIND("e", "Examine");
- ADD_BIND("t", "Talk to");
- ADD_BIND("i", "Inventory");
- ADD_BIND("u", "Use");
- break;
- }
- break;
- case 4:
- title = "Other game controls:";
- if (version <= 2) {
- ADD_TEXT("Inventory: (not yet implemented)");
- ADD_BIND("u", "Scroll list up");
- ADD_BIND("j", "Scroll list down");
- ADD_BIND("i", "Upper left item");
- ADD_BIND("k", "Lower left item");
- ADD_BIND("o", "Upper right item");
- ADD_BIND("l", "Lower right item");
- ADD_LINE;
- ADD_TEXT("Switching characters:");
- if (gameId == GID_MANIAC) {
- ADD_BIND("F1", "Dave");
- ADD_BIND("F2", "Second kid");
- ADD_BIND("F3", "Third kid");
- } else {
- ADD_BIND("F1", "Zak");
- ADD_BIND("F2", "Annie");
- ADD_BIND("F3", "Melissa");
- ADD_BIND("F4", "Leslie");
- }
- } else if (gameId == GID_INDY3 || gameId == GID_ZAK) {
- // Indy3, or FM-TOWNS Zak
- ADD_TEXT("Inventory:");
- ADD_BIND("y", "Upper left item");
- ADD_BIND("h", "Middle left item");
- ADD_BIND("n", "Lower left item");
- ADD_BIND("u", "Upper right item");
- ADD_BIND("j", "Middle right item");
- ADD_BIND("m", "Lower right item");
- ADD_BIND("o", "Scroll list up");
- ADD_BIND("l", "Scroll list down");
- if (gameId == GID_ZAK) {
- ADD_LINE;
- ADD_TEXT("Switching characters:");
- ADD_BIND("F1", "Zak");
- ADD_BIND("F2", "Annie");
- ADD_BIND("F3", "Melissa");
- ADD_BIND("F4", "Leslie");
- }
- }
- break;
- case 5:
- switch (gameId) {
- case GID_INDY3:
- title = "Fighting controls (numpad):";
- ADD_BIND("7", "Step back");
- ADD_BIND("4", "Step back");
- ADD_BIND("1", "Step back");
- ADD_BIND("8", "Block high");
- ADD_BIND("5", "Block middle");
- ADD_BIND("2", "Block low");
- ADD_BIND("9", "Punch high");
- ADD_BIND("6", "Punch middle");
- ADD_BIND("3", "Punch low");
- ADD_LINE;
- ADD_LINE;
- ADD_TEXT("These are for Indy on left.");
- ADD_TEXT("When Indy is on the right,");
- ADD_TEXT("7, 4, and 1 are switched with");
- ADD_TEXT("9, 6, and 3, respectively.");
- break;
- }
- break;
- case 6:
- switch (gameId) {
- case GID_INDY3:
- title = "Biplane controls (numpad):";
- ADD_BIND("7", "Fly to upper left");
- ADD_BIND("4", "Fly to left");
- ADD_BIND("1", "Fly to lower left");
- ADD_BIND("8", "Fly upwards");
- ADD_BIND("5", "Fly straight");
- ADD_BIND("2", "Fly down");
- ADD_BIND("9", "Fly to upper right");
- ADD_BIND("6", "Fly to right");
- ADD_BIND("3", "Fly to lower right");
- break;
- }
- break;
- }
- while (i < HELP_NUM_LINES) {
- ADD_LINE;
- }
-}
-
-#undef ADD_BIND
-#undef ADD_TEXT
-#undef ADD_LINE
-
-} // End of namespace Scumm
diff --git a/scumm/help.h b/scumm/help.h
deleted file mode 100644
index 9691c09594..0000000000
--- a/scumm/help.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCUMM_HELP_H
-#define SCUMM_HELP_H
-
-#include "common/str.h"
-
-namespace Scumm {
-
-#define HELP_NUM_LINES 15
-
-class ScummHelp {
-protected:
- typedef Common::String String;
-
-public:
- static int numPages(byte gameId);
- static void updateStrings(byte gameId, byte version, Common::Platform platform,
- int page, String &title, String *&key, String *&dsc);
-};
-
-} // End of namespace Scumm
-
-#endif
-
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
deleted file mode 100644
index 5d170e98b8..0000000000
--- a/scumm/imuse.cpp
+++ /dev/null
@@ -1,2043 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/version.h"
-
-#include "common/util.h"
-#include "common/system.h"
-
-#include "scumm/imuse.h"
-#include "scumm/imuse_internal.h"
-#include "scumm/instrument.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-#include "scumm/util.h"
-
-#include "sound/mididrv.h"
-
-
-namespace Scumm {
-
-////////////////////////////////////////
-//
-// IMuseInternal implementation
-//
-////////////////////////////////////////
-
-IMuseInternal::IMuseInternal() :
-_native_mt32(false),
-_enable_gs(false),
-_sc55(false),
-_midi_adlib(0),
-_midi_native(0),
-_base_sounds(0),
-_paused(false),
-_initialized(false),
-_tempoFactor(0),
-_player_limit(ARRAYSIZE(_players)),
-_recycle_players(false),
-_direct_passthrough(false),
-_queue_end(0),
-_queue_pos(0),
-_queue_sound(0),
-_queue_adding(0),
-_queue_marker(0),
-_queue_cleared(0),
-_master_volume(0),
-_music_volume(0),
-_trigger_count(0),
-_snm_trigger_index(0) {
- memset(_channel_volume,0,sizeof(_channel_volume));
- memset(_channel_volume_eff,0,sizeof(_channel_volume_eff));
- memset(_volchan_table,0,sizeof(_volchan_table));
-}
-
-byte *IMuseInternal::findStartOfSound(int sound) {
- byte *ptr = NULL;
- int32 size, pos;
-
- if (_base_sounds)
- ptr = _base_sounds[sound];
-
- if (ptr == NULL) {
- debug(1, "IMuseInternal::findStartOfSound(): Sound %d doesn't exist!", sound);
- return NULL;
- }
-
- // Check for old-style headers first, like 'RO'
- if (ptr[4] == 'R' && ptr[5] == 'O'&& ptr[6] != 'L')
- return ptr + 4;
- if (ptr[8] == 'S' && ptr[9] == 'O')
- return ptr + 8;
-
- ptr += 8;
- size = READ_BE_UINT32(ptr);
- ptr += 4;
-
- // Okay, we're looking for one of those things: either
- // an 'MThd' tag (for SMF), or a 'FORM' tag (for XMIDI).
- size = 48; // Arbitrary; we should find our tag within the first 48 bytes of the resource
- pos = 0;
- while (pos < size) {
- if (!memcmp(ptr + pos, "MThd", 4) || !memcmp(ptr + pos, "FORM", 4))
- return ptr + pos;
- ++pos; // We could probably iterate more intelligently
- }
-
- debug(3, "IMuseInternal::findStartOfSound(): Failed to align on sound %d!", sound);
- return 0;
-}
-
-bool IMuseInternal::isMT32(int sound) {
- byte *ptr = NULL;
- uint32 tag;
-
- if (_base_sounds)
- ptr = _base_sounds[sound];
-
- if (ptr == NULL)
- return false;
-
- tag = *(((uint32 *)ptr) + 1);
- switch (tag) {
- case MKID('ADL '):
- case MKID('ASFX'): // Special AD class for old Adlib sound effects
- case MKID('SPK '):
- return false;
-
- case MKID('AMI '):
- case MKID('ROL '):
- return true;
-
- case MKID('MAC '): // Occurs in the Mac version of FOA and MI2
- return true;
-
- case MKID('GMD '):
- case MKID('MIDI'): // Occurs in Sam & Max
- return false;
- }
-
- // Old style 'RO' has equivalent properties to 'ROL'
- if (ptr[4] == 'R' && ptr[5] == 'O')
- return true;
- // Euphony tracks show as 'SO' and have equivalent properties to 'ADL'
- if (ptr[8] == 'S' && ptr[9] == 'O')
- return false;
-
- error("Unknown music type: '%s'", tag2str(tag));
-
- return false;
-}
-
-bool IMuseInternal::isMIDI(int sound) {
- byte *ptr = NULL;
- uint32 tag;
-
- if (_base_sounds)
- ptr = _base_sounds[sound];
-
- if (ptr == NULL)
- return false;
-
- tag = *(((uint32 *)ptr) + 1);
- switch (tag) {
- case MKID('ADL '):
- case MKID('ASFX'): // Special AD class for old Adlib sound effects
- case MKID('SPK '):
- return false;
-
- case MKID('AMI '):
- case MKID('ROL '):
- return true;
-
- case MKID('MAC '): // Occurs in the Mac version of FOA and MI2
- return true;
-
- case MKID('GMD '):
- case MKID('MIDI'): // Occurs in Sam & Max
- return true;
- }
-
- // Old style 'RO' has equivalent properties to 'ROL'
- if (ptr[4] == 'R' && ptr[5] == 'O')
- return true;
- // Euphony tracks show as 'SO' and have equivalent properties to 'ADL'
- // FIXME: Right now we're pretending it's GM.
- if (ptr[8] == 'S' && ptr[9] == 'O')
- return true;
-
- error("Unknown music type: '%s'", tag2str(tag));
-
- return false;
-}
-
-MidiDriver *IMuseInternal::getBestMidiDriver(int sound) {
- MidiDriver *driver = NULL;
-
- if (isMIDI(sound)) {
- if (_midi_native) {
- driver = _midi_native;
- } else {
- // Route it through Adlib anyway.
- driver = _midi_adlib;
- }
- } else {
- driver = _midi_adlib;
- }
- return driver;
-}
-
-bool IMuseInternal::startSound(int sound) {
- Player *player;
- void *ptr;
-
- // Do not start a sound if it is already set to start on an ImTrigger
- // event. This fixes carnival music problems where a sound has been set
- // to trigger at the right time, but then is started up immediately
- // anyway, only to be restarted later when the trigger occurs.
- //
- // However, we have to make sure the sound with the trigger is actually
- // playing, otherwise the music may stop when Sam and Max are thrown
- // out of Bumpusville, because entering the mansion sets up a trigger
- // for a sound that isn't necessarily playing. This is somewhat related
- // to bug #780918.
-
- int i;
- ImTrigger *trigger = _snm_triggers;
- for (i = ARRAYSIZE(_snm_triggers); i; --i, ++trigger) {
- if (trigger->sound && trigger->id && trigger->command[0] == 8 && trigger->command[1] == sound && getSoundStatus(trigger->sound))
- return false;
- }
-
- ptr = findStartOfSound(sound);
- if (!ptr) {
- debug(2, "IMuseInternal::startSound(): Couldn't find sound %d!", sound);
- return false;
- }
-
- // Check which MIDI driver this track should use.
- // If it's NULL, it ain't something we can play.
- MidiDriver *driver = getBestMidiDriver(sound);
- if (!driver)
- return false;
-
- // If the requested sound is already playing, start it over
- // from scratch. This was originally a hack to prevent Sam & Max
- // iMuse messiness while upgrading the iMuse engine, but it
- // is apparently necessary to deal with fade-and-restart
- // race conditions that were observed in MI2. Reference
- // Bug #590511 and Patch #607175 (which was reversed to fix
- // an FOA regression: Bug #622606).
- player = findActivePlayer(sound);
- if (!player)
- player = allocate_player(128);
- if (!player)
- return false;
-
- // HACK: This is to work around a problem at the Dino Bungie Memorial.
- // There are three pieces of music involved here:
- //
- // 80 - Main theme (looping)
- // 81 - Music when entering Rex's and Wally's room (not looping)
- // 82 - Music when listening to Rex or Wally
- //
- // When entering, tune 81 starts, tune 80 is faded down (not out) and
- // a trigger is set in tune 81 to fade tune 80 back up.
- //
- // When listening to Rex or Wally, tune 82 is started, tune 81 is faded
- // out and tune 80 is faded down even further.
- //
- // However, when tune 81 is faded out its trigger will cause tune 80 to
- // fade back up, resulting in two tunes being played simultaneously at
- // full blast. It's no use trying to keep tune 81 playing at volume 0.
- // It doesn't loop, so eventually it will terminate on its own.
- //
- // I don't know how the original interpreter handled this - or even if
- // it handled it at all - but it looks like sloppy scripting to me. Our
- // workaround is to clear the trigger if the player listens to Rex or
- // Wally before tune 81 has finished on its own.
-
- if (g_scumm->_gameId == GID_SAMNMAX && sound == 82 && getSoundStatus(81, false))
- ImClearTrigger(81, 1);
-
- player->clear();
- return player->startSound(sound, driver, _direct_passthrough);
-}
-
-
-Player *IMuseInternal::allocate_player(byte priority) {
- Player *player = _players, *best = NULL;
- int i;
- byte bestpri = 255;
-
- for (i = _player_limit; i != 0; i--, player++) {
- if (!player->isActive())
- return player;
- if (player->getPriority() < bestpri) {
- best = player;
- bestpri = player->getPriority();
- }
- }
-
- if (bestpri < priority || _recycle_players)
- return best;
-
- debug(1, "Denying player request");
- return NULL;
-}
-
-void IMuseInternal::init_players() {
- Player *player = _players;
- int i;
-
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- player->_se = this;
- player->clear(); // Used to just set _active to false
- }
-}
-
-void IMuseInternal::init_parts() {
- Part *part;
- int i;
-
- for (i = 0, part = _parts; i != ARRAYSIZE(_parts); i++, part++) {
- part->init();
- part->_se = this;
- part->_slot = i;
- }
-}
-
-int IMuseInternal::stopSound(int sound) {
- int r = -1;
- Player *player = findActivePlayer(sound);
- if (player) {
- player->clear();
- r = 0;
- }
- return r;
-}
-
-int IMuseInternal::stopAllSounds() {
- Player *player = _players;
- int i;
-
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- if (player->isActive())
- player->clear();
- }
- return 0;
-}
-
-void IMuseInternal::on_timer(MidiDriver *midi) {
- if (_paused || !_initialized)
- return;
-
- if (midi == _midi_native || !_midi_native)
- handleDeferredCommands(midi);
- sequencer_timers(midi);
-}
-
-int IMuseInternal::getMusicTimer() const {
- int best_time = 0;
- const Player *player = _players;
- int i;
-
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- if (player->isActive()) {
- int timer = player->getMusicTimer();
- if (timer > best_time)
- best_time = timer;
- }
- }
- return best_time;
-}
-
-void IMuseInternal::sequencer_timers(MidiDriver *midi) {
- Player *player = _players;
- int i;
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- if (player->isActive() && player->getMidiDriver() == midi) {
- player->onTimer();
- }
- }
-}
-
-void IMuseInternal::handle_marker(uint id, byte data) {
- uint16 *p = 0;
- uint pos;
-
- if (_queue_adding && _queue_sound == id && data == _queue_marker)
- return;
-
- // Fix for bug #733401, revised for bug #761637:
- // It would seem that sometimes a marker is in the queue
- // but not at the head position. In the case of our bug,
- // this seems to be the result of commands in the queue
- // for songs that are no longer playing. So we skip
- // ahead to the appropriate marker, effectively chomping
- // anything in the queue before it. This fixes the FOA
- // end credits music, but needs to be tested for inappopriate
- // behavior elsewhere.
- pos = _queue_end;
- while (pos != _queue_pos) {
- p = _cmd_queue[pos].array;
- if (p[0] == TRIGGER_ID && p[1] == id && p[2] == data)
- break;
- pos = (pos + 1) % ARRAYSIZE(_cmd_queue);
- }
-
- if (pos == _queue_pos)
- return;
-
- if (pos != _queue_end)
- debug(0, "Skipping entries in iMuse command queue to reach marker");
-
- _trigger_count--;
- _queue_cleared = false;
- do {
- pos = (pos + 1) % ARRAYSIZE(_cmd_queue);
- if (_queue_pos == pos)
- break;
- p = _cmd_queue[pos].array;
- if (*p++ != COMMAND_ID)
- break;
- _queue_end = pos;
-
- doCommand(p[0], p[1], p[2], p[3], p[4], p[5], p[6], 0);
-
- if (_queue_cleared)
- return;
- pos = _queue_end;
- } while (1);
-
- _queue_end = pos;
-}
-
-int IMuseInternal::get_channel_volume(uint a) {
- if (a < 8)
- return _channel_volume_eff[a];
- return (_master_volume * _music_volume / 255) / 2;
-}
-
-Part *IMuseInternal::allocate_part(byte pri, MidiDriver *midi) {
- Part *part, *best = NULL;
- int i;
-
- for (i = ARRAYSIZE(_parts), part = _parts; i != 0; i--, part++) {
- if (!part->_player)
- return part;
- if (pri >= part->_pri_eff) {
- pri = part->_pri_eff;
- best = part;
- }
- }
-
- if (best) {
- best->uninit();
- reallocateMidiChannels(midi);
- } else {
- debug(1, "Denying part request");
- }
- return best;
-}
-
-int IMuseInternal::getSoundStatus(int sound, bool ignoreFadeouts) const {
- int i;
- const Player *player = _players;
-
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- if (player->isActive() && (!ignoreFadeouts || !player->isFadingOut())) {
- if (sound == -1)
- return player->getID();
- else if (player->getID() == (uint16)sound)
- return 1;
- }
- }
- return (sound == -1) ? 0 : get_queue_sound_status(sound);
-}
-
-int IMuseInternal::get_queue_sound_status(int sound) const {
- const uint16 *a;
- int i, j;
-
- j = _queue_pos;
- i = _queue_end;
-
- while (i != j) {
- a = _cmd_queue[i].array;
- if (a[0] == COMMAND_ID && a[1] == 8 && a[2] == (uint16)sound)
- return 2;
- i = (i + 1) % ARRAYSIZE(_cmd_queue);
- }
-
- for (i = 0; i < ARRAYSIZE (_deferredCommands); ++i) {
- if (_deferredCommands[i].time_left && _deferredCommands[i].a == 8 &&
- _deferredCommands[i].b == sound) {
- return 2;
- }
- }
-
- return 0;
-}
-
-int IMuseInternal::set_volchan(int sound, int volchan) {
- int r;
- int i;
- int num;
- Player *player, *best, *sameid;
-
- r = get_volchan_entry(volchan);
- if (r == -1)
- return -1;
-
- if (r >= 8) {
- player = findActivePlayer(sound);
- if (player && player->_vol_chan != (uint16)volchan) {
- player->_vol_chan = volchan;
- player->setVolume(player->getVolume());
- return 0;
- }
- return -1;
- } else {
- best = NULL;
- num = 0;
- sameid = NULL;
- for (i = ARRAYSIZE(_players), player = _players; i != 0; i--, player++) {
- if (player->isActive()) {
- if (player->_vol_chan == (uint16)volchan) {
- num++;
- if (!best || player->getPriority() <= best->getPriority())
- best = player;
- } else if (player->getID() == (uint16)sound) {
- sameid = player;
- }
- }
- }
- if (sameid == NULL)
- return -1;
- if (num >= r)
- best->clear();
- player->_vol_chan = volchan;
- player->setVolume(player->getVolume());
- return 0;
- }
-}
-
-int IMuseInternal::clear_queue() {
- _queue_adding = false;
- _queue_cleared = true;
- _queue_pos = 0;
- _queue_end = 0;
- _trigger_count = 0;
- return 0;
-}
-
-int IMuseInternal::enqueue_command(int a, int b, int c, int d, int e, int f, int g) {
- uint16 *p;
- uint i;
-
- i = _queue_pos;
-
- if (i == _queue_end)
- return -1;
-
- if (a == -1) {
- _queue_adding = false;
- _trigger_count++;
- return 0;
- }
-
- p = _cmd_queue[_queue_pos].array;
- p[0] = COMMAND_ID;
- p[1] = a;
- p[2] = b;
- p[3] = c;
- p[4] = d;
- p[5] = e;
- p[6] = f;
- p[7] = g;
-
- i = (i + 1) % ARRAYSIZE(_cmd_queue);
-
- if (_queue_end != i) {
- _queue_pos = i;
- return 0;
- } else {
- _queue_pos = (i - 1) % ARRAYSIZE(_cmd_queue);
- return -1;
- }
-}
-
-int IMuseInternal::query_queue(int param) {
- switch (param) {
- case 0: // Get trigger count
- return _trigger_count;
- case 1: // Get trigger type
- if (_queue_end == _queue_pos)
- return -1;
- return _cmd_queue[_queue_end].array[1];
- case 2: // Get trigger sound
- if (_queue_end == _queue_pos)
- return 0xFF;
- return _cmd_queue[_queue_end].array[2];
- default:
- return -1;
- }
-}
-
-int IMuseInternal::setMusicVolume(uint vol) {
- if (vol > 255)
- vol = 255;
- if (_music_volume == vol)
- return 0;
- _music_volume = vol;
- vol = _master_volume * _music_volume / 255;
- for (uint i = 0; i < ARRAYSIZE(_channel_volume); i++) {
- _channel_volume_eff[i] = _channel_volume[i] * vol / 255;
- }
- if (!_paused)
- update_volumes();
- return 0;
-}
-
-int IMuseInternal::setImuseMasterVolume(uint vol) {
- if (vol > 255)
- vol = 255;
- if (_master_volume == vol)
- return 0;
- _master_volume = vol;
- vol = _master_volume * _music_volume / 255;
- for (uint i = 0; i < ARRAYSIZE(_channel_volume); i++) {
- _channel_volume_eff[i] = _channel_volume[i] * vol / 255;
- }
- if (!_paused)
- update_volumes();
- return 0;
-}
-
-int IMuseInternal::terminate1() {
- _initialized = false;
- stopAllSounds();
- return 0;
-}
-
-// This is the stuff that has to be done
-// outside the monitor's mutex, otherwise
-// a deadlock occurs.
-int IMuseInternal::terminate2() {
- if (_midi_adlib) {
- _midi_adlib->close();
- delete _midi_adlib;
- _midi_adlib = 0;
- }
-
- if (_midi_native) {
- _midi_native->close();
- delete _midi_native;
- _midi_native = 0;
- }
-
- return 0;
-}
-
-int IMuseInternal::enqueue_trigger(int sound, int marker) {
- uint16 *p;
- uint pos;
-
- pos = _queue_pos;
-
- p = _cmd_queue[pos].array;
- p[0] = TRIGGER_ID;
- p[1] = sound;
- p[2] = marker;
-
- pos = (pos + 1) % ARRAYSIZE(_cmd_queue);
- if (_queue_end == pos) {
- _queue_pos = (pos - 1) % ARRAYSIZE(_cmd_queue);
- return -1;
- }
-
- _queue_pos = pos;
- _queue_adding = true;
- _queue_sound = sound;
- _queue_marker = marker;
- return 0;
-}
-
-int32 IMuseInternal::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) {
- int args[8];
- args[0] = a;
- args[1] = b;
- args[2] = c;
- args[3] = d;
- args[4] = e;
- args[5] = f;
- args[6] = g;
- args[7] = h;
- return doCommand(8, args);
-}
-
-int32 IMuseInternal::doCommand(int numargs, int a[]) {
- int i;
-
- if (numargs < 1)
- return -1;
- byte cmd = a[0] & 0xFF;
- byte param = a[0] >> 8;
- Player *player = NULL;
-
- if (!_initialized && (cmd || param))
- return -1;
-
-#ifdef IMUSE_DEBUG
- {
- char string[128];
- sprintf(string, "doCommand - %d (%d/%d)", a[0], (int)param, (int)cmd);
- for (i = 1; i < numargs; ++i)
- sprintf(string + strlen(string), ", %d", a[i]);
- debug(0, string);
- }
-#endif
-
- if (param == 0) {
- switch (cmd) {
- case 6:
- if (a[1] > 127)
- return -1;
- else {
- debug(0, "IMuse doCommand(6) - setImuseMasterVolume (%d)", a[1]);
- return setImuseMasterVolume((a[1] << 1) | (a[1] ? 0 : 1)); // Convert from 0-127 to 0-255
- }
- case 7:
- debug(0, "IMuse doCommand(7) - getMasterVolume (%d)", a[1]);
- return _master_volume / 2; // Convert from 0-255 to 0-127
- case 8:
- return startSound(a[1]) ? 0 : -1;
- case 9:
- return stopSound(a[1]);
- case 10: // FIXME: Sam and Max - Not sure if this is correct
- return stopAllSounds();
- case 11:
- return stopAllSounds();
- case 12:
- // Sam & Max: Player-scope commands
- player = findActivePlayer(a[1]);
- if (!player)
- return -1;
-
- switch (a[3]) {
- case 6:
- // Set player volume.
- return player->setVolume(a[4]);
- default:
- error("IMuseInternal::doCommand(12) unsupported sub-command %d", a[3]);
- }
- return -1;
- case 13:
- return getSoundStatus(a[1]);
- case 14:
- // Sam and Max: Parameter fade
- player = findActivePlayer(a[1]);
- if (player)
- return player->addParameterFader(a[3], a[4], a[5]);
- return -1;
-
- case 15:
- // Sam & Max: Set hook for a "maybe" jump
- player = findActivePlayer(a[1]);
- if (player) {
- player->setHook(0, a[3], 0);
- return 0;
- }
- return -1;
- case 16:
- debug(0, "IMuse doCommand(16) - set_volchan (%d, %d)", a[1], a[2]);
- return set_volchan(a[1], a[2]);
- case 17:
- if (g_scumm->_gameId != GID_SAMNMAX) {
- debug(0, "IMuse doCommand(17) - set_channel_volume (%d, %d)", a[1], a[2]);
- return set_channel_volume(a[1], a[2]);
- } else {
- if (a[4]) {
- int b[16];
- memset(b, 0, sizeof(b));
- for (i = 0; i < numargs; ++i)
- b[i] = a[i];
- return ImSetTrigger(b[1], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11]);
- } else {
- return ImClearTrigger(a[1], a[3]);
- }
- }
- case 18:
- if (g_scumm->_gameId != GID_SAMNMAX) {
- return set_volchan_entry(a[1], a[2]);
- } else {
- // Sam & Max: ImCheckTrigger.
- // According to Mike's notes to Ender,
- // this function returns the number of triggers
- // associated with a particular player ID and
- // trigger ID.
- a[0] = 0;
- for (i = 0; i < ARRAYSIZE(_snm_triggers); ++i) {
- if (_snm_triggers[i].sound == a[1] && _snm_triggers[i].id &&
- (a[3] == -1 || _snm_triggers[i].id == a[3]))
- {
- ++a[0];
- }
- }
- return a[0];
- }
- case 19:
- // Sam & Max: ImClearTrigger
- // This should clear a trigger that's been set up
- // with ImSetTrigger(cmd == 17). Seems to work....
- return ImClearTrigger(a[1], a[3]);
- case 20:
- // Sam & Max: Deferred Command
- addDeferredCommand(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
- return 0;
- case 2:
- case 3:
- return 0;
- default:
- error("doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d) unsupported", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
- }
- } else if (param == 1) {
- if ((1 << cmd) & 0x783FFF) {
- player = findActivePlayer(a[1]);
- if (!player)
- return -1;
- if ((1 << cmd) & (1 << 11 | 1 << 22)) {
- assert(a[2] >= 0 && a[2] <= 15);
- player = (Player *)player->getPart(a[2]);
- if (!player)
- return -1;
- }
- }
-
- switch (cmd) {
- case 0:
- if (g_scumm->_gameId == GID_SAMNMAX) {
- if (a[3] == 1) // Measure number
- return ((player->getBeatIndex() - 1) >> 2) + 1;
- else if (a[3] == 2) // Beat number
- return player->getBeatIndex();
- return -1;
- } else {
- return player->getParam(a[2], a[3]);
- }
- case 1:
- if (g_scumm->_gameId == GID_SAMNMAX) {
- // FIXME: Could someone verify this?
- //
- // This jump instruction is known to be used in
- // the following cases:
- //
- // 1) Going anywhere on the USA map
- // 2) Winning the Wak-A-Rat game
- // 3) Losing or quitting the Wak-A-Rat game
- // 4) Conroy hitting Max with a golf club
- //
- // For all these cases the position parameters
- // are always the same: 2, 1, 0, 0.
- //
- // 5) When leaving the bigfoot party. The
- // position parameters are: 3, 4, 300, 0
- // 6) At Frog Rock, when the UFO appears. The
- // position parameters are: 10, 4, 400, 1
- //
- // The last two cases used to be buggy, so I
- // have made a change to how the last two
- // position parameters are handled. I still do
- // not know if it's correct, but it sounds
- // good to me at least.
-
- debug(0, "doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d)", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
- player->jump(a[3] - 1, (a[4] - 1) * 4 + a[5], a[6] + ((a[7] * player->getTicksPerBeat()) >> 2));
- } else
- player->setPriority(a[2]);
- return 0;
- case 2:
- return player->setVolume(a[2]);
- case 3:
- player->setPan(a[2]);
- return 0;
- case 4:
- return player->setTranspose(a[2], a[3]);
- case 5:
- player->setDetune(a[2]);
- return 0;
- case 6:
- player->setSpeed(a[2]);
- return 0;
- case 7:
- return player->jump(a[2], a[3], a[4]) ? 0 : -1;
- case 8:
- return player->scan(a[2], a[3], a[4]);
- case 9:
- return player->setLoop(a[2], a[3], a[4], a[5], a[6]) ? 0 : -1;
- case 10:
- player->clearLoop();
- return 0;
- case 11:
- ((Part *)player)->set_onoff(a[3] != 0);
- return 0;
- case 12:
- return player->setHook(a[2], a[3], a[4]);
- case 13:
- return player->addParameterFader(ParameterFader::pfVolume, a[2], a[3]);
- case 14:
- return enqueue_trigger(a[1], a[2]);
- case 15:
- return enqueue_command(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
- case 16:
- return clear_queue();
- case 19:
- return player->getParam(a[2], a[3]);
- case 20:
- return player->setHook(a[2], a[3], a[4]);
- case 21:
- return -1;
- case 22:
- ((Part *)player)->volume(a[3]);
- return 0;
- case 23:
- return query_queue(a[1]);
- case 24:
- return 0;
- default:
- error("doCommand(%d [%d/%d], %d, %d, %d, %d, %d, %d, %d) unsupported", a[0], param, cmd, a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
- return -1;
- }
- }
-
- return -1;
-}
-
-int32 IMuseInternal::ImSetTrigger(int sound, int id, int a, int b, int c, int d, int e, int f, int g, int h) {
- // Sam & Max: ImSetTrigger.
- // Sets a trigger for a particular player and
- // marker ID, along with doCommand parameters
- // to invoke at the marker. The marker is
- // represented by MIDI SysEx block 00 xx(F7)
- // where "xx" is the marker ID.
- uint16 oldest_trigger = 0;
- ImTrigger *oldest_ptr = NULL;
-
- int i;
- ImTrigger *trig = _snm_triggers;
- for (i = ARRAYSIZE(_snm_triggers); i; --i, ++trig) {
- if (!trig->id)
- break;
- // We used to only compare 'id' and 'sound' here, but at least
- // at the Dino Bungie Memorial that causes the music to stop
- // after getting the T-Rex tooth. See bug #888161.
- if (trig->id == id && trig->sound == sound && trig->command[0] == a)
- break;
-
- uint16 diff;
- if (trig->expire <= _snm_trigger_index)
- diff = _snm_trigger_index - trig->expire;
- else
- diff = 0x10000 - trig->expire + _snm_trigger_index;
-
- if (!oldest_ptr || oldest_trigger < diff) {
- oldest_ptr = trig;
- oldest_trigger = diff;
- }
- }
-
- // If we didn't find a trigger, see if we can expire one.
- if (!i) {
- if (!oldest_ptr)
- return -1;
- trig = oldest_ptr;
- }
-
- trig->id = id;
- trig->sound = sound;
- trig->expire = (++_snm_trigger_index & 0xFFFF);
- trig->command[0] = a;
- trig->command[1] = b;
- trig->command[2] = c;
- trig->command[3] = d;
- trig->command[4] = e;
- trig->command[5] = f;
- trig->command[6] = g;
- trig->command[7] = h;
-
- // If the command is to start a sound, stop that sound if it's already playing.
- // This fixes some carnival music problems.
- // NOTE: We ONLY do this if the sound that will trigger the command is actually
- // playing. Otherwise, there's a problem when exiting and re-entering the
- // Bumpusville mansion. Ref Bug #780918.
- if (trig->command[0] == 8 && getSoundStatus(trig->command[1]) && getSoundStatus(sound))
- stopSound(trig->command[1]);
- return 0;
-}
-
-int32 IMuseInternal::ImClearTrigger(int sound, int id) {
- int count = 0;
- int i;
- ImTrigger *trig = _snm_triggers;
- for (i = ARRAYSIZE(_snm_triggers); i; --i, ++trig) {
- if ((sound == -1 || trig->sound == sound) && trig->id && (id == -1 || trig->id == id)) {
- trig->sound = trig->id = 0;
- ++count;
- }
- }
- return (count > 0) ? 0 : -1;
-}
-
-int32 IMuseInternal::ImFireAllTriggers(int sound) {
- if (!sound)
- return 0;
- int count = 0;
- int i;
- for (i = 0; i < ARRAYSIZE(_snm_triggers); ++i) {
- if (_snm_triggers[i].sound == sound) {
- _snm_triggers[i].sound = _snm_triggers[i].id = 0;
- doCommand(8, _snm_triggers[i].command);
- ++count;
- }
- }
- return (count > 0) ? 0 : -1;
-}
-
-int IMuseInternal::set_channel_volume(uint chan, uint vol)
-{
- if (chan >= 8 || vol > 127)
- return -1;
-
- _channel_volume[chan] = vol;
- _channel_volume_eff[chan] = _master_volume * _music_volume * vol / 255 / 255;
- update_volumes();
- return 0;
-}
-
-void IMuseInternal::update_volumes() {
- Player *player;
- int i;
-
- for (i = ARRAYSIZE(_players), player = _players; i != 0; i--, player++) {
- if (player->isActive())
- player->setVolume(player->getVolume());
- }
-}
-
-int IMuseInternal::set_volchan_entry(uint a, uint b) {
- if (a >= 8)
- return -1;
- _volchan_table[a] = b;
- return 0;
-}
-
-int HookDatas::query_param(int param, byte chan) {
- switch (param) {
- case 18:
- return _jump[0];
- case 19:
- return _transpose;
- case 20:
- return _part_onoff[chan];
- case 21:
- return _part_volume[chan];
- case 22:
- return _part_program[chan];
- case 23:
- return _part_transpose[chan];
- default:
- return -1;
- }
-}
-
-int HookDatas::set(byte cls, byte value, byte chan) {
- switch (cls) {
- case 0:
- if (value != _jump[0]) {
- _jump[1] = _jump[0];
- _jump[0] = value;
- }
- break;
- case 1:
- _transpose = value;
- break;
- case 2:
- if (chan < 16)
- _part_onoff[chan] = value;
- else if (chan == 16)
- memset(_part_onoff, value, 16);
- break;
- case 3:
- if (chan < 16)
- _part_volume[chan] = value;
- else if (chan == 16)
- memset(_part_volume, value, 16);
- break;
- case 4:
- if (chan < 16)
- _part_program[chan] = value;
- else if (chan == 16)
- memset(_part_program, value, 16);
- break;
- case 5:
- if (chan < 16)
- _part_transpose[chan] = value;
- else if (chan == 16)
- memset(_part_transpose, value, 16);
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-Player *IMuseInternal::findActivePlayer(int id) {
- int i;
- Player *player = _players;
-
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- if (player->isActive() && player->getID() == (uint16)id)
- return player;
- }
- return NULL;
-}
-
-int IMuseInternal::get_volchan_entry(uint a) {
- if (a < 8)
- return _volchan_table[a];
- return -1;
-}
-
-uint32 IMuseInternal::property(int prop, uint32 value) {
- switch (prop) {
- case IMuse::PROP_TEMPO_BASE:
- // This is a specified as a percentage of normal
- // music speed. The number must be an integer
- // ranging from 50 to 200(for 50% to 200% normal speed).
- if (value >= 50 && value <= 200)
- _tempoFactor = value;
- break;
-
- case IMuse::PROP_NATIVE_MT32:
- _native_mt32 = (value > 0);
- Instrument::nativeMT32(_native_mt32);
- if (_midi_native && _native_mt32)
- initMT32(_midi_native);
- break;
-
- case IMuse::PROP_GS:
- _enable_gs = (value > 0);
-
- // If True Roland MT-32 is not selected, run in GM or GS mode.
- // If it is selected, change the Roland GS synth to MT-32 mode.
- if (_midi_native && !_native_mt32)
- initGM(_midi_native);
- else if (_midi_native && _native_mt32 && _enable_gs) {
- _sc55 = true;
- initGM(_midi_native);
- }
- break;
-
- case IMuse::PROP_LIMIT_PLAYERS:
- if (value > 0 && value <= ARRAYSIZE(_players))
- _player_limit = (int)value;
- break;
-
- case IMuse::PROP_RECYCLE_PLAYERS:
- _recycle_players = (value != 0);
- break;
-
- case IMuse::PROP_DIRECT_PASSTHROUGH:
- _direct_passthrough = (value != 0);
- break;
- }
-
- return 0;
-}
-
-void IMuseInternal::setBase(byte **base) {
- _base_sounds = base;
-}
-
-IMuseInternal *IMuseInternal::create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver) {
- IMuseInternal *i = new IMuseInternal;
- i->initialize(syst, nativeMidiDriver, adlibMidiDriver);
- return i;
-}
-
-int IMuseInternal::initialize(OSystem *syst, MidiDriver *native_midi, MidiDriver *adlib_midi) {
- int i;
-
- _midi_native = native_midi;
- _midi_adlib = adlib_midi;
- if (native_midi != NULL)
- initMidiDriver(native_midi);
- if (adlib_midi != NULL)
- initMidiDriver(adlib_midi);
-
- if (!_tempoFactor)
- _tempoFactor = 100;
- _master_volume = 255;
-
- for (i = 0; i != 8; i++)
- _channel_volume[i] = _channel_volume_eff[i] = _volchan_table[i] = 127;
-
- init_players();
- init_queue();
- init_parts();
-
- _initialized = true;
-
- return 0;
-}
-
-void IMuseInternal::initMidiDriver(MidiDriver *midi) {
- // Open MIDI driver
- int result = midi->open();
- if (result)
- error("IMuse initialization - %s", MidiDriver::getErrorName(result));
-
- // Connect to the driver's timer
- midi->setTimerCallback(midi, &IMuseInternal::midiTimerCallback);
-}
-
-void IMuseInternal::initMT32(MidiDriver *midi) {
- byte buffer[52];
- char info[256] = "ScummVM ";
- int len;
-
- // Reset the MT-32
- memcpy(&buffer[0], "\x41\x10\x16\x12\x7f\x00\x00\x01\x00", 9);
- midi->sysEx(buffer, 9);
- g_system->delayMillis(100);
-
- // Compute version string (truncated to 20 chars max.)
- strcat(info, gScummVMVersion);
- len = strlen(info);
- if (len > 20)
- len = 20;
-
- // Display a welcome message on MT-32 displays.
- memcpy(&buffer[4], "\x20\x00\x00", 3);
- memcpy(&buffer[7], " ", 20);
- memcpy(buffer + 7 +(20 - len) / 2, info, len);
- byte checksum = 0;
- for (int i = 4; i < 27; ++i)
- checksum -= buffer[i];
- buffer[27] = checksum & 0x7F;
- midi->sysEx(buffer, 28);
- g_system->delayMillis(500);
-
- // Setup master tune, reverb mode, reverb time, reverb level,
- // channel mapping, partial reserve and master volume
- memcpy(&buffer[4], "\x10\x00\x00\x40\x00\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x64\x77", 27);
- midi->sysEx(buffer, 31);
- g_system->delayMillis(250);
-
- // Map percussion to notes 24 - 34 without reverb
- memcpy(&buffer[4], "\x03\x01\x10\x40\x64\x07\x00\x4a\x64\x06\x00\x41\x64\x07\x00\x4b\x64\x08\x00\x45\x64\x06\x00\x44\x64\x0b\x00\x51\x64\x05\x00\x43\x64\x08\x00\x50\x64\x07\x00\x42\x64\x03\x00\x4c\x64\x07\x00\x44", 48);
- midi->sysEx(buffer, 52);
- g_system->delayMillis(250);
-}
-
-void IMuseInternal::initGM(MidiDriver *midi) {
- byte buffer[11];
- int i;
-
- // General MIDI System On message
- // Resets all GM devices to default settings
- memcpy(&buffer[0], "\xF0\x7E\x7F\x09\x01\xF7", 6);
- midi->sysEx(buffer, 6);
- debug(2, "GM SysEx: GM System On");
- g_system->delayMillis(200);
-
- if (_enable_gs) {
-
- // All GS devices recognize the GS Reset command,
- // even with Roland's ID. It is impractical to
- // support other manufacturers' devices for
- // further GS settings, as there are limitless
- // numbers of them out there that would each
- // require individual SysEx commands with unique IDs.
-
- // Roland GS SysEx ID
- memcpy(&buffer[0], "\xF0\x41\x10\x42\x12", 5);
-
- // GS Reset
- memcpy(&buffer[5], "\x40\x00\x7F\x00\x41\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: GS Reset");
- g_system->delayMillis(200);
-
- if (_sc55) {
- // This mode is for GS devices that support an MT-32-compatible
- // Map, such as the Roland Sound Canvas line of modules. It
- // will allow them to work with True MT-32 mode, but will
- // obviously still ignore MT-32 SysEx (and thus custom
- // instruments).
-
- // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation
- for (i = 0; i < 16; ++i) {
- midi->send(( 127 << 16) | (0 << 8) | (0xB0 | i));
- midi->send(( 1 << 16) | (32 << 8) | (0xB0 | i));
- midi->send(( 0 << 16) | (0 << 8) | (0xC0 | i));
- }
- debug(2, "GS Program Change: CM-64/32L Map Selected");
-
- // Set Percussion Channel to SC-55 Map (CC#32, 01H), then
- // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums)
- midi->getPercussionChannel()->controlChange(0, 0);
- midi->getPercussionChannel()->controlChange(32, 1);
- midi->send(127 << 8 | 0xC0 | 9);
- debug(2, "GS Program Change: Drum Map is CM-64/32L");
-
- }
-
- // Set Master Chorus to 0. The MT-32 has no chorus capability.
- memcpy(&buffer[5], "\x40\x01\x3A\x00\x05\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: Master Chorus Level is 0");
-
- // Set Channels 1-16 Reverb to 64, which is the
- // equivalent of MT-32 default Reverb Level 5
- for (i = 0; i < 16; ++i)
- midi->send(( 64 << 16) | (91 << 8) | (0xB0 | i));
- debug(2, "GM Controller 91 Change: Channels 1-16 Reverb Level is 64");
-
- // Set Channels 1-16 Pitch Bend Sensitivity to
- // 12 semitones; then lock the RPN by setting null.
- for (i = 0; i < 16; ++i) {
- midi->send(( 0 << 16) | (100 << 8) | (0xB0 | i));
- midi->send(( 0 << 16) | (101 << 8) | (0xB0 | i));
- midi->send(( 12 << 16) | (6 << 8) | (0xB0 | i));
- midi->send(( 0 << 16) | (38 << 8) | (0xB0 | i));
- midi->send(( 127 << 16) | (100 << 8) | (0xB0 | i));
- midi->send(( 127 << 16) | (101 << 8) | (0xB0 | i));
- }
- debug(2, "GM Controller 6 Change: Channels 1-16 Pitch Bend Sensitivity is 12 semitones");
-
- // Set channels 1-16 Mod. LFO1 Pitch Depth to 4
- memcpy(&buffer[5], "\x40\x20\x04\x04\x18\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x21\x04\x04\x17\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x22\x04\x04\x16\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x23\x04\x04\x15\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x24\x04\x04\x14\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x25\x04\x04\x13\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x26\x04\x04\x12\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x27\x04\x04\x11\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x28\x04\x04\x10\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x29\x04\x04\x0F\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x2A\x04\x04\x0E\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x2B\x04\x04\x0D\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x2C\x04\x04\x0C\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x2D\x04\x04\x0B\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x2E\x04\x04\x0A\xF7", 6);
- midi->sysEx(buffer, 11);
- memcpy(&buffer[5], "\x40\x2F\x04\x04\x09\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: Channels 1-16 Mod. LFO1 Pitch Depth Level is 4");
-
- // Set Percussion Channel Expression to 80
- midi->getPercussionChannel()->controlChange(11, 80);
- debug(2, "GM Controller 11 Change: Percussion Channel Expression Level is 80");
-
- // Turn off Percussion Channel Rx. Expression so that
- // Expression cannot be modified. I don't know why, but
- // Roland does it this way.
- memcpy(&buffer[5], "\x40\x10\x0E\x00\x22\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: Percussion Channel Rx. Expression is OFF");
-
- // Change Reverb Character to 0. I don't think this
- // sounds most like MT-32, but apparently Roland does.
- memcpy(&buffer[5], "\x40\x01\x31\x00\x0E\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: Reverb Character is 0");
-
- // Change Reverb Pre-LF to 4, which is similar to
- // what MT-32 reverb does.
- memcpy(&buffer[5], "\x40\x01\x32\x04\x09\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: Reverb Pre-LF is 4");
-
- // Change Reverb Time to 106; the decay on Hall 2
- // Reverb is too fast compared to the MT-32's
- memcpy(&buffer[5], "\x40\x01\x34\x6A\x21\xF7", 6);
- midi->sysEx(buffer, 11);
- debug(2, "GS SysEx: Reverb Time is 106");
- }
-}
-
-void IMuseInternal::init_queue() {
- _queue_adding = false;
- _queue_pos = 0;
- _queue_end = 0;
- _trigger_count = 0;
-}
-
-void IMuseInternal::pause(bool paused) {
- if (_paused == paused)
- return;
- int vol = _music_volume;
- if (paused)
- _music_volume = 0;
- update_volumes();
- _music_volume = vol;
-
- // Fix for Bug #817871. The MT-32 apparently fails
- // sometimes to respond to a channel volume message
- // (or only uses it for subsequent note events).
- // The result is hanging notes on pause. Reportedly
- // happens in the original distro, too. To fix that,
- // just send AllNotesOff to the channels.
- if (_midi_native && _native_mt32) {
- for (int i = 0; i < 16; ++i)
- _midi_native->send(123 << 8 | 0xB0 | i);
- }
-
- _paused = paused;
-}
-
-void IMuseInternal::handleDeferredCommands(MidiDriver *midi) {
- uint32 advance = midi->getBaseTempo();
-
- DeferredCommand *ptr = &_deferredCommands[0];
- int i;
- for (i = ARRAYSIZE(_deferredCommands); i; --i, ++ptr) {
- if (!ptr->time_left)
- continue;
- if (ptr->time_left <= advance) {
- doCommand(ptr->a, ptr->b, ptr->c, ptr->d, ptr->e, ptr->f, 0, 0);
- ptr->time_left = advance;
- }
- ptr->time_left -= advance;
- }
-}
-
-// "time" is interpreted as hundredths of a second.
-// FIXME: Is that correct?
-// We convert it to microseconds before prceeding
-void IMuseInternal::addDeferredCommand(int time, int a, int b, int c, int d, int e, int f) {
- DeferredCommand *ptr = &_deferredCommands[0];
- int i;
- for (i = ARRAYSIZE(_deferredCommands); i; --i, ++ptr) {
- if (!ptr->time_left)
- break;
- }
-
- if (i) {
- ptr->time_left = time * 10000;
- ptr->a = a;
- ptr->b = b;
- ptr->c = c;
- ptr->d = d;
- ptr->e = e;
- ptr->f = f;
- }
-}
-
-////////////////////////////////////////////////////////////
-//
-// IMuseInternal load/save implementation
-//
-////////////////////////////////////////////////////////////
-
-int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm) {
- const SaveLoadEntry mainEntries[] = {
- MKLINE(IMuseInternal, _queue_end, sleUint8, VER(8)),
- MKLINE(IMuseInternal, _queue_pos, sleUint8, VER(8)),
- MKLINE(IMuseInternal, _queue_sound, sleUint16, VER(8)),
- MKLINE(IMuseInternal, _queue_adding, sleByte, VER(8)),
- MKLINE(IMuseInternal, _queue_marker, sleByte, VER(8)),
- MKLINE(IMuseInternal, _queue_cleared, sleByte, VER(8)),
- MKLINE(IMuseInternal, _master_volume, sleByte, VER(8)),
- MKLINE(IMuseInternal, _trigger_count, sleUint16, VER(8)),
- MKLINE(IMuseInternal, _snm_trigger_index, sleUint16, VER(54)),
- MKARRAY(IMuseInternal, _channel_volume[0], sleUint16, 8, VER(8)),
- MKARRAY(IMuseInternal, _volchan_table[0], sleUint16, 8, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry cmdQueueEntries[] = {
- MKARRAY(CommandQueue, array[0], sleUint16, 8, VER(23)),
- MKEND()
- };
-
- // VolumeFader is obsolete.
- const SaveLoadEntry volumeFaderEntries[] = {
- MK_OBSOLETE(VolumeFader, player, sleUint16, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, active, sleUint8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, curvol, sleUint8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_lo_max, sleUint16, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, num_steps, sleUint16, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_hi, sleInt8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, direction, sleInt8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_lo, sleInt8, VER(8), VER(16)),
- MK_OBSOLETE(VolumeFader, speed_lo_counter, sleUint16, VER(8), VER(16)),
- MKEND()
- };
-
- const SaveLoadEntry snmTriggerEntries[] = {
- MKLINE(ImTrigger, sound, sleInt16, VER(54)),
- MKLINE(ImTrigger, id, sleByte, VER(54)),
- MKLINE(ImTrigger, expire, sleUint16, VER(54)),
- MKARRAY(ImTrigger, command[0], sleUint16, 8, VER(54)),
- MKEND()
- };
-
- int i;
-
- ser->saveLoadEntries(this, mainEntries);
- ser->saveLoadArrayOf(_cmd_queue, ARRAYSIZE(_cmd_queue), sizeof(_cmd_queue[0]), cmdQueueEntries);
- ser->saveLoadArrayOf(_snm_triggers, ARRAYSIZE(_snm_triggers), sizeof(_snm_triggers[0]), snmTriggerEntries);
-
- // The players
- for (i = 0; i < ARRAYSIZE(_players); ++i)
- _players[i].saveLoadWithSerializer(ser);
-
- // The parts
- for (i = 0; i < ARRAYSIZE(_parts); ++i)
- _parts[i].saveLoadWithSerializer(ser);
-
- { // Load/save the instrument definitions, which were revamped with V11.
- Part *part = &_parts[0];
- if (ser->getVersion() >= VER(11)) {
- for (i = ARRAYSIZE(_parts); i; --i, ++part) {
- part->_instrument.saveOrLoad(ser);
- }
- } else {
- for (i = ARRAYSIZE(_parts); i; --i, ++part)
- part->_instrument.clear();
- }
- }
-
- // VolumeFader has been replaced with the more generic ParameterFader.
- // FIXME: replace this loop by something like
- // if (loading && version <= 16) ser->skip(XXX bytes);
- for (i = 0; i < 8; ++i)
- ser->saveLoadEntries(0, volumeFaderEntries);
-
- if (ser->isLoading()) {
- // Load all sounds that we need
- fix_players_after_load(scumm);
- fix_parts_after_load();
- setImuseMasterVolume(_master_volume);
-
- if (_midi_native)
- reallocateMidiChannels(_midi_native);
- if (_midi_adlib)
- reallocateMidiChannels(_midi_adlib);
- }
-
- return 0;
-}
-
-void IMuseInternal::fix_parts_after_load() {
- Part *part;
- int i;
-
- for (i = ARRAYSIZE(_parts), part = _parts; i != 0; i--, part++) {
- if (part->_player)
- part->fix_after_load();
- }
-}
-
-// Only call this routine from the main thread,
-// since it uses getResourceAddress
-void IMuseInternal::fix_players_after_load(ScummEngine *scumm) {
- Player *player = _players;
- int i;
-
- for (i = ARRAYSIZE(_players); i != 0; i--, player++) {
- if (player->isActive()) {
- scumm->getResourceAddress(rtSound, player->getID());
- player->fixAfterLoad();
- }
- }
-}
-
-Part::Part() {
- _slot = 0;
- _next = 0;
- _prev = 0;
- _mc = 0;
- _player = 0;
- _pitchbend = 0;
- _pitchbend_factor = 0;
- _transpose = 0;
- _transpose_eff = 0;
- _vol = 0;
- _vol_eff = 0;
- _detune = 0;
- _detune_eff = 0;
- _pan = 0;
- _pan_eff = 0;
- _on = false;
- _modwheel = 0;
- _pedal = false;
- _pri = 0;
- _pri_eff = 0;
- _chan = 0;
- _effect_level = 0;
- _chorus = 0;
- _percussion = 0;
- _bank = 0;
- _unassigned_instrument = false;
-}
-
-void Part::saveLoadWithSerializer(Serializer *ser) {
- const SaveLoadEntry partEntries[] = {
- MKLINE(Part, _pitchbend, sleInt16, VER(8)),
- MKLINE(Part, _pitchbend_factor, sleUint8, VER(8)),
- MKLINE(Part, _transpose, sleInt8, VER(8)),
- MKLINE(Part, _vol, sleUint8, VER(8)),
- MKLINE(Part, _detune, sleInt8, VER(8)),
- MKLINE(Part, _pan, sleInt8, VER(8)),
- MKLINE(Part, _on, sleUint8, VER(8)),
- MKLINE(Part, _modwheel, sleUint8, VER(8)),
- MKLINE(Part, _pedal, sleUint8, VER(8)),
- MK_OBSOLETE(Part, _program, sleUint8, VER(8), VER(16)),
- MKLINE(Part, _pri, sleUint8, VER(8)),
- MKLINE(Part, _chan, sleUint8, VER(8)),
- MKLINE(Part, _effect_level, sleUint8, VER(8)),
- MKLINE(Part, _chorus, sleUint8, VER(8)),
- MKLINE(Part, _percussion, sleUint8, VER(8)),
- MKLINE(Part, _bank, sleUint8, VER(8)),
- MKEND()
- };
-
- int num;
- if (ser->isSaving()) {
- num = (_next ? (_next - _se->_parts + 1) : 0);
- ser->saveUint16(num);
-
- num = (_prev ? (_prev - _se->_parts + 1) : 0);
- ser->saveUint16(num);
-
- num = (_player ? (_player - _se->_players + 1) : 0);
- ser->saveUint16(num);
- } else {
- num = ser->loadUint16();
- _next = (num ? &_se->_parts[num - 1] : 0);
-
- num = ser->loadUint16();
- _prev = (num ? &_se->_parts[num - 1] : 0);
-
- num = ser->loadUint16();
- _player = (num ? &_se->_players[num - 1] : 0);
- }
- ser->saveLoadEntries(this, partEntries);
-}
-
-void Part::set_detune(int8 detune) {
- _detune_eff = clamp((_detune = detune) + _player->getDetune(), -128, 127);
- if (_mc)
- sendPitchBend();
-}
-
-void Part::pitchBend(int16 value) {
- _pitchbend = value;
- if (_mc)
- sendPitchBend();
-}
-
-void Part::volume(byte value) {
- _vol_eff = ((_vol = value) + 1) * _player->getEffectiveVolume() >> 7;
- if (_mc)
- _mc->volume(_vol_eff);
-}
-
-void Part::set_pri(int8 pri) {
- _pri_eff = clamp((_pri = pri) + _player->getPriority(), 0, 255);
- if (_mc)
- _mc->priority(_pri_eff);
-}
-
-void Part::set_pan(int8 pan) {
- _pan_eff = clamp((_pan = pan) + _player->getPan(), -64, 63);
- if (_mc)
- _mc->panPosition(_pan_eff + 0x40);
-}
-
-void Part::set_transpose(int8 transpose) {
- _transpose_eff = transpose_clamp((_transpose = transpose) + _player->getTranspose(), -24, 24);
- if (_mc)
- sendPitchBend();
-}
-
-void Part::sustain(bool value) {
- _pedal = value;
- if (_mc)
- _mc->sustain(value);
-}
-
-void Part::modulationWheel(byte value) {
- _modwheel = value;
- if (_mc)
- _mc->modulationWheel(value);
-}
-
-void Part::chorusLevel(byte value) {
- _chorus = value;
- if (_mc)
- _mc->chorusLevel(value);
-}
-
-void Part::effectLevel(byte value)
-{
- _effect_level = value;
- if (_mc)
- _mc->effectLevel(value);
-}
-
-void Part::fix_after_load() {
- set_transpose(_transpose);
- volume(_vol);
- set_detune(_detune);
- set_pri(_pri);
- set_pan(_pan);
- sendAll();
-}
-
-void Part::pitchBendFactor(byte value) {
- if (value > 12)
- return;
- pitchBend(0);
- _pitchbend_factor = value;
- if (_mc)
- _mc->pitchBendFactor(value);
-}
-
-void Part::set_onoff(bool on) {
- if (_on != on) {
- _on = on;
- if (!on)
- off();
- if (!_percussion)
- _player->_se->reallocateMidiChannels(_player->getMidiDriver());
- }
-}
-
-void Part::set_instrument(byte * data) {
- _instrument.adlib(data);
- if (clearToTransmit())
- _instrument.send(_mc);
-}
-
-void Part::load_global_instrument(byte slot) {
- _player->_se->copyGlobalAdlibInstrument(slot, &_instrument);
- if (clearToTransmit())
- _instrument.send(_mc);
-}
-
-void Part::noteOn(byte note, byte velocity) {
- if (!_on)
- return;
-
- MidiChannel *mc = _mc;
-
- // DEBUG
- if (_unassigned_instrument && !_percussion) {
- _unassigned_instrument = false;
- if (!_instrument.isValid()) {
- debug(0, "[%02d] No instrument specified", (int)_chan);
- return;
- }
- }
-
- if (mc && _instrument.isValid()) {
- mc->noteOn(note, velocity);
- } else if (_percussion) {
- mc = _player->getMidiDriver()->getPercussionChannel();
- if (!mc)
- return;
- static byte prev_vol_eff = 128;
- if (_vol_eff != prev_vol_eff){
- mc->volume(_vol_eff);
- prev_vol_eff = _vol_eff;
- }
- if ((note < 35) && (!_player->_se->isNativeMT32()))
- note = Instrument::_gmRhythmMap[note];
-
- mc->noteOn(note, velocity);
- }
-}
-
-void Part::noteOff(byte note) {
- if (!_on)
- return;
-
- MidiChannel *mc = _mc;
- if (mc) {
- mc->noteOff(note);
- } else if (_percussion) {
- mc = _player->getMidiDriver()->getPercussionChannel();
- if (mc)
- mc->noteOff(note);
- }
-}
-
-void Part::init() {
- _player = NULL;
- _next = NULL;
- _prev = NULL;
- _mc = NULL;
-}
-
-void Part::setup(Player *player) {
- _player = player;
-
- _percussion = (player->isMIDI() && _chan == 9); // true;
- _on = true;
- _pri_eff = player->getPriority();
- _pri = 0;
- _vol = 127;
- _vol_eff = player->getEffectiveVolume();
- _pan = clamp(player->getPan(), -64, 63);
- _transpose_eff = player->getTranspose();
- _transpose = 0;
- _detune = 0;
- _detune_eff = player->getDetune();
- _pitchbend_factor = 2;
- _pitchbend = 0;
- _effect_level = 64;
- _instrument.clear();
- _unassigned_instrument = true;
- _chorus = 0;
- _modwheel = 0;
- _bank = 0;
- _pedal = false;
- _mc = NULL;
-}
-
-void Part::uninit() {
- if (!_player)
- return;
- off();
- _player->removePart(this);
- _player = NULL;
-}
-
-void Part::off() {
- if (_mc) {
- _mc->allNotesOff();
- _mc->release();
- _mc = NULL;
- }
-}
-
-bool Part::clearToTransmit() {
- if (_mc)
- return true;
- if (_instrument.isValid())
- _player->_se->reallocateMidiChannels(_player->getMidiDriver());
- return false;
-}
-
-void Part::sendAll() {
- if (!clearToTransmit())
- return;
- _mc->pitchBendFactor(_pitchbend_factor);
- sendPitchBend();
- _mc->volume(_vol_eff);
- _mc->sustain(_pedal);
- _mc->modulationWheel(_modwheel);
- _mc->panPosition(_pan_eff + 0x40);
- _mc->effectLevel(_effect_level);
- if (_instrument.isValid())
- _instrument.send(_mc);
- _mc->chorusLevel(_chorus);
- _mc->priority(_pri_eff);
-}
-
-void Part::sendPitchBend() {
- int16 bend = _pitchbend;
- // RPN-based pitchbend range doesn't work for the MT32,
- // so we'll do the scaling ourselves.
- if (_player->_se->isNativeMT32())
- bend = bend * _pitchbend_factor / 12;
- _mc->pitchBend(clamp(bend + (_detune_eff * 64 / 12) + (_transpose_eff * 8192 / 12), -8192, 8191));
-}
-
-void Part::programChange(byte value) {
- _bank = 0;
- _instrument.program(value, _player->isMT32());
- if (clearToTransmit())
- _instrument.send(_mc);
-}
-
-void Part::set_instrument(uint b) {
- _bank = (byte)(b >> 8);
- if (_bank)
- error("Non-zero instrument bank selection. Please report this");
- _instrument.program((byte)b, _player->isMT32());
- if (clearToTransmit())
- _instrument.send(_mc);
-}
-
-void Part::allNotesOff() {
- if (!_mc)
- return;
- _mc->allNotesOff();
-}
-
-////////////////////////////////////////
-//
-// Some more IMuseInternal stuff
-//
-////////////////////////////////////////
-
-void IMuseInternal::midiTimerCallback(void *data) {
- MidiDriver *driver = (MidiDriver *)data;
- if (g_scumm->_imuse)
- g_scumm->_imuse->on_timer(driver);
-}
-
-void IMuseInternal::reallocateMidiChannels(MidiDriver *midi) {
- Part *part, *hipart;
- int i;
- byte hipri, lopri;
- Part *lopart;
-
- while (true) {
- hipri = 0;
- hipart = NULL;
- for (i = 32, part = _parts; i; i--, part++) {
- if (part->_player && part->_player->getMidiDriver() == midi &&
- !part->_percussion && part->_on &&
- !part->_mc && part->_pri_eff >= hipri) {
- hipri = part->_pri_eff;
- hipart = part;
- }
- }
-
- if (!hipart)
- return;
-
- if ((hipart->_mc = midi->allocateChannel()) == NULL) {
- lopri = 255;
- lopart = NULL;
- for (i = 32, part = _parts; i; i--, part++) {
- if (part->_mc && part->_mc->device() == midi && part->_pri_eff <= lopri) {
- lopri = part->_pri_eff;
- lopart = part;
- }
- }
-
- if (lopart == NULL || lopri >= hipri)
- return;
- lopart->off();
-
- if ((hipart->_mc = midi->allocateChannel()) == NULL)
- return;
- }
- hipart->sendAll();
- }
-}
-
-void IMuseInternal::setGlobalAdlibInstrument(byte slot, byte *data) {
- if (slot < 32) {
- _global_adlib_instruments[slot].adlib(data);
- }
-}
-
-void IMuseInternal::copyGlobalAdlibInstrument(byte slot, Instrument *dest) {
- if (slot >= 32)
- return;
- _global_adlib_instruments[slot].copy_to(dest);
-}
-
-////////////////////////////////////////////////////////////
-//
-// IMuse implementation
-//
-// IMuse actually serves as a concurency monitor front-end
-// to IMuseInternal and ensures that only one thread
-// accesses the object at a time. This is necessary to
-// prevent scripts and the MIDI parser from yanking objects
-// out from underneath each other.
-//
-////////////////////////////////////////////////////////////
-
-IMuse::IMuse(OSystem *system, IMuseInternal *target)
- : _system(system), _target(target) {
- _mutex = system->createMutex();
-}
-
-IMuse::~IMuse() {
- if (_mutex)
- _system->deleteMutex(_mutex);
- if (_target)
- delete _target;
-}
-
-inline void IMuse::in() const {
- _system->lockMutex(_mutex);
-}
-inline void IMuse::out() const {
- _system->unlockMutex(_mutex);
-}
-
-void IMuse::on_timer(MidiDriver *midi) { in(); _target->on_timer(midi); out(); }
-void IMuse::pause(bool paused) { in(); _target->pause(paused); out(); }
-int IMuse::save_or_load(Serializer *ser, ScummEngine *scumm) { in(); int ret = _target->save_or_load(ser, scumm); out(); return ret; }
-void IMuse::setMusicVolume(int vol) { in(); _target->setMusicVolume(vol); out(); }
-void IMuse::startSound(int sound) { in(); _target->startSound(sound); out(); }
-void IMuse::stopSound(int sound) { in(); _target->stopSound(sound); out(); }
-void IMuse::stopAllSounds() { in(); _target->stopAllSounds(); out(); }
-int IMuse::getSoundStatus(int sound) const { in(); int ret = _target->getSoundStatus(sound, true); out(); return ret; }
-bool IMuse::get_sound_active(int sound) const { in(); bool ret = _target->getSoundStatus(sound, false) ? 1 : 0; out(); return ret; }
-int IMuse::getMusicTimer() const { in(); int ret = _target->getMusicTimer(); out(); return ret; }
-int32 IMuse::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) { in(); int32 ret = _target->doCommand(a,b,c,d,e,f,g,h); out(); return ret; }
-int32 IMuse::doCommand(int numargs, int args[]) { in(); int32 ret = _target->doCommand(numargs, args); out(); return ret; }
-int IMuse::clear_queue() { in(); int ret = _target->clear_queue(); out(); return ret; }
-void IMuse::setBase(byte **base) { in(); _target->setBase(base); out(); }
-uint32 IMuse::property(int prop, uint32 value) { in(); uint32 ret = _target->property(prop, value); out(); return ret; }
-void IMuse::terminate() { in(); _target->terminate1(); out(); _target->terminate2(); }
-
-// The IMuse::create method provides a front-end factory
-// for creating IMuseInternal without exposing that class
-// to the client.
-IMuse *IMuse::create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver) {
- IMuseInternal *engine = IMuseInternal::create(syst, nativeMidiDriver, adlibMidiDriver);
- return new IMuse(syst, engine);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/imuse.h b/scumm/imuse.h
deleted file mode 100644
index 0c9a9206ba..0000000000
--- a/scumm/imuse.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef IMUSE_H
-#define IMUSE_H
-
-#include "common/scummsys.h"
-#include "common/mutex.h"
-#include "scumm/music.h"
-
-class MidiDriver;
-class OSystem;
-
-namespace Scumm {
-
-class IMuseInternal;
-class ScummEngine;
-class Serializer;
-
-class IMuse : public MusicEngine {
-private:
- OSystem *_system;
- IMuseInternal *_target;
- mutable Common::MutexRef _mutex;
-
- IMuse(OSystem *system, IMuseInternal *target);
- void in() const;
- void out() const;
-
-public:
- ~IMuse();
-
- enum {
- PROP_TEMPO_BASE,
- PROP_NATIVE_MT32,
- PROP_GS,
- PROP_LIMIT_PLAYERS,
- PROP_RECYCLE_PLAYERS,
- PROP_DIRECT_PASSTHROUGH
- };
-
- void on_timer(MidiDriver *midi);
- void pause(bool paused);
- int save_or_load(Serializer *ser, ScummEngine *scumm);
- void setMusicVolume(int vol);
- void startSound(int sound);
- void stopSound(int sound);
- void stopAllSounds();
- int getSoundStatus(int sound) const;
- bool get_sound_active(int sound) const;
- int getMusicTimer() const;
- int32 doCommand(int a, int b, int c, int d, int e, int f, int g, int h);
- int32 doCommand(int numargs, int args[]);
- int clear_queue();
- void setBase(byte **base);
- uint32 property(int prop, uint32 value);
- void terminate();
-
- // Factory methods
- static IMuse *create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/imuse_digi/dimuse.cpp b/scumm/imuse_digi/dimuse.cpp
deleted file mode 100644
index c057cc8d85..0000000000
--- a/scumm/imuse_digi/dimuse.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "common/timer.h"
-
-#include "scumm/actor.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-IMuseDigital::Track::Track()
- : soundId(-1), used(false), stream(NULL), stream2(NULL) {
-}
-
-void IMuseDigital::timer_handler(void *refCon) {
- IMuseDigital *imuseDigital = (IMuseDigital *)refCon;
- imuseDigital->callback();
-}
-
-IMuseDigital::IMuseDigital(ScummEngine *scumm, int fps)
- : _vm(scumm) {
- _pause = false;
- _sound = new ImuseDigiSndMgr(_vm);
- _callbackFps = fps;
- resetState();
- for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
- _track[l] = new Track;
- _track[l]->trackId = l;
- _track[l]->used = false;
- }
- _vm->_timer->installTimerProc(timer_handler, 1000000 / _callbackFps, this);
-
- _audioNames = NULL;
- _numAudioNames = 0;
-}
-
-IMuseDigital::~IMuseDigital() {
- stopAllSounds();
- _vm->_timer->removeTimerProc(timer_handler);
- for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
- delete _track[l];
- }
- delete _sound;
- free(_audioNames);
-}
-
-void IMuseDigital::resetState() {
- _curMusicState = 0;
- _curMusicSeq = 0;
- _curMusicCue = 0;
- memset(_attributes, 0, sizeof(_attributes));
- _nextSeqToPlay = 0;
-}
-
-void IMuseDigital::saveOrLoad(Serializer *ser) {
- Common::StackLock lock(_mutex, "IMuseDigital::saveOrLoad()");
-
- const SaveLoadEntry mainEntries[] = {
- MK_OBSOLETE(IMuseDigital, _volVoice, sleInt32, VER(31), VER(42)),
- MK_OBSOLETE(IMuseDigital, _volSfx, sleInt32, VER(31), VER(42)),
- MK_OBSOLETE(IMuseDigital, _volMusic, sleInt32, VER(31), VER(42)),
- MKLINE(IMuseDigital, _curMusicState, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _curMusicSeq, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _curMusicCue, sleInt32, VER(31)),
- MKLINE(IMuseDigital, _nextSeqToPlay, sleInt32, VER(31)),
- MKARRAY(IMuseDigital, _attributes[0], sleInt32, 188, VER(31)),
- MKEND()
- };
-
- const SaveLoadEntry trackEntries[] = {
- MKLINE(Track, pan, sleInt8, VER(31)),
- MKLINE(Track, vol, sleInt32, VER(31)),
- MKLINE(Track, volFadeDest, sleInt32, VER(31)),
- MKLINE(Track, volFadeStep, sleInt32, VER(31)),
- MKLINE(Track, volFadeDelay, sleInt32, VER(31)),
- MKLINE(Track, volFadeUsed, sleByte, VER(31)),
- MKLINE(Track, soundId, sleInt32, VER(31)),
- MKARRAY(Track, soundName[0], sleByte, 15, VER(31)),
- MKLINE(Track, used, sleByte, VER(31)),
- MKLINE(Track, toBeRemoved, sleByte, VER(31)),
- MKLINE(Track, souStream, sleByte, VER(31)),
- MKLINE(Track, started, sleByte, VER(31)),
- MKLINE(Track, priority, sleInt32, VER(31)),
- MKLINE(Track, regionOffset, sleInt32, VER(31)),
- MK_OBSOLETE(Track, trackOffset, sleInt32, VER(31), VER(31)),
- MKLINE(Track, dataOffset, sleInt32, VER(31)),
- MKLINE(Track, curRegion, sleInt32, VER(31)),
- MKLINE(Track, curHookId, sleInt32, VER(31)),
- MKLINE(Track, volGroupId, sleInt32, VER(31)),
- MKLINE(Track, soundType, sleInt32, VER(31)),
- MKLINE(Track, iteration, sleInt32, VER(31)),
- MKLINE(Track, mod, sleInt32, VER(31)),
- MKLINE(Track, mixerFlags, sleInt32, VER(31)),
- MK_OBSOLETE(Track, mixerVol, sleInt32, VER(31), VER(42)),
- MK_OBSOLETE(Track, mixerPan, sleInt32, VER(31), VER(42)),
- MKLINE(Track, compressed, sleByte, VER(45)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, mainEntries);
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
- Track *track = _track[l];
- if (!ser->isSaving()) {
- track->compressed = false;
- }
- ser->saveLoadEntries(track, trackEntries);
- if (!ser->isSaving()) {
- if (!track->used)
- continue;
- track->readyToRemove = false;
- if ((track->toBeRemoved) || (track->souStream) || (track->curRegion == -1)) {
- track->stream2 = NULL;
- track->stream = NULL;
- track->used = false;
- continue;
- }
-
- track->soundHandle = _sound->openSound(track->soundId,
- track->soundName, track->soundType,
- track->volGroupId, -1);
- if (!track->soundHandle) {
- warning("IMuseDigital::saveOrLoad: Can't open sound so will not be resumed, propably on diffrent CD");
- track->stream2 = NULL;
- track->stream = NULL;
- track->used = false;
- continue;
- }
-
- if (track->compressed) {
- track->regionOffset = 0;
- }
- track->compressed = _sound->isCompressed(track->soundHandle);
- if (track->compressed) {
- track->regionOffset = 0;
- }
- track->dataOffset = _sound->getRegionOffset(track->soundHandle, track->curRegion);
- int bits = _sound->getBits(track->soundHandle);
- int channels = _sound->getChannels(track->soundHandle);
- int freq = _sound->getFreq(track->soundHandle);
- track->iteration = freq * channels;
- track->mixerFlags = 0;
- if (channels == 2)
- track->mixerFlags = Audio::Mixer::FLAG_STEREO | Audio::Mixer::FLAG_REVERSE_STEREO;
-
- if ((bits == 12) || (bits == 16)) {
- track->mixerFlags |= Audio::Mixer::FLAG_16BITS;
- track->iteration *= 2;
- } else if (bits == 8) {
- track->mixerFlags |= Audio::Mixer::FLAG_UNSIGNED;
- } else
- error("IMuseDigital::saveOrLoad(): Can't handle %d bit samples", bits);
-
-#ifdef SCUMM_LITTLE_ENDIAN
- if (track->compressed)
- track->mixerFlags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
-#endif
-
- int32 streamBufferSize = track->iteration;
- track->stream2 = NULL;
- track->stream = makeAppendableAudioStream(freq, track->mixerFlags, streamBufferSize);
-
- const int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
- const int vol = track->vol / 1000;
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
-
- if (track->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (track->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (track->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- _vm->_mixer->playInputStream(type, &track->handle, track->stream, -1, vol, pan, false);
- }
- }
-}
-
-void IMuseDigital::callback() {
- Common::StackLock lock(_mutex, "IMuseDigital::callback()");
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->readyToRemove) {
- if (track->toBeRemoved) {
- track->readyToRemove = true;
- continue;
- }
-
- if (_pause || !_vm)
- return;
-
- if (track->volFadeUsed) {
- if (track->volFadeStep < 0) {
- if (track->vol > track->volFadeDest) {
- track->vol += track->volFadeStep;
- if (track->vol < track->volFadeDest) {
- track->vol = track->volFadeDest;
- track->volFadeUsed = false;
- }
- if (track->vol == 0) {
- track->toBeRemoved = true;
- }
- }
- } else if (track->volFadeStep > 0) {
- if (track->vol < track->volFadeDest) {
- track->vol += track->volFadeStep;
- if (track->vol > track->volFadeDest) {
- track->vol = track->volFadeDest;
- track->volFadeUsed = false;
- }
- }
- }
- debug(5, "Fade: sound(%d), Vol(%d)", track->soundId, track->vol / 1000);
- }
-
- const int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
- const int vol = track->vol / 1000;
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
-
- if (track->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (track->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (track->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- if (track->stream) {
- byte *data = NULL;
- int32 result = 0;
-
- if (track->curRegion == -1) {
- switchToNextRegion(track);
- if (track->toBeRemoved)
- continue;
- }
-
- int bits = _sound->getBits(track->soundHandle);
- int channels = _sound->getChannels(track->soundHandle);
-
- int32 mixer_size = track->iteration / _callbackFps;
-
- if (track->stream->endOfData()) {
- mixer_size *= 2;
- }
-
- if ((bits == 12) || (bits == 16)) {
- if (channels == 1)
- mixer_size &= ~1;
- if (channels == 2)
- mixer_size &= ~3;
- } else {
- if (channels == 2)
- mixer_size &= ~1;
- }
-
- if (mixer_size == 0)
- continue;
-
- do {
- if (bits == 12) {
- byte *ptr = NULL;
-
- mixer_size += track->mod;
- int mixer_size_12 = (mixer_size * 3) / 4;
- int length = (mixer_size_12 / 3) * 4;
- track->mod = mixer_size - length;
-
- int32 offset = (track->regionOffset * 3) / 4;
- int result2 = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &ptr, offset, mixer_size_12);
- result = BundleCodecs::decode12BitsSample(ptr, &data, result2);
-
- free(ptr);
- } else if (bits == 16) {
- result = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &data, track->regionOffset, mixer_size);
- if (channels == 1) {
- result &= ~1;
- }
- if (channels == 2) {
- result &= ~3;
- }
- } else if (bits == 8) {
- result = _sound->getDataFromRegion(track->soundHandle, track->curRegion, &data, track->regionOffset, mixer_size);
- if (channels == 2) {
- result &= ~1;
- }
- }
-
- if (result > mixer_size)
- result = mixer_size;
-
- if (_vm->_mixer->isReady()) {
- _vm->_mixer->setChannelVolume(track->handle, vol);
- _vm->_mixer->setChannelBalance(track->handle, pan);
- track->stream->append(data, result);
- track->regionOffset += result;
- }
- free(data);
-
- if (_sound->isEndOfRegion(track->soundHandle, track->curRegion)) {
- switchToNextRegion(track);
- if (track->toBeRemoved)
- break;
- }
- mixer_size -= result;
- assert(mixer_size >= 0);
- } while (mixer_size != 0);
- } else if (track->stream2) {
- if (_vm->_mixer->isReady()) {
- if (!track->started) {
- track->started = true;
- _vm->_mixer->playInputStream(type, &track->handle, track->stream2, -1, vol, pan, false);
- } else {
- _vm->_mixer->setChannelVolume(track->handle, vol);
- _vm->_mixer->setChannelBalance(track->handle, pan);
- }
- }
- }
- }
- }
-}
-
-void IMuseDigital::switchToNextRegion(Track *track) {
- assert(track);
- debug(5, "switchToNextRegion(track:%d)", track->trackId);
-
- if (track->trackId >= MAX_DIGITAL_TRACKS) {
- track->toBeRemoved = true;
- debug(5, "exit (fadetrack can't go next region) switchToNextRegion(trackId:%d)", track->trackId);
- return;
- }
-
- int num_regions = _sound->getNumRegions(track->soundHandle);
-
- if (++track->curRegion == num_regions) {
- track->toBeRemoved = true;
- debug(5, "exit (end of regions) switchToNextRegion(track:%d)", track->trackId);
- return;
- }
-
- ImuseDigiSndMgr::soundStruct *soundHandle = track->soundHandle;
- int jumpId = _sound->getJumpIdByRegionAndHookId(soundHandle, track->curRegion, track->curHookId);
- if (jumpId == -1)
- jumpId = _sound->getJumpIdByRegionAndHookId(soundHandle, track->curRegion, 0);
- if (jumpId != -1) {
- int region = _sound->getRegionIdByJumpId(soundHandle, jumpId);
- assert(region != -1);
- int sampleHookId = _sound->getJumpHookId(soundHandle, jumpId);
- assert(sampleHookId != -1);
- int fadeDelay = (60 * _sound->getJumpFade(soundHandle, jumpId)) / 1000;
- if (sampleHookId != 0) {
- if (track->curHookId == sampleHookId) {
- if (fadeDelay != 0) {
- Track *fadeTrack = cloneToFadeOutTrack(track, fadeDelay);
- if (fadeTrack) {
- fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundHandle, fadeTrack->curRegion);
- fadeTrack->regionOffset = 0;
- debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
- fadeTrack->curHookId = 0;
- }
- }
- track->curRegion = region;
- debug(5, "switchToNextRegion-sound(%d) jump to region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
- track->curHookId = 0;
- }
- } else {
- if (fadeDelay != 0) {
- Track *fadeTrack = cloneToFadeOutTrack(track, fadeDelay);
- if (fadeTrack) {
- fadeTrack->dataOffset = _sound->getRegionOffset(fadeTrack->soundHandle, fadeTrack->curRegion);
- fadeTrack->regionOffset = 0;
- debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", fadeTrack->soundId, fadeTrack->curRegion, fadeTrack->curHookId);
- }
- }
- track->curRegion = region;
- debug(5, "switchToNextRegion-sound(%d) jump to region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
- }
- }
-
- debug(5, "switchToNextRegion-sound(%d) select region %d, curHookId: %d", track->soundId, track->curRegion, track->curHookId);
- track->dataOffset = _sound->getRegionOffset(soundHandle, track->curRegion);
- track->regionOffset = 0;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/imuse_digi/dimuse.h b/scumm/imuse_digi/dimuse.h
deleted file mode 100644
index fed2e48457..0000000000
--- a/scumm/imuse_digi/dimuse.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#if !defined(IMUSE_DIGI_H) && !defined(DISABLE_SCUMM_7_8)
-#define IMUSE_DIGI_H
-
-#include "common/scummsys.h"
-#include "common/util.h"
-
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-#include "scumm/imuse_digi/dimuse_sndmgr.h"
-#include "scumm/music.h"
-#include "scumm/sound.h"
-
-#include "sound/mixer.h"
-#include "sound/audiostream.h"
-
-namespace Scumm {
-
-#define MAX_DIGITAL_TRACKS 8
-#define MAX_DIGITAL_FADETRACKS 8
-
-struct imuseDigTable;
-struct imuseComiTable;
-class Serializer;
-
-class IMuseDigital : public MusicEngine {
-private:
-
- int _callbackFps;
-
- struct Track {
- int trackId;
-
- int8 pan; // pan
- int32 vol; // volume
- int32 volFadeDest; //
- int32 volFadeStep; //
- int32 volFadeDelay; //
- bool volFadeUsed; //
-
- int32 soundId;
- char soundName[15];
- bool used;
- bool toBeRemoved;
- bool readyToRemove;
- bool started;
- bool souStream;
- bool compressed;
- int32 priority;
- int32 regionOffset;
- int32 dataOffset;
- int32 curRegion;
- int32 curHookId;
- int32 volGroupId;
- int32 soundType;
- int32 iteration;
- int32 mod;
- int32 mixerFlags;
-
- ImuseDigiSndMgr::soundStruct *soundHandle;
- Audio::SoundHandle handle;
- AppendableAudioStream *stream;
- AudioStream *stream2;
-
- Track();
- };
-
- Track *_track[MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS];
-
- Common::Mutex _mutex;
- ScummEngine *_vm;
- ImuseDigiSndMgr *_sound;
-
- char *_audioNames;
- int32 _numAudioNames;
-
- bool _pause;
-
- int32 _attributes[188];
- int32 _nextSeqToPlay;
- int32 _curMusicState;
- int32 _curMusicSeq;
- int32 _curMusicCue;
-
- static void timer_handler(void *refConf);
- void callback();
- void switchToNextRegion(Track *track);
- int allocSlot(int priority);
- void startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority);
- void selectVolumeGroup(int soundId, int volGroupId);
-
- int32 getPosInMs(int soundId);
- void getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height);
-
- int getSoundIdByName(const char *soundName);
- void fadeOutMusic(int fadeDelay);
- Track *cloneToFadeOutTrack(Track *track, int fadeDelay);
-
- void setFtMusicState(int stateId);
- void setFtMusicSequence(int seqId);
- void setFtMusicCuePoint(int cueId);
- void playFtMusic(const char *songName, int opcode, int volume);
-
- void setComiMusicState(int stateId);
- void setComiMusicSequence(int seqId);
- void playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence);
-
- void setDigMusicState(int stateId);
- void setDigMusicSequence(int seqId);
- void playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence);
-
-public:
- IMuseDigital(ScummEngine *scumm, int fps);
- virtual ~IMuseDigital();
-
- void setAudioNames(int32 num, char *names);
-
- void startVoice(int soundId, AudioStream *input);
- void startVoice(int soundId, const char *soundName);
- void startMusic(int soundId, int volume);
- void startMusic(const char *soundName, int soundId, int hookId, int volume);
- void startSfx(int soundId, int priority);
- void startSound(int sound)
- { error("MusicEngine::startSound() Should be never called"); }
-
- void saveOrLoad(Serializer *ser);
- void resetState();
-
- void setPriority(int soundId, int priority);
- void setVolume(int soundId, int volume);
- void setPan(int soundId, int pan);
- void setFade(int soundId, int destVolume, int delay60HzTicks);
- int getCurMusicSoundId();
- char *getCurMusicSoundName();
- void setHookId(int soundId, int hookId);
- void setMusicVolume(int vol) {}
- void stopSound(int sound);
- void stopAllSounds();
- void pause(bool pause);
- void parseScriptCmds(int cmd, int soundId, int sub_cmd, int d, int e, int f, int g, int h);
- void refreshScripts();
- void flushTracks();
- int getSoundStatus(int sound) const;
- int32 getCurMusicPosInMs();
- int32 getCurVoiceLipSyncWidth();
- int32 getCurVoiceLipSyncHeight();
- int32 getCurMusicLipSyncWidth(int syncId);
- int32 getCurMusicLipSyncHeight(int syncId);
-};
-
-struct imuseRoomMap {
- int8 roomId;
- byte stateIndex1;
- byte offset;
- byte stateIndex2;
- byte atribPos;
- byte stateIndex3;
-};
-
-struct imuseDigTable {
- byte opcode;
- int16 soundId;
- char name[20];
- byte atribPos;
- byte hookId;
- char filename[13];
-};
-
-struct imuseComiTable {
- byte opcode;
- int16 soundId;
- char name[20];
- byte atribPos;
- byte hookId;
- int16 fadeOut60TicksDelay;
- char filename[13];
-};
-
-
-struct imuseFtNames {
- char name[20];
-};
-
-struct imuseFtStateTable {
- char audioName[9];
- byte opcode;
- byte volume;
- char name[21];
-};
-
-struct imuseFtSeqTable {
- char audioName[9];
- byte opcode;
- byte volume;
-};
-
-#ifdef PALMOS_68K
-extern const imuseRoomMap *_digStateMusicMap;
-extern const imuseDigTable *_digStateMusicTable;
-extern const imuseDigTable *_digSeqMusicTable;
-extern const imuseComiTable *_comiStateMusicTable;
-extern const imuseComiTable *_comiSeqMusicTable;
-extern const imuseFtStateTable *_ftStateMusicTable;
-extern const imuseFtSeqTable *_ftSeqMusicTable;
-extern const imuseFtNames *_ftSeqNames;
-#else
-extern const imuseRoomMap _digStateMusicMap[];
-extern const imuseDigTable _digStateMusicTable[];
-extern const imuseDigTable _digSeqMusicTable[];
-extern const imuseComiTable _comiStateMusicTable[];
-extern const imuseComiTable _comiSeqMusicTable[];
-extern const imuseFtStateTable _ftStateMusicTable[];
-extern const imuseFtSeqTable _ftSeqMusicTable[];
-extern const imuseFtNames _ftSeqNames[];
-#endif
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/imuse_digi/dimuse_bndmgr.cpp b/scumm/imuse_digi/dimuse_bndmgr.cpp
deleted file mode 100644
index d36d733ef2..0000000000
--- a/scumm/imuse_digi/dimuse_bndmgr.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-#include "scumm/scumm.h"
-#include "scumm/util.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-
-namespace Scumm {
-
-BundleDirCache::BundleDirCache() {
- for (int fileId = 0; fileId < ARRAYSIZE(_budleDirCache); fileId++) {
- _budleDirCache[fileId].bundleTable = NULL;
- _budleDirCache[fileId].fileName[0] = 0;
- _budleDirCache[fileId].numFiles = 0;
- _budleDirCache[fileId].compressedBun = false;
- _budleDirCache[fileId].indexTable = NULL;
- }
-}
-
-BundleDirCache::~BundleDirCache() {
- for (int fileId = 0; fileId < ARRAYSIZE(_budleDirCache); fileId++) {
- free(_budleDirCache[fileId].bundleTable);
- free(_budleDirCache[fileId].indexTable);
- }
-}
-
-BundleDirCache::AudioTable *BundleDirCache::getTable(int slot) {
- return _budleDirCache[slot].bundleTable;
-}
-
-int32 BundleDirCache::getNumFiles(int slot) {
- return _budleDirCache[slot].numFiles;
-}
-
-BundleDirCache::IndexNode *BundleDirCache::getIndexTable(int slot) {
- return _budleDirCache[slot].indexTable;
-}
-
-bool BundleDirCache::isCompressed(int slot) {
- return _budleDirCache[slot].compressedBun;
-}
-
-int BundleDirCache::matchFile(const char *filename) {
- int32 tag, offset;
- bool found = false;
- int freeSlot = -1;
- int fileId;
-
- for (fileId = 0; fileId < ARRAYSIZE(_budleDirCache); fileId++) {
- if ((_budleDirCache[fileId].bundleTable == NULL) && (freeSlot == -1)) {
- freeSlot = fileId;
- }
- if (scumm_stricmp(filename, _budleDirCache[fileId].fileName) == 0) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- ScummFile file;
-
- if (g_scumm->openFile(file, filename) == false) {
- error("BundleDirCache::matchFile() Can't open bundle file: %s", filename);
- return false;
- }
-
- if (freeSlot == -1)
- error("BundleDirCache::matchFileFile() Can't find free slot for file bundle dir cache");
-
- tag = file.readUint32BE();
- if (tag == 'LB23')
- _budleDirCache[freeSlot].compressedBun = true;
- offset = file.readUint32BE();
-
- strcpy(_budleDirCache[freeSlot].fileName, filename);
- _budleDirCache[freeSlot].numFiles = file.readUint32BE();
- _budleDirCache[freeSlot].bundleTable = (AudioTable *) malloc(_budleDirCache[freeSlot].numFiles * sizeof(AudioTable));
-
- file.seek(offset, SEEK_SET);
-
- _budleDirCache[freeSlot].indexTable =
- (IndexNode *)calloc(_budleDirCache[freeSlot].numFiles, sizeof(IndexNode));
-
- for (int32 i = 0; i < _budleDirCache[freeSlot].numFiles; i++) {
- char name[24], c;
- int32 z = 0;
- int32 z2;
-
- if (tag == 'LB23') {
- file.read(_budleDirCache[freeSlot].bundleTable[i].filename, 24);
- } else {
- for (z2 = 0; z2 < 8; z2++)
- if ((c = file.readByte()) != 0)
- name[z++] = c;
- name[z++] = '.';
- for (z2 = 0; z2 < 4; z2++)
- if ((c = file.readByte()) != 0)
- name[z++] = c;
-
- name[z] = '\0';
- strcpy(_budleDirCache[freeSlot].bundleTable[i].filename, name);
- }
- _budleDirCache[freeSlot].bundleTable[i].offset = file.readUint32BE();
- _budleDirCache[freeSlot].bundleTable[i].size = file.readUint32BE();
- strcpy(_budleDirCache[freeSlot].indexTable[i].filename,
- _budleDirCache[freeSlot].bundleTable[i].filename);
- _budleDirCache[freeSlot].indexTable[i].index = i;
- }
- qsort(_budleDirCache[freeSlot].indexTable, _budleDirCache[freeSlot].numFiles,
- sizeof(IndexNode), (int (*)(const void*, const void*))scumm_stricmp);
- return freeSlot;
- } else {
- return fileId;
- }
-}
-
-BundleMgr::BundleMgr(BundleDirCache *cache) {
- _cache = cache;
- _bundleTable = NULL;
- _compTable = NULL;
- _numFiles = 0;
- _numCompItems = 0;
- _curSample = -1;
- _fileBundleId = -1;
- _compInput = NULL;
-}
-
-BundleMgr::~BundleMgr() {
- close();
-}
-
-Common::File *BundleMgr::getFile(const char *filename, int32 &offset, int32 &size) {
- BundleDirCache::IndexNode target;
- strcpy(target.filename, filename);
- BundleDirCache::IndexNode *found = (BundleDirCache::IndexNode *)bsearch(&target, _indexTable, _numFiles,
- sizeof(BundleDirCache::IndexNode), (int (*)(const void*, const void*))scumm_stricmp);
- if (found) {
- _file.seek(_bundleTable[found->index].offset, SEEK_SET);
- offset = _bundleTable[found->index].offset;
- size = _bundleTable[found->index].size;
- return &_file;
- }
-
- return NULL;
-}
-
-bool BundleMgr::open(const char *filename, bool &compressed, bool errorFlag) {
- if (_file.isOpen())
- return true;
-
- if (g_scumm->openFile(_file, filename) == false) {
- if (errorFlag) {
- error("BundleMgr::open() Can't open bundle file: %s", filename);
- } else {
- warning("BundleMgr::open() Can't open bundle file: %s", filename);
- }
- return false;
- }
-
- int slot = _cache->matchFile(filename);
- assert(slot != -1);
- compressed = _cache->isCompressed(slot);
- _numFiles = _cache->getNumFiles(slot);
- assert(_numFiles);
- _bundleTable = _cache->getTable(slot);
- _indexTable = _cache->getIndexTable(slot);
- assert(_bundleTable);
- _compTableLoaded = false;
- _outputSize = 0;
- _lastBlock = -1;
-
- return true;
-}
-
-void BundleMgr::close() {
- if (_file.isOpen()) {
- _file.close();
- _bundleTable = NULL;
- _numFiles = 0;
- _numCompItems = 0;
- _compTableLoaded = false;
- _lastBlock = -1;
- _outputSize = 0;
- _curSample = -1;
- free(_compTable);
- _compTable = NULL;
- free(_compInput);
- _compInput = NULL;
- }
-}
-
-bool BundleMgr::loadCompTable(int32 index) {
- _file.seek(_bundleTable[index].offset, SEEK_SET);
- uint32 tag = _file.readUint32BE();
- _numCompItems = _file.readUint32BE();
- assert(_numCompItems > 0);
- _file.seek(8, SEEK_CUR);
-
- if (tag != MKID_BE('COMP')) {
- error("BundleMgr::loadCompTable() Compressed sound %d invalid (%s)", index, tag2str(tag));
- return false;
- }
-
- _compTable = (CompTable *)malloc(sizeof(CompTable) * _numCompItems);
- int32 maxSize = 0;
- for (int i = 0; i < _numCompItems; i++) {
- _compTable[i].offset = _file.readUint32BE();
- _compTable[i].size = _file.readUint32BE();
- _compTable[i].codec = _file.readUint32BE();
- _file.seek(4, SEEK_CUR);
- if (_compTable[i].size > maxSize)
- maxSize = _compTable[i].size;
- }
- // CMI hack: one more byte at the end of input buffer
- _compInput = (byte *)malloc(maxSize + 1);
-
- return true;
-}
-
-int32 BundleMgr::decompressSampleByCurIndex(int32 offset, int32 size, byte **comp_final, int header_size, bool header_outside) {
- return decompressSampleByIndex(_curSample, offset, size, comp_final, header_size, header_outside);
-}
-
-int32 BundleMgr::decompressSampleByIndex(int32 index, int32 offset, int32 size, byte **comp_final, int header_size, bool header_outside) {
- int32 i, final_size, output_size;
- int skip, first_block, last_block;
-
- assert(0 <= index && index < _numFiles);
-
- if (_file.isOpen() == false) {
- error("BundleMgr::decompressSampleByIndex() File is not open!");
- return 0;
- }
-
- if (_curSample == -1)
- _curSample = index;
-
- assert(_curSample == index);
-
- if (!_compTableLoaded) {
- _compTableLoaded = loadCompTable(index);
- if (!_compTableLoaded)
- return 0;
- }
-
- first_block = (offset + header_size) / 0x2000;
- last_block = (offset + header_size + size - 1) / 0x2000;
-
- // Clip last_block by the total number of blocks (= "comp items")
- if ((last_block >= _numCompItems) && (_numCompItems > 0))
- last_block = _numCompItems - 1;
-
- int32 blocks_final_size = 0x2000 * (1 + last_block - first_block);
- *comp_final = (byte *)malloc(blocks_final_size);
- final_size = 0;
-
- skip = (offset + header_size) % 0x2000;
-
- for (i = first_block; i <= last_block; i++) {
- if (_lastBlock != i) {
- // CMI hack: one more zero byte at the end of input buffer
- _compInput[_compTable[i].size] = 0;
- _file.seek(_bundleTable[index].offset + _compTable[i].offset, SEEK_SET);
- _file.read(_compInput, _compTable[i].size);
- _outputSize = BundleCodecs::decompressCodec(_compTable[i].codec, _compInput, _compOutput, _compTable[i].size);
- if (_outputSize > 0x2000) {
- error("_outputSize: %d", _outputSize);
- }
- _lastBlock = i;
- }
-
- output_size = _outputSize;
-
- if (header_outside) {
- output_size -= skip;
- } else {
- if ((header_size != 0) && (skip >= header_size))
- output_size -= skip;
- }
-
- if ((output_size + skip) > 0x2000) // workaround
- output_size -= (output_size + skip) - 0x2000;
-
- if (output_size > size)
- output_size = size;
-
- assert(final_size + output_size <= blocks_final_size);
-
- memcpy(*comp_final + final_size, _compOutput + skip, output_size);
- final_size += output_size;
-
- size -= output_size;
- assert(size >= 0);
- if (size == 0)
- break;
-
- skip = 0;
- }
-
- return final_size;
-}
-
-int32 BundleMgr::decompressSampleByName(const char *name, int32 offset, int32 size, byte **comp_final, bool header_outside) {
- int32 final_size = 0;
-
- if (!_file.isOpen()) {
- error("BundleMgr::decompressSampleByName() File is not open!");
- return 0;
- }
-
- BundleDirCache::IndexNode target;
- strcpy(target.filename, name);
- BundleDirCache::IndexNode *found = (BundleDirCache::IndexNode *)bsearch(&target, _indexTable, _numFiles,
- sizeof(BundleDirCache::IndexNode), (int (*)(const void*, const void*))scumm_stricmp);
- if (found) {
- final_size = decompressSampleByIndex(found->index, offset, size, comp_final, 0, header_outside);
- return final_size;
- }
-
- debug(2, "BundleMgr::decompressSampleByName() Failed finding voice %s", name);
- return final_size;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/imuse_digi/dimuse_bndmgr.h b/scumm/imuse_digi/dimuse_bndmgr.h
deleted file mode 100644
index 36d4f5683e..0000000000
--- a/scumm/imuse_digi/dimuse_bndmgr.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef BUNDLE_MGR_H
-#define BUNDLE_MGR_H
-
-#include "common/scummsys.h"
-#include "common/file.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-class BundleDirCache {
-public:
- struct AudioTable {
- char filename[24];
- int32 offset;
- int32 size;
- };
-
- struct IndexNode {
- char filename[24];
- int32 index;
- };
-
-private:
-
- struct FileDirCache {
- char fileName[20];
- AudioTable *bundleTable;
- int32 numFiles;
- bool compressedBun;
- IndexNode *indexTable;
- } _budleDirCache[4];
-
-public:
- BundleDirCache();
- ~BundleDirCache();
-
- int matchFile(const char *filename);
- AudioTable *getTable(int slot);
- IndexNode *getIndexTable(int slot);
- int32 getNumFiles(int slot);
- bool isCompressed(int slot);
-};
-
-class BundleMgr {
-
-private:
-
- struct CompTable {
- int32 offset;
- int32 size;
- int32 codec;
- };
-
- BundleDirCache *_cache;
- BundleDirCache::AudioTable *_bundleTable;
- BundleDirCache::IndexNode *_indexTable;
- CompTable *_compTable;
- int _numFiles;
- int _numCompItems;
- int _curSample;
- ScummFile _file;
- bool _compTableLoaded;
- int _fileBundleId;
- byte _compOutput[0x2000];
- byte *_compInput;
- int _outputSize;
- int _lastBlock;
-
- bool loadCompTable(int32 index);
-
-public:
-
- BundleMgr(BundleDirCache *_cache);
- ~BundleMgr();
-
- bool open(const char *filename, bool &compressed, bool errorFlag=false);
- void close();
- Common::File *getFile(const char *filename, int32 &offset, int32 &size);
- int32 decompressSampleByName(const char *name, int32 offset, int32 size, byte **comp_final, bool header_outside);
- int32 decompressSampleByIndex(int32 index, int32 offset, int32 size, byte **comp_final, int header_size, bool header_outside);
- int32 decompressSampleByCurIndex(int32 offset, int32 size, byte **comp_final, int header_size, bool header_outside);
-};
-
-namespace BundleCodecs {
-
-uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size);
-void initializeImcTables();
-int32 decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 input_size);
-
-} // End of namespace BundleCodecs
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/imuse_digi/dimuse_codecs.cpp b/scumm/imuse_digi/dimuse_codecs.cpp
deleted file mode 100644
index dccae928b0..0000000000
--- a/scumm/imuse_digi/dimuse_codecs.cpp
+++ /dev/null
@@ -1,655 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-#include "common/util.h"
-
-namespace Scumm {
-
-namespace BundleCodecs {
-
-uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size) {
- uint32 loop_size = size / 3;
- uint32 s_size = loop_size * 4;
- byte *ptr = *dst = (byte *)malloc(s_size);
-
- uint32 tmp;
- while (loop_size--) {
- byte v1 = *src++;
- byte v2 = *src++;
- byte v3 = *src++;
- tmp = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
- WRITE_BE_UINT16(ptr, tmp); ptr += 2;
- tmp = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
- WRITE_BE_UINT16(ptr, tmp); ptr += 2;
- }
- return s_size;
-}
-
-/*
- * The "IMC" codec below (see cases 13 & 15 in decompressCodec) is actually a
- * variant of the IMA codec, see also
- * <http://www.multimedia.cx/simpleaudio.html>
- *
- * It is somewhat different, though: the standard ADPCM codecs use a fixed
- * size for their data packets (4 bits), while the codec implemented here
- * varies the size of each "packet" between 2 and 7 bits.
- */
-
-static byte _imcTableEntryBitCount[89];
-
-#ifdef PALMOS_68K
-static const int16 *imcTable;
-#else
-static const int16 imcTable[89] = {
- 7, 8, 9, 10, 11, 12, 13, 14,
- 16, 17, 19, 21, 23, 25, 28, 31,
- 34, 37, 41, 45, 50, 55, 60, 66,
- 73, 80, 88, 97, 107, 118, 130, 143,
- 157, 173, 190, 209, 230, 253, 279, 307,
- 337, 371, 408, 449, 494, 544, 598, 658,
- 724, 796, 876, 963, 1060, 1166, 1282, 1411,
- 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
- 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
- 7132, 7845, 8630, 9493,10442,11487,12635,13899,
- 15289,16818,18500,20350,22385,24623,27086,29794,
- 32767
-};
-#endif
-
-static const byte imxOtherTable[6][64] = {
- {
- 0xFF,
- 4
- },
-
- {
- 0xFF, 0xFF,
- 2, 8
- },
-
- {
- 0xFF, 0xFF, 0xFF, 0xFF,
- 1, 2, 4, 6
- },
-
- {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 1, 2, 4, 6, 8, 12, 16, 32
- },
-
- {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 1, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 32
- },
-
- {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32
- }
-};
-
-void initializeImcTables() {
- int pos;
-
- for (pos = 0; pos < ARRAYSIZE(imcTable); ++pos) {
- byte put = 0;
- int32 tableValue = ((imcTable[pos] * 4) / 7) / 2;
- while (tableValue != 0) {
- tableValue /= 2;
- put++;
- }
- if (put < 2) {
- put = 2;
- }
- if (put > 7) {
- put = 7;
- }
- _imcTableEntryBitCount[pos] = put;
- }
-}
-
-#define NextBit \
- do { \
- bit = mask & 1; \
- mask >>= 1; \
- if (!--bitsleft) { \
- mask = READ_LE_UINT16(srcptr); \
- srcptr += 2; \
- bitsleft = 16; \
- } \
- } while (0)
-
-static int32 compDecode(byte *src, byte *dst) {
- byte *result, *srcptr = src, *dstptr = dst;
- int data, size, bit, bitsleft = 16, mask = READ_LE_UINT16(srcptr);
- srcptr += 2;
-
- for (;;) {
- NextBit;
- if (bit) {
- *dstptr++ = *srcptr++;
- } else {
- NextBit;
- if (!bit) {
- NextBit;
- size = bit << 1;
- NextBit;
- size = (size | bit) + 3;
- data = *srcptr++ | 0xffffff00;
- } else {
- data = *srcptr++;
- size = *srcptr++;
-
- data |= 0xfffff000 + ((size & 0xf0) << 4);
- size = (size & 0x0f) + 3;
-
- if (size == 3)
- if (((*srcptr++) + 1) == 1)
- return dstptr - dst;
- }
- result = dstptr + data;
- while (size--)
- *dstptr++ = *result++;
- }
- }
-}
-#undef NextBit
-
-int32 decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 input_size) {
- int32 output_size, channels;
- int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z;
- byte *src, *t_table, *p, *ptr;
- byte t_tmp1, t_tmp2;
-
- switch (codec) {
- case 0:
- memcpy(comp_output, comp_input, input_size);
- output_size = input_size;
- break;
-
- case 1:
- output_size = compDecode(comp_input, comp_output);
- break;
-
- case 2:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
- break;
-
- case 3:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
- break;
-
- case 4:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
-
- t_table = (byte *)malloc(output_size);
-
- src = comp_output;
- length = (output_size << 3) / 12;
- k = 0;
- if (length > 0) {
- c = -12;
- s = 0;
- j = 0;
- do {
- ptr = src + length + (k >> 1);
- t_tmp2 = src[j];
- if (k & 1) {
- r = c >> 3;
- t_table[r + 2] = ((t_tmp2 & 0x0f) << 4) | (ptr[1] >> 4);
- t_table[r + 1] = (t_tmp2 & 0xf0) | (t_table[r + 1]);
- } else {
- r = s >> 3;
- t_table[r + 0] = ((t_tmp2 & 0x0f) << 4) | (ptr[0] & 0x0f);
- t_table[r + 1] = t_tmp2 >> 4;
- }
- s += 12;
- c += 12;
- k++;
- j++;
- } while (k < length);
- }
- offset1 = ((length - 1) * 3) >> 1;
- t_table[offset1 + 1] = (t_table[offset1 + 1]) | (src[length - 1] & 0xf0);
- memcpy(src, t_table, output_size);
- free(t_table);
- break;
-
- case 5:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
-
- t_table = (byte *)malloc(output_size);
-
- src = comp_output;
- length = (output_size << 3) / 12;
- k = 1;
- c = 0;
- s = 12;
- t_table[0] = src[length] >> 4;
- t = length + k;
- j = 1;
- if (t > k) {
- do {
- t_tmp1 = *(src + length + (k >> 1));
- t_tmp2 = src[j - 1];
- if (k & 1) {
- r = c >> 3;
- t_table[r + 0] = (t_tmp2 & 0xf0) | t_table[r];
- t_table[r + 1] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 & 0x0f);
- } else {
- r = s >> 3;
- t_table[r + 0] = t_tmp2 >> 4;
- t_table[r - 1] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 >> 4);
- }
- s += 12;
- c += 12;
- k++;
- j++;
- } while (k < t);
- }
- memcpy(src, t_table, output_size);
- free(t_table);
- break;
-
- case 6:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
-
- t_table = (byte *)malloc(output_size);
-
- src = comp_output;
- length = (output_size << 3) / 12;
- k = 0;
- c = 0;
- j = 0;
- s = -12;
- t_table[0] = src[output_size - 1];
- t_table[output_size - 1] = src[length - 1];
- t = length - 1;
- if (t > 0) {
- do {
- t_tmp1 = *(src + length + (k >> 1));
- t_tmp2 = src[j];
- if (k & 1) {
- r = s >> 3;
- t_table[r + 2] = (t_tmp2 & 0xf0) | t_table[r + 2];
- t_table[r + 3] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 >> 4);
- } else {
- r = c >> 3;
- t_table[r + 2] = t_tmp2 >> 4;
- t_table[r + 1] = ((t_tmp2 & 0x0f) << 4) | (t_tmp1 & 0x0f);
- }
- s += 12;
- c += 12;
- k++;
- j++;
- } while (k < t);
- }
- memcpy(src, t_table, output_size);
- free(t_table);
- break;
-
- case 10:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
-
- t_table = (byte *)malloc(output_size);
- memcpy(t_table, p, output_size);
-
- offset1 = output_size / 3;
- offset2 = offset1 << 1;
- offset3 = offset2;
- src = comp_output;
-
- while (offset1--) {
- offset2 -= 2;
- offset3--;
- t_table[offset2 + 0] = src[offset1];
- t_table[offset2 + 1] = src[offset3];
- }
-
- src = comp_output;
- length = (output_size << 3) / 12;
- k = 0;
- if (length > 0) {
- c = -12;
- s = 0;
- do {
- j = length + (k >> 1);
- t_tmp1 = t_table[k];
- if (k & 1) {
- r = c >> 3;
- t_tmp2 = t_table[j + 1];
- src[r + 2] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4);
- src[r + 1] = (src[r + 1]) | (t_tmp1 & 0xf0);
- } else {
- r = s >> 3;
- t_tmp2 = t_table[j];
- src[r + 0] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
- src[r + 1] = t_tmp1 >> 4;
- }
- s += 12;
- c += 12;
- k++;
- } while (k < length);
- }
- offset1 = ((length - 1) * 3) >> 1;
- src[offset1 + 1] = (t_table[length] & 0xf0) | src[offset1 + 1];
- free(t_table);
- break;
-
- case 11:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
-
- t_table = (byte *)malloc(output_size);
- memcpy(t_table, p, output_size);
-
- offset1 = output_size / 3;
- offset2 = offset1 << 1;
- offset3 = offset2;
- src = comp_output;
-
- while (offset1--) {
- offset2 -= 2;
- offset3--;
- t_table[offset2 + 0] = src[offset1];
- t_table[offset2 + 1] = src[offset3];
- }
-
- src = comp_output;
- length = (output_size << 3) / 12;
- k = 1;
- c = 0;
- s = 12;
- t_tmp1 = t_table[length] >> 4;
- src[0] = t_tmp1;
- t = length + k;
- if (t > k) {
- do {
- j = length + (k >> 1);
- t_tmp1 = t_table[k - 1];
- t_tmp2 = t_table[j];
- if (k & 1) {
- r = c >> 3;
- src[r + 0] = (src[r]) | (t_tmp1 & 0xf0);
- src[r + 1] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
- } else {
- r = s >> 3;
- src[r + 0] = t_tmp1 >> 4;
- src[r - 1] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4);
- }
- s += 12;
- c += 12;
- k++;
- } while (k < t);
- }
- free(t_table);
- break;
-
- case 12:
- output_size = compDecode(comp_input, comp_output);
- p = comp_output;
- for (z = 2; z < output_size; z++)
- p[z] += p[z - 1];
- for (z = 1; z < output_size; z++)
- p[z] += p[z - 1];
-
- t_table = (byte *)malloc(output_size);
- memcpy(t_table, p, output_size);
-
- offset1 = output_size / 3;
- offset2 = offset1 << 1;
- offset3 = offset2;
- src = comp_output;
-
- while (offset1--) {
- offset2 -= 2;
- offset3--;
- t_table[offset2 + 0] = src[offset1];
- t_table[offset2 + 1] = src[offset3];
- }
-
- src = comp_output;
- length = (output_size << 3) / 12;
- k = 0;
- c = 0;
- s = -12;
- src[0] = t_table[output_size - 1];
- src[output_size - 1] = t_table[length - 1];
- t = length - 1;
- if (t > 0) {
- do {
- j = length + (k >> 1);
- t_tmp1 = t_table[k];
- t_tmp2 = t_table[j];
- if (k & 1) {
- r = s >> 3;
- src[r + 2] = (src[r + 2]) | (t_tmp1 & 0xf0);
- src[r + 3] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4);
- } else {
- r = c >> 3;
- src[r + 2] = t_tmp1 >> 4;
- src[r + 1] = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
- }
- s += 12;
- c += 12;
- k++;
- } while (k < t);
- }
- free(t_table);
- break;
-
- case 13:
- case 15:
- if (codec == 13) {
- channels = 1;
- } else {
- channels = 2;
- }
-
- {
- // Decoder for the the IMA ADPCM variants used in COMI.
- // Contrary to regular IMA ADPCM, this codec uses a variable
- // bitsize for the encoded data.
-
- const int MAX_CHANNELS = 2;
- int32 outputSamplesLeft;
- int32 destPos;
- int16 firstWord;
- byte initialTablePos[MAX_CHANNELS] = {0, 0};
- int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7};
- int32 initialOutputWord[MAX_CHANNELS] = {0, 0};
- int32 totalBitOffset, curTablePos, outputWord;
- byte *dst;
- int i;
-
- // We only support mono and stereo
- assert(channels == 1 || channels == 2);
-
- src = comp_input;
- dst = comp_output;
- output_size = 0x2000;
- outputSamplesLeft = 0x1000;
-
- // Every data packet contains 0x2000 bytes of audio data
- // when extracted. In order to encode bigger data sets,
- // one has to split the data into multiple blocks.
- //
- // Every block starts with a 2 byte word. If that word is
- // non-zero, it indicates the size of a block of raw audio
- // data (not encoded) following it. That data we simply copy
- // to the output buffer and the proceed by decoding the
- // remaining data.
- //
- // If on the other hand the word is zero, then what follows
- // are 7*channels bytes containing seed data for the decoder.
- firstWord = READ_BE_UINT16(src);
- src += 2;
- if (firstWord != 0) {
- // Copy raw data
- memcpy(dst, src, firstWord);
- dst += firstWord;
- src += firstWord;
- assert((firstWord & 1) == 0);
- outputSamplesLeft -= firstWord / 2;
- } else {
- // Read the seed values for the decoder.
- for (i = 0; i < channels; i++) {
- initialTablePos[i] = *src;
- src += 1;
- initialimcTableEntry[i] = READ_BE_UINT32(src);
- src += 4;
- initialOutputWord[i] = READ_BE_UINT32(src);
- src += 4;
- }
- }
-
- totalBitOffset = 0;
- // The channels are encoded separately.
- for (int chan = 0; chan < channels; chan++) {
- // Read initial state (this makes it possible for the data stream
- // to be split & spread across multiple data chunks.
- curTablePos = initialTablePos[chan];
- //imcTableEntry = initialimcTableEntry[chan];
- outputWord = initialOutputWord[chan];
-
- // We need to interleave the channels in the output; we achieve
- // that by using a variables dest offset:
- destPos = chan * 2;
-
- const int bound = (channels == 1)
- ? outputSamplesLeft
- : ((chan == 0)
- ? (outputSamplesLeft+1) / 2
- : outputSamplesLeft / 2);
- for (i = 0; i < bound; ++i) {
- // Determine the size (in bits) of the next data packet
- const int32 curTableEntryBitCount = _imcTableEntryBitCount[curTablePos];
- assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7);
-
- // Read the next data packet
- const byte *readPos = src + (totalBitOffset >> 3);
- const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7));
- const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount));
-
- // Advance read position to the next data packet
- totalBitOffset += curTableEntryBitCount;
-
- // Decode the data packet into a delta value for the output signal.
- const byte signBitMask = (1 << (curTableEntryBitCount - 1));
- const byte dataBitMask = (signBitMask - 1);
- const byte data = (packet & dataBitMask);
-
- int32 delta = imcTable[curTablePos] * (2 * data + 1) >> (curTableEntryBitCount - 1);
-
- // The topmost bit in the data packet tells is a sign bit
- if ((packet & signBitMask) != 0) {
- delta = -delta;
- }
-
- // Accumulate the delta onto the output data
- outputWord += delta;
-
- // Clip outputWord to 16 bit signed, and write it into the destination stream
- if (outputWord > 0x7fff)
- outputWord = 0x7fff;
- if (outputWord < -0x8000)
- outputWord = -0x8000;
- WRITE_BE_UINT16(dst + destPos, outputWord);
- destPos += channels << 1;
-
- // Adjust the curTablePos
- curTablePos += (int8)imxOtherTable[curTableEntryBitCount - 2][data];
- if (curTablePos < 0)
- curTablePos = 0;
- else if (curTablePos >= ARRAYSIZE(imcTable))
- curTablePos = ARRAYSIZE(imcTable) - 1;
- }
- }
- }
- break;
-
- default:
- error("BundleCodecs::decompressCodec() Unknown codec %d!", (int)codec);
- output_size = 0;
- break;
- }
-
- return output_size;
-}
-
-} // End of namespace BundleCodecs
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(DimuseCodecs)
-_GSETPTR(Scumm::BundleCodecs::imcTable, GBVARS_IMCTABLE_INDEX, int16, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(DimuseCodecs)
-_GRELEASEPTR(GBVARS_IMCTABLE_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/imuse_digi/dimuse_music.cpp b/scumm/imuse_digi/dimuse_music.cpp
deleted file mode 100644
index 4c0cedc57c..0000000000
--- a/scumm/imuse_digi/dimuse_music.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-#include "scumm/scumm.h"
-#include "scumm/imuse_digi/dimuse.h"
-
-namespace Scumm {
-
-#define DIG_STATE_OFFSET 11
-#define DIG_SEQ_OFFSET (DIG_STATE_OFFSET + 65)
-#define COMI_STATE_OFFSET 3
-
-void IMuseDigital::setDigMusicState(int stateId) {
- int l, num = -1;
-
- for (l = 0; _digStateMusicTable[l].soundId != -1; l++) {
- if ((_digStateMusicTable[l].soundId == stateId)) {
- debug(5, "Set music state: %s, %s", _digStateMusicTable[l].name, _digStateMusicTable[l].filename);
- num = l;
- break;
- }
- }
-
- if (num == -1) {
- for (l = 0; _digStateMusicMap[l].roomId != -1; l++) {
- if ((_digStateMusicMap[l].roomId == stateId)) {
- break;
- }
- }
- num = l;
-
- int offset = _attributes[_digStateMusicMap[num].offset];
- if (offset == 0) {
- if (_attributes[_digStateMusicMap[num].atribPos] != 0) {
- num = _digStateMusicMap[num].stateIndex3;
- } else {
- num = _digStateMusicMap[num].stateIndex1;
- }
- } else {
- int stateIndex2 = _digStateMusicMap[num].stateIndex2;
- if (stateIndex2 == 0) {
- num = _digStateMusicMap[num].stateIndex1 + offset;
- } else {
- num = stateIndex2;
- }
- }
- }
-
- debug(5, "Set music state: %s, %s", _digStateMusicTable[num].name, _digStateMusicTable[num].filename);
-
- if (_curMusicState == num)
- return;
-
- if (_curMusicSeq == 0) {
- if (num == 0)
- playDigMusic(NULL, &_digStateMusicTable[0], num, false);
- else
- playDigMusic(_digStateMusicTable[num].name, &_digStateMusicTable[num], num, false);
- }
-
- _curMusicState = num;
-}
-
-void IMuseDigital::setDigMusicSequence(int seqId) {
- int l, num = -1;
-
- if (seqId == 0)
- seqId = 2000;
-
- for (l = 0; _digSeqMusicTable[l].soundId != -1; l++) {
- if ((_digSeqMusicTable[l].soundId == seqId)) {
- debug(5, "Set music sequence: %s, %s", _digSeqMusicTable[l].name, _digSeqMusicTable[l].filename);
- num = l;
- break;
- }
- }
-
- if (num == -1)
- return;
-
- if (_curMusicSeq == num)
- return;
-
- if (num != 0) {
- if (_curMusicSeq == 0) {
- playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true);
- _nextSeqToPlay = 0;
- _attributes[DIG_SEQ_OFFSET + num] = 1;
- } else {
- if ((_digSeqMusicTable[_curMusicSeq].opcode == 4) || (_digSeqMusicTable[_curMusicSeq].opcode == 6)) {
- _nextSeqToPlay = num;
- return;
- } else {
- playDigMusic(_digSeqMusicTable[num].name, &_digSeqMusicTable[num], 0, true);
- _nextSeqToPlay = 0;
- _attributes[DIG_SEQ_OFFSET + num] = 1;
- }
- }
- } else {
- if (_nextSeqToPlay != 0) {
- playDigMusic(_digSeqMusicTable[_nextSeqToPlay].name, &_digSeqMusicTable[_nextSeqToPlay], 0, true);
- _attributes[DIG_SEQ_OFFSET + _nextSeqToPlay] = 1;
- num = _nextSeqToPlay;
- _nextSeqToPlay = 0;
- } else {
- if (_curMusicState != 0) {
- playDigMusic(_digStateMusicTable[_curMusicState].name, &_digStateMusicTable[_curMusicState], _curMusicState, true);
- } else
- playDigMusic(NULL, &_digStateMusicTable[0], _curMusicState, true);
- num = 0;
- }
- }
-
- _curMusicSeq = num;
-}
-
-void IMuseDigital::playDigMusic(const char *songName, const imuseDigTable *table, int atribPos, bool sequence) {
- int hookId = 0;
-
- if (songName != NULL) {
- if ((_attributes[DIG_SEQ_OFFSET + 38] != 0) && (_attributes[DIG_SEQ_OFFSET + 41] == _attributes[DIG_SEQ_OFFSET + 38])) {
- if ((atribPos == 43) || (atribPos == 44))
- hookId = 3;
- }
-
- if ((_attributes[DIG_SEQ_OFFSET + 46] != 0) && (_attributes[DIG_SEQ_OFFSET + 48] == 0)) {
- if ((atribPos == 38) || (atribPos == 39))
- hookId = 3;
- }
-
- if ((_attributes[DIG_SEQ_OFFSET + 53] != 0)) {
- if ((atribPos == 50) || (atribPos == 51))
- hookId = 3;
- }
-
- if ((atribPos != 0) && (hookId == 0)) {
- if (table->atribPos != 0)
- atribPos = table->atribPos;
- hookId = _attributes[DIG_STATE_OFFSET + atribPos];
- if (table->hookId != 0) {
- if ((hookId != 0) && (table->hookId > 1)) {
- _attributes[DIG_STATE_OFFSET + atribPos] = 2;
- } else {
- _attributes[DIG_STATE_OFFSET + atribPos] = hookId + 1;
- if (table->hookId < hookId + 1)
- _attributes[DIG_STATE_OFFSET + atribPos] = 1;
- }
- }
- }
- }
-
- fadeOutMusic(120);
-
- switch(table->opcode) {
- case 0:
- case 5:
- case 6:
- break;
- case 3:
- case 4:
- if (table->filename[0] == 0) {
- return;
- }
- if ((!sequence) && (table->atribPos != 0) &&
- (table->atribPos == _digStateMusicTable[_curMusicState].atribPos)) {
- startMusic(table->filename, table->soundId, 0, 127);
- return;
- }
- startMusic(table->filename, table->soundId, hookId, 127);
- break;
- }
-}
-
-void IMuseDigital::setComiMusicState(int stateId) {
- int l, num = -1;
-
- // This happens at the beginning of Part II, but should apparently not
- // do anything since the correct music is already playing. A left-over
- // of some kind?
-
- if (stateId == 4)
- return;
-
- if (stateId == 0)
- stateId = 1000;
-
- for (l = 0; _comiStateMusicTable[l].soundId != -1; l++) {
- if ((_comiStateMusicTable[l].soundId == stateId)) {
- debug(5, "Set music state: %s, %s", _comiStateMusicTable[l].name, _comiStateMusicTable[l].filename);
- num = l;
- break;
- }
- }
- assert(num != -1);
-
- if (_curMusicState == num)
- return;
-
- if (_curMusicSeq == 0) {
- if (num == 0)
- playComiMusic(NULL, &_comiStateMusicTable[0], num, false);
- else
- playComiMusic(_comiStateMusicTable[num].name, &_comiStateMusicTable[num], num, false);
- }
-
- _curMusicState = num;
-}
-
-void IMuseDigital::setComiMusicSequence(int seqId) {
- int l, num = -1;
-
- if (seqId == 0)
- seqId = 2000;
-
- for (l = 0; _comiSeqMusicTable[l].soundId != -1; l++) {
- if ((_comiSeqMusicTable[l].soundId == seqId)) {
- debug(5, "Set music sequence: %s, %s", _comiSeqMusicTable[l].name, _comiSeqMusicTable[l].filename);
- num = l;
- break;
- }
- }
- assert(num != -1);
-
- if (_curMusicSeq == num)
- return;
-
- if (num != 0) {
- if (_curMusicSeq == 0) {
- playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true);
- _nextSeqToPlay = 0;
- } else {
- if ((_comiSeqMusicTable[_curMusicSeq].opcode == 4) || (_comiSeqMusicTable[_curMusicSeq].opcode == 6)) {
- _nextSeqToPlay = num;
- return;
- } else {
- playComiMusic(_comiSeqMusicTable[num].name, &_comiSeqMusicTable[num], 0, true);
- _nextSeqToPlay = 0;
- }
- }
- } else {
- if (_nextSeqToPlay != 0) {
- playComiMusic(_comiSeqMusicTable[_nextSeqToPlay].name, &_comiSeqMusicTable[_nextSeqToPlay], 0, true);
- num = _nextSeqToPlay;
- _nextSeqToPlay = 0;
- } else {
- if (_curMusicState != 0) {
- playComiMusic(_comiStateMusicTable[_curMusicState].name, &_comiStateMusicTable[_curMusicState], _curMusicState, true);
- } else
- playComiMusic(NULL, &_comiStateMusicTable[0], _curMusicState, true);
- num = 0;
- }
- }
-
- _curMusicSeq = num;
-}
-
-void IMuseDigital::playComiMusic(const char *songName, const imuseComiTable *table, int atribPos, bool sequence) {
- int hookId = 0;
-
- if ((songName != NULL) && (atribPos != 0)) {
- if (table->atribPos != 0)
- atribPos = table->atribPos;
- hookId = _attributes[COMI_STATE_OFFSET + atribPos];
- if (table->hookId != 0) {
- if ((hookId != 0) && (table->hookId > 1)) {
- _attributes[COMI_STATE_OFFSET + atribPos] = 2;
- } else {
- _attributes[COMI_STATE_OFFSET + atribPos] = hookId + 1;
- if (table->hookId < hookId + 1)
- _attributes[COMI_STATE_OFFSET + atribPos] = 1;
- }
- }
- }
-
- switch(table->opcode) {
- case 0:
- case 8:
- case 9:
- fadeOutMusic(120);
- break;
- case 1:
- if (table->filename[0] == 0) {
- fadeOutMusic(120);
- return;
- }
- fadeOutMusic(120);
- startMusic(table->filename, table->soundId, 0, 1);
- setFade(table->soundId, 127, 120);
- break;
- case 2:
- if (table->filename[0] == 0) {
- fadeOutMusic(60);
- return;
- }
- fadeOutMusic(table->fadeOut60TicksDelay);
- startMusic(table->filename, table->soundId, table->hookId, 127);
- break;
- case 3:
- case 4:
- case 12:
- if (table->filename[0] == 0) {
- fadeOutMusic(60);
- return;
- }
- fadeOutMusic(table->fadeOut60TicksDelay);
- if ((!sequence) && (table->atribPos != 0) &&
- (table->atribPos == _comiStateMusicTable[_curMusicState].atribPos)) {
- startMusic(table->filename, table->soundId, 0, 127);
- return;
- }
- if (table->opcode == 12) {
- startMusic(table->filename, table->soundId, table->hookId, 127);
- } else {
- startMusic(table->filename, table->soundId, hookId, 127);
- }
- break;
- }
-}
-
-void IMuseDigital::setFtMusicState(int stateId) {
- if (stateId > 48)
- return;
-
- debug(5, "State music: %s, %s", _ftStateMusicTable[stateId].name, _ftStateMusicTable[stateId].audioName);
-
- if (_curMusicState == stateId)
- return;
-
- if (_curMusicSeq == 0) {
- if (stateId == 0)
- playFtMusic(NULL, 0, 0);
- else
- playFtMusic(_ftStateMusicTable[stateId].audioName, _ftStateMusicTable[stateId].opcode, _ftStateMusicTable[stateId].volume);
- }
-
- _curMusicState = stateId;
-}
-
-void IMuseDigital::setFtMusicSequence(int seqId) {
- if (seqId > 52)
- return;
-
- debug(5, "Sequence music: %s", _ftSeqNames[seqId].name);
-
- if (_curMusicSeq == seqId)
- return;
-
- if (seqId == 0) {
- if (_curMusicState == 0)
- playFtMusic(NULL, 0, 0);
- else {
- playFtMusic(_ftStateMusicTable[_curMusicState].audioName, _ftStateMusicTable[_curMusicState].opcode, _ftStateMusicTable[_curMusicState].volume);
- }
- } else {
- int seq = (seqId - 1) * 4;
- playFtMusic(_ftSeqMusicTable[seq].audioName, _ftSeqMusicTable[seq].opcode, _ftSeqMusicTable[seq].volume);
- }
-
- _curMusicSeq = seqId;
- _curMusicCue = 0;
-}
-
-void IMuseDigital::setFtMusicCuePoint(int cueId) {
- if (cueId > 3)
- return;
-
- debug(5, "Cue point sequence: %d", cueId);
-
- if (_curMusicSeq == 0)
- return;
-
- if (_curMusicCue == cueId)
- return;
-
- if (cueId == 0)
- playFtMusic(NULL, 0, 0);
- else {
- int seq = ((_curMusicSeq - 1) * 4) + cueId;
- playFtMusic(_ftSeqMusicTable[seq].audioName, _ftSeqMusicTable[seq].opcode, _ftSeqMusicTable[seq].volume);
- }
-
- _curMusicCue = cueId;
-}
-
-void IMuseDigital::setAudioNames(int32 num, char *names) {
- free(_audioNames);
- _numAudioNames = num;
- _audioNames = names;
-}
-
-int IMuseDigital::getSoundIdByName(const char *soundName) {
- if (soundName && soundName[0] != 0) {
- for (int r = 0; r < _numAudioNames; r++) {
- if (strcmp(soundName, &_audioNames[r * 9]) == 0) {
- return r;
- }
- }
- }
-
- return -1;
-}
-
-void IMuseDigital::playFtMusic(const char *songName, int opcode, int volume) {
- fadeOutMusic(200);
-
- switch(opcode) {
- case 0:
- case 4:
- break;
- case 1:
- case 2:
- case 3:
- {
- int soundId = getSoundIdByName(songName);
- if (soundId != -1) {
- startMusic(soundId, volume);
- }
- }
- break;
- }
-}
-
-
-} // End of namespace Scumm
diff --git a/scumm/imuse_digi/dimuse_script.cpp b/scumm/imuse_digi/dimuse_script.cpp
deleted file mode 100644
index 83deb91e54..0000000000
--- a/scumm/imuse_digi/dimuse_script.cpp
+++ /dev/null
@@ -1,409 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "common/timer.h"
-
-#include "scumm/actor.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-void IMuseDigital::parseScriptCmds(int cmd, int b, int c, int d, int e, int f, int g, int h) {
- int soundId = b;
- int sub_cmd = c;
-
- if (!cmd)
- return;
-
- switch (cmd) {
- case 10: // ImuseStopAllSounds
- stopAllSounds();
- break;
- case 12: // ImuseSetParam
- switch (sub_cmd) {
- case 0x400: // select group volume
- selectVolumeGroup(soundId, d);
- break;
- case 0x500: // set priority
- setPriority(soundId, d);
- break;
- case 0x600: // set volume
- setVolume(soundId, d);
- break;
- case 0x700: // set pan
- setPan(soundId, d);
- break;
- default:
- warning("IMuseDigital::doCommand SetParam DEFAULT command %d", sub_cmd);
- break;
- }
- break;
- case 14: // ImuseFadeParam
- switch (sub_cmd) {
- case 0x600: // set volume fading
- if ((d != 0) && (e == 0))
- setVolume(soundId, d);
- else if ((d == 0) && (e == 0))
- stopSound(soundId);
- else
- setFade(soundId, d, e);
- break;
- default:
- warning("IMuseDigital::doCommand FadeParam DEFAULT sub command %d", sub_cmd);
- break;
- }
- break;
- case 25: // ImuseStartStream
- debug(5, "ImuseStartStream (%d, %d, %d)", soundId, c, d);
- break;
- case 26: // ImuseSwitchStream
- debug(5, "ImuseSwitchStream (%d, %d, %d, %d, %d)", soundId, c, d, e, f);
- break;
- case 0x1000: // ImuseSetState
- debug(5, "ImuseSetState (%d)", b);
- if ((_vm->_gameId == GID_DIG) && (_vm->_features & GF_DEMO)) {
- if (b == 1) {
- fadeOutMusic(200);
- startMusic(1, 127);
- } else {
- if (getSoundStatus(2) == 0) {
- fadeOutMusic(200);
- startMusic(2, 127);
- }
- }
- } else if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO)) {
- fadeOutMusic(120);
- if (b == 2) {
- startMusic("in1.imx", 1100, 0, 127);
- } else if (b == 4) {
- startMusic("in2.imx", 1120, 0, 127);
- } else if (b == 8) {
- startMusic("out1.imx", 1140, 0, 127);
- } else if (b == 9) {
- startMusic("out2.imx", 1150, 0, 127);
- } else if (b == 16) {
- startMusic("gun.imx", 1210, 0, 127);
- } else {
- warning("imuse digital: set state unknown for cmi demo: %d, room: %d", b, _vm->_currentRoom);
- }
- } else if (_vm->_gameId == GID_DIG) {
- setDigMusicState(b);
- } else if (_vm->_gameId == GID_CMI) {
- setComiMusicState(b);
- } else if (_vm->_gameId == GID_FT) {
- setFtMusicState(b);
- }
- break;
- case 0x1001: // ImuseSetSequence
- debug(5, "ImuseSetSequence (%d)", b);
- if (_vm->_gameId == GID_DIG) {
- setDigMusicSequence(b);
- } else if (_vm->_gameId == GID_CMI) {
- setComiMusicSequence(b);
- } else if (_vm->_gameId == GID_FT) {
- setFtMusicSequence(b);
- }
- break;
- case 0x1002: // ImuseSetCuePoint
- debug(5, "ImuseSetCuePoint (%d)", b);
- if (_vm->_gameId == GID_FT) {
- setFtMusicCuePoint(b);
- }
- break;
- case 0x1003: // ImuseSetAttribute
- debug(5, "ImuseSetAttribute (%d, %d)", b, c);
- assert((_vm->_gameId == GID_DIG) || (_vm->_gameId == GID_FT));
- if (_vm->_gameId == GID_DIG) {
- _attributes[b] = c;
- }
- break;
- case 0x2000: // ImuseSetGroupSfxVolume
- debug(5, "ImuseSetGroupSFXVolume (%d)", b);
-// setGroupSfxVolume(b);
- break;
- case 0x2001: // ImuseSetGroupVoiceVolume
- debug(5, "ImuseSetGroupVoiceVolume (%d)", b);
-// setGroupVoiceVolume(b);
- break;
- case 0x2002: // ImuseSetGroupMusicVolume
- debug(5, "ImuseSetGroupMusicVolume (%d)", b);
-// setGroupMusicVolume(b);
- break;
- default:
- error("IMuseDigital::doCommand DEFAULT command %d", cmd);
- }
-}
-
-void IMuseDigital::flushTracks() {
- Common::StackLock lock(_mutex, "IMuseDigital::flushTracks()");
- debug(5, "flushTracks()");
- for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
- Track *track = _track[l];
- if (track->used && (track->readyToRemove ||
- (_vm->_insaneRunning && track->toBeRemoved))) { // INSANE hack for sync timer mode
- if (track->stream) {
- if (!track->stream->endOfStream()) {
- track->stream->finish();
- }
- if (track->stream->endOfStream()
- || _vm->_mixer->isPaused() // hack for paused Mixer
- || _vm->_insaneRunning) { // INSANE hack for sync timer mode
- _vm->_mixer->stopHandle(track->handle);
- delete track->stream;
- track->stream = NULL;
- _sound->closeSound(track->soundHandle);
- track->soundHandle = NULL;
- track->used = false;
- }
- } else if (track->stream2) {
- _vm->_mixer->stopHandle(track->handle);
- delete track->stream2;
- track->stream2 = NULL;
- track->used = false;
- }
- }
- }
-}
-
-void IMuseDigital::refreshScripts() {
- Common::StackLock lock(_mutex, "IMuseDigital::refreshScripts()");
- debug(5, "refreshScripts()");
- bool found = false;
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- found = true;
- }
- }
-
- if (!found && (_curMusicSeq != 0)) {
- debug(5, "refreshScripts() Start Sequence");
- parseScriptCmds(0x1001, 0, 0, 0, 0, 0, 0, 0);
- }
-}
-
-void IMuseDigital::startVoice(int soundId, AudioStream *input) {
- debug(5, "startVoiceStream(%d)", soundId);
- startSound(soundId, "", 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);
-}
-
-void IMuseDigital::startVoice(int soundId, const char *soundName) {
- debug(5, "startVoiceBundle(%s)", soundName);
- startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_VOICE, NULL, 0, 127, 127);
-}
-
-void IMuseDigital::startMusic(int soundId, int volume) {
- debug(5, "startMusicResource(%d)", soundId);
- startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);
-}
-
-void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, int volume) {
- debug(5, "startMusicBundle(%s)", soundName);
- startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_MUSIC, NULL, hookId, volume, 126);
-}
-
-void IMuseDigital::startSfx(int soundId, int priority) {
- debug(5, "startSfx(%d)", soundId);
- startSound(soundId, "", IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);
-}
-
-void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
- int32 sync_size;
- byte *sync_ptr;
-
- msPos /= 16;
- if (msPos < 65536) {
- Common::StackLock lock(_mutex, "IMuseDigital::getLipSync()");
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- _sound->getSyncSizeAndPtrById(track->soundHandle, syncId, sync_size, &sync_ptr);
- if ((sync_size != 0) && (sync_ptr != NULL)) {
- sync_size /= 4;
- while (sync_size--) {
- if (READ_BE_UINT16(sync_ptr) >= msPos)
- break;
- sync_ptr += 4;
- }
- if (sync_size < 0)
- sync_ptr -= 4;
- else
- if (READ_BE_UINT16(sync_ptr) > msPos)
- sync_ptr -= 4;
-
- width = sync_ptr[2];
- height = sync_ptr[3];
- return;
- }
- }
- }
- }
-}
-
-int32 IMuseDigital::getPosInMs(int soundId) {
- Common::StackLock lock(_mutex, "IMuseDigital::getPosInMs()");
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- int32 pos = (5 * (track->dataOffset + track->regionOffset)) / (track->iteration / 200);
- return pos;
- }
- }
-
- return 0;
-}
-
-int IMuseDigital::getSoundStatus(int sound) const {
- Common::StackLock lock(_mutex, "IMuseDigital::getSoundStatus()");
- debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->soundId == sound) {
- if ((track->stream2 && _vm->_mixer->isSoundHandleActive(track->handle)) ||
- (track->stream && track->used && !track->readyToRemove)) {
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-void IMuseDigital::stopSound(int soundId) {
- Common::StackLock lock(_mutex, "IMuseDigital::stopSound()");
- debug(5, "IMuseDigital::stopSound(%d)", soundId);
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->toBeRemoved = true;
- }
- }
-}
-
-int32 IMuseDigital::getCurMusicPosInMs() {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicPosInMs()");
- int soundId = -1;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- soundId = track->soundId;
- }
- }
-
- int32 msPos = getPosInMs(soundId);
- debug(5, "IMuseDigital::getCurMusicPosInMs(%d) = %d", soundId, msPos);
- return msPos;
-}
-
-int32 IMuseDigital::getCurVoiceLipSyncWidth() {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurVoiceLipSyncWidth()");
- int32 msPos = getPosInMs(kTalkSoundID) + 50;
- int32 width = 0, height = 0;
-
- debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d)", kTalkSoundID);
- getLipSync(kTalkSoundID, 0, msPos, width, height);
- return width;
-}
-
-int32 IMuseDigital::getCurVoiceLipSyncHeight() {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurVoiceLipSyncHeight()");
- int32 msPos = getPosInMs(kTalkSoundID) + 50;
- int32 width = 0, height = 0;
-
- debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d)", kTalkSoundID);
- getLipSync(kTalkSoundID, 0, msPos, width, height);
- return height;
-}
-
-int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicLipSyncWidth()");
- int soundId = -1;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- soundId = track->soundId;
- }
- }
-
- int32 msPos = getPosInMs(soundId) + 50;
- int32 width = 0, height = 0;
-
- debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d, %d)", soundId, msPos);
- getLipSync(soundId, syncId, msPos, width, height);
- return width;
-}
-
-int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicLipSyncHeight()");
- int soundId = -1;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- soundId = track->soundId;
- }
- }
-
- int32 msPos = getPosInMs(soundId) + 50;
- int32 width = 0, height = 0;
-
- debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d, %d)", soundId, msPos);
- getLipSync(soundId, syncId, msPos, width, height);
- return height;
-}
-
-void IMuseDigital::stopAllSounds() {
- debug(5, "IMuseDigital::stopAllSounds");
-
- for (;;) {
- bool foundNotRemoved = false;
- for (int l = 0; l < MAX_DIGITAL_TRACKS + MAX_DIGITAL_FADETRACKS; l++) {
- Track *track = _track[l];
- if (track->used) {
- track->toBeRemoved = true;
- foundNotRemoved = true;
- }
- }
- if (!foundNotRemoved)
- break;
- flushTracks();
- _vm->_system->delayMillis(50);
-#if defined(_WIN32_WCE) || defined (PALMOS_MODE) || defined(__SYMBIAN32__)
- _vm->parseEvents(); // timers are events, we need to consume them
-#endif
- }
-}
-
-void IMuseDigital::pause(bool p) {
- _pause = p;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/imuse_digi/dimuse_sndmgr.cpp b/scumm/imuse_digi/dimuse_sndmgr.cpp
deleted file mode 100644
index 7d3d06f16e..0000000000
--- a/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ /dev/null
@@ -1,625 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-#include "common/util.h"
-
-#include "sound/voc.h"
-#include "sound/vorbis.h"
-#include "sound/mp3.h"
-
-#include "scumm/scumm.h"
-#include "scumm/util.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_sndmgr.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-
-namespace Scumm {
-
-ImuseDigiSndMgr::ImuseDigiSndMgr(ScummEngine *scumm) {
- for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- memset(&_sounds[l], 0, sizeof(soundStruct));
- }
- _vm = scumm;
- _disk = 0;
- _cacheBundleDir = new BundleDirCache();
- BundleCodecs::initializeImcTables();
-}
-
-ImuseDigiSndMgr::~ImuseDigiSndMgr() {
- for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- closeSound(&_sounds[l]);
- }
-
- delete _cacheBundleDir;
-}
-
-void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs) {
- uint32 tag;
- int32 size = 0;
-
- do {
- tag = READ_BE_UINT32(ptr); ptr += 4;
- switch(tag) {
- case MKID_BE('TEXT'):
- case MKID_BE('STOP'):
- case MKID_BE('FRMT'):
- case MKID_BE('DATA'):
- size = READ_BE_UINT32(ptr); ptr += size + 4;
- break;
- case MKID_BE('REGN'):
- numRegions++;
- size = READ_BE_UINT32(ptr); ptr += size + 4;
- break;
- case MKID_BE('JUMP'):
- numJumps++;
- size = READ_BE_UINT32(ptr); ptr += size + 4;
- break;
- case MKID_BE('SYNC'):
- numSyncs++;
- size = READ_BE_UINT32(ptr); ptr += size + 4;
- break;
- default:
- error("ImuseDigiSndMgr::countElements() Unknown sfx header '%s'", tag2str(tag));
- }
- } while (tag != MKID_BE('DATA'));
-}
-
-void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::File *file, soundStruct *sound, int32 offset, int32 size) {
- int l;
-
- file->seek(offset, SEEK_SET);
- uint32 tag = file->readUint32BE();
- assert(tag == 'RMAP');
- int32 version = file->readUint32BE();
- if (version != 2) {
- error("ImuseDigiSndMgr::prepareSoundFromRMAP: Wrong version number, expected 2, but it's: %d.", version);
- }
- sound->bits = file->readUint32BE();
- sound->freq = file->readUint32BE();
- sound->channels = file->readUint32BE();
- sound->numRegions = file->readUint32BE();
- sound->numJumps = file->readUint32BE();
- sound->numSyncs = file->readUint32BE();
- sound->region = (_region *)malloc(sizeof(_region) * sound->numRegions);
- sound->jump = (_jump *)malloc(sizeof(_jump) * sound->numJumps);
- sound->sync = (_sync *)malloc(sizeof(_sync) * sound->numSyncs);
- for (l = 0; l < sound->numRegions; l++) {
- sound->region[l].offset = file->readUint32BE();
- sound->region[l].length = file->readUint32BE();
- }
- for (l = 0; l < sound->numJumps; l++) {
- sound->jump[l].offset = file->readUint32BE();
- sound->jump[l].dest = file->readUint32BE();
- sound->jump[l].hookId = file->readUint32BE();
- sound->jump[l].fadeDelay = file->readUint32BE();
- }
- for (l = 0; l < sound->numSyncs; l++) {
- sound->sync[l].size = file->readUint32BE();
- sound->sync[l].ptr = (byte *)malloc(sound->sync[l].size);
- file->read(sound->sync[l].ptr, sound->sync[l].size);
- }
-}
-
-void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
- if (READ_UINT32(ptr) == MKID('Crea')) {
- bool quit = false;
- int len;
-
- int32 offset = READ_LE_UINT16(ptr + 20);
- int16 code = READ_LE_UINT16(ptr + 24);
-
- sound->region = (_region *)malloc(sizeof(_region) * 70);
- sound->jump = (_jump *)malloc(sizeof(_jump));
- sound->resPtr = ptr;
- sound->bits = 8;
- sound->channels = 1;
-
- while (!quit) {
- len = READ_LE_UINT32(ptr + offset);
- code = len & 0xFF;
- if ((code != 0) && (code != 1) && (code != 6) && (code != 7)) {
- // try again with 2 bytes forward (workaround for some FT sounds (ex.362, 363)
- offset += 2;
- len = READ_LE_UINT32(ptr + offset);
- code = len & 0xFF;
- if ((code != 0) && (code != 1) && (code != 6) && (code != 7)) {
- error("Invalid code in VOC file : %d", code);
- }
- }
- offset += 4;
- len >>= 8;
- switch(code) {
- case 0:
- quit = true;
- break;
- case 1:
- {
- int time_constant = ptr[offset];
- offset += 2;
- len -= 2;
- sound->freq = getSampleRateFromVOCRate(time_constant);
- sound->region[sound->numRegions].offset = offset;
- sound->region[sound->numRegions].length = len;
- sound->numRegions++;
- }
- break;
- case 6: // begin of loop
- sound->jump[0].dest = offset + 8;
- sound->jump[0].hookId = 0;
- sound->jump[0].fadeDelay = 0;
- break;
- case 7: // end of loop
- sound->jump[0].offset = offset - 4;
- sound->numJumps++;
- sound->region[sound->numRegions].offset = offset - 4;
- sound->region[sound->numRegions].length = 0;
- sound->numRegions++;
- break;
- default:
- error("Invalid code in VOC file : %d", code);
- quit = true;
- break;
- }
- offset += len;
- }
- } else if (READ_UINT32(ptr) == MKID('iMUS')) {
- uint32 tag;
- int32 size = 0;
- byte *s_ptr = ptr;
- ptr += 16;
-
- int curIndexRegion = 0;
- int curIndexJump = 0;
- int curIndexSync = 0;
-
- sound->numRegions = 0;
- sound->numJumps = 0;
- sound->numSyncs = 0;
- countElements(ptr, sound->numRegions, sound->numJumps, sound->numSyncs);
- sound->region = (_region *)malloc(sizeof(_region) * sound->numRegions);
- sound->jump = (_jump *)malloc(sizeof(_jump) * sound->numJumps);
- sound->sync = (_sync *)malloc(sizeof(_sync) * sound->numSyncs);
-
- do {
- tag = READ_BE_UINT32(ptr); ptr += 4;
- switch(tag) {
- case MKID_BE('FRMT'):
- ptr += 12;
- sound->bits = READ_BE_UINT32(ptr); ptr += 4;
- sound->freq = READ_BE_UINT32(ptr); ptr += 4;
- sound->channels = READ_BE_UINT32(ptr); ptr += 4;
- break;
- case MKID_BE('TEXT'):
- case MKID_BE('STOP'):
- size = READ_BE_UINT32(ptr); ptr += size + 4;
- break;
- case MKID_BE('REGN'):
- ptr += 4;
- sound->region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4;
- sound->region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4;
- curIndexRegion++;
- break;
- case MKID_BE('JUMP'):
- ptr += 4;
- sound->jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4;
- sound->jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4;
- sound->jump[curIndexJump].hookId = READ_BE_UINT32(ptr); ptr += 4;
- sound->jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4;
- curIndexJump++;
- break;
- case MKID_BE('SYNC'):
- size = READ_BE_UINT32(ptr); ptr += 4;
- sound->sync[curIndexSync].size = size;
- sound->sync[curIndexSync].ptr = (byte *)malloc(size);
- memcpy(sound->sync[curIndexSync].ptr, ptr, size);
- curIndexSync++;
- ptr += size;
- break;
- case MKID_BE('DATA'):
- ptr += 4;
- break;
- default:
- error("ImuseDigiSndMgr::prepareSound(%d/%s) Unknown sfx header '%s'", sound->soundId, sound->name, tag2str(tag));
- }
- } while (tag != MKID_BE('DATA'));
- sound->offsetData = ptr - s_ptr;
- } else {
- error("ImuseDigiSndMgr::prepareSound(): Unknown sound format");
- }
-}
-
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::allocSlot() {
- for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- if (!_sounds[l].inUse) {
- _sounds[l].inUse = true;
- return &_sounds[l];
- }
- }
-
- return NULL;
-}
-
-bool ImuseDigiSndMgr::openMusicBundle(soundStruct *sound, int disk) {
- bool result = false;
-
- sound->bundle = new BundleMgr(_cacheBundleDir);
- if (_vm->_gameId == GID_CMI) {
- if (_vm->_features & GF_DEMO) {
- result = sound->bundle->open("music.bun", sound->compressed);
- } else {
- char musicfile[20];
- if (disk == -1)
- disk = _vm->VAR(_vm->VAR_CURRENTDISK);
- sprintf(musicfile, "musdisk%d.bun", disk);
-// if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
-// _vm->_imuseDigital->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
-// _vm->_imuseDigital->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
-// _vm->_imuseDigital->stopAllSounds();
-// sound->bundle->closeFile();
-// }
-
- result = sound->bundle->open(musicfile, sound->compressed, true);
-
- // FIXME: Shouldn't we only set _disk if result == true?
- _disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
- }
- } else if (_vm->_gameId == GID_DIG)
- result = sound->bundle->open("digmusic.bun", sound->compressed, true);
- else
- error("ImuseDigiSndMgr::openMusicBundle() Don't know which bundle file to load");
-
- _vm->VAR(_vm->VAR_MUSIC_BUNDLE_LOADED) = result ? 1 : 0;
-
- return result;
-}
-
-bool ImuseDigiSndMgr::openVoiceBundle(soundStruct *sound, int disk) {
- bool result = false;
-
- sound->bundle = new BundleMgr(_cacheBundleDir);
- if (_vm->_gameId == GID_CMI) {
- if (_vm->_features & GF_DEMO) {
- result = sound->bundle->open("voice.bun", sound->compressed);
- } else {
- char voxfile[20];
- if (disk == -1)
- disk = _vm->VAR(_vm->VAR_CURRENTDISK);
- sprintf(voxfile, "voxdisk%d.bun", disk);
-// if (_disk != _vm->VAR(_vm->VAR_CURRENTDISK)) {
-// _vm->_imuseDigital->parseScriptCmds(0x1000, 0, 0, 0, 0, 0, 0, 0);
-// _vm->_imuseDigital->parseScriptCmds(0x2000, 0, 0, 0, 0, 0, 0, 0);
-// _vm->_imuseDigital->stopAllSounds();
-// sound->bundle->closeFile();
-// }
-
- result = sound->bundle->open(voxfile, sound->compressed);
-
- // FIXME: Shouldn't we only set _disk if result == true?
- _disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
- }
- } else if (_vm->_gameId == GID_DIG)
- result = sound->bundle->open("digvoice.bun", sound->compressed);
- else
- error("ImuseDigiSndMgr::openVoiceBundle() Don't know which bundle file to load");
-
- _vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = result ? 1 : 0;
-
- return result;
-}
-
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk) {
- assert(soundId >= 0);
- assert(soundType);
-
- soundStruct *sound = allocSlot();
- if (!sound) {
- error("ImuseDigiSndMgr::openSound() can't alloc free sound slot");
- }
-
- const bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
- bool result = false;
- byte *ptr = NULL;
-
- switch (soundType) {
- case IMUSE_RESOURCE:
- assert(soundName[0] == 0); // Paranoia check
-
- _vm->ensureResourceLoaded(rtSound, soundId);
- _vm->res.lock(rtSound, soundId);
- ptr = _vm->getResourceAddress(rtSound, soundId);
- if (ptr == NULL) {
- closeSound(sound);
- return NULL;
- }
- sound->resPtr = ptr;
- break;
- case IMUSE_BUNDLE:
- if (volGroupId == IMUSE_VOLGRP_VOICE)
- result = openVoiceBundle(sound, disk);
- else if (volGroupId == IMUSE_VOLGRP_MUSIC)
- result = openMusicBundle(sound, disk);
- else
- error("ImuseDigiSndMgr::openSound() Don't know how load sound: %d", soundId);
- if (!result) {
- closeSound(sound);
- return NULL;
- }
- if (sound->compressed) {
- char fileName[24];
- int32 offset = 0, size = 0;
- sprintf(fileName, "%s.map", soundName);
- Common::File *rmapFile = sound->bundle->getFile(fileName, offset, size);
- if (!rmapFile) {
- closeSound(sound);
- return NULL;
- }
- prepareSoundFromRMAP(rmapFile, sound, offset, size);
- strcpy(sound->name, soundName);
- sound->soundId = soundId;
- sound->type = soundType;
- sound->volGroupId = volGroupId;
- sound->disk = _disk;
- return sound;
- } else if (soundName[0] == 0) {
- if (sound->bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside) == 0 || ptr == NULL) {
- closeSound(sound);
- return NULL;
- }
- } else {
- if (sound->bundle->decompressSampleByName(soundName, 0, 0x2000, &ptr, header_outside) == 0 || ptr == NULL) {
- closeSound(sound);
- return NULL;
- }
- }
- sound->resPtr = 0;
- break;
- default:
- error("ImuseDigiSndMgr::openSound() Unknown soundType %d (trying to load sound %d)", soundType, soundId);
- }
-
- strcpy(sound->name, soundName);
- sound->soundId = soundId;
- sound->type = soundType;
- sound->volGroupId = volGroupId;
- sound->disk = _disk;
- prepareSound(ptr, sound);
- if ((soundType == IMUSE_BUNDLE) && !sound->compressed) {
- free(ptr);
- }
- return sound;
-}
-
-void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
-
- if (soundHandle->resPtr) {
- bool found = false;
- for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- if ((_sounds[l].soundId == soundHandle->soundId) && (&_sounds[l] != soundHandle))
- found = true;
- }
- if (!found)
- _vm->res.unlock(rtSound, soundHandle->soundId);
- }
-
- if (soundHandle->compressedStream)
- delete soundHandle->compressedStream;
-
- delete soundHandle->bundle;
-
- for (int r = 0; r < soundHandle->numSyncs; r++)
- free(soundHandle->sync[r].ptr);
- free(soundHandle->region);
- free(soundHandle->jump);
- free(soundHandle->sync);
- memset(soundHandle, 0, sizeof(soundStruct));
-}
-
-ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::cloneSound(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
-
- return openSound(soundHandle->soundId, soundHandle->name, soundHandle->type, soundHandle->volGroupId, soundHandle->disk);
-}
-
-bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {
- if (!soundHandle)
- return false;
- for (int l = 0; l < MAX_IMUSE_SOUNDS; l++) {
- if (soundHandle == &_sounds[l])
- return true;
- }
- return false;
-}
-
-bool ImuseDigiSndMgr::isCompressed(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->compressed;
-}
-
-int ImuseDigiSndMgr::getFreq(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->freq;
-}
-
-int ImuseDigiSndMgr::getBits(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->bits;
-}
-
-int ImuseDigiSndMgr::getChannels(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->channels;
-}
-
-bool ImuseDigiSndMgr::isEndOfRegion(soundStruct *soundHandle, int region) {
- assert(checkForProperHandle(soundHandle));
- assert(region >= 0 && region < soundHandle->numRegions);
- return soundHandle->endFlag;
-}
-
-int ImuseDigiSndMgr::getNumRegions(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->numRegions;
-}
-
-int ImuseDigiSndMgr::getNumJumps(soundStruct *soundHandle) {
- assert(checkForProperHandle(soundHandle));
- return soundHandle->numJumps;
-}
-
-int ImuseDigiSndMgr::getRegionOffset(soundStruct *soundHandle, int region) {
- debug(5, "getRegionOffset() region:%d", region);
- assert(checkForProperHandle(soundHandle));
- assert(region >= 0 && region < soundHandle->numRegions);
- return soundHandle->region[region].offset;
-}
-
-int ImuseDigiSndMgr::getJumpIdByRegionAndHookId(soundStruct *soundHandle, int region, int hookId) {
- debug(5, "getJumpIdByRegionAndHookId() region:%d, hookId:%d", region, hookId);
- assert(checkForProperHandle(soundHandle));
- assert(region >= 0 && region < soundHandle->numRegions);
- int32 offset = soundHandle->region[region].offset;
- for (int l = 0; l < soundHandle->numJumps; l++) {
- if (offset == soundHandle->jump[l].offset) {
- if (soundHandle->jump[l].hookId == hookId)
- return l;
- }
- }
-
- return -1;
-}
-
-void ImuseDigiSndMgr::getSyncSizeAndPtrById(soundStruct *soundHandle, int number, int32 &sync_size, byte **sync_ptr) {
- assert(checkForProperHandle(soundHandle));
- assert(number >= 0);
- if (number < soundHandle->numSyncs) {
- sync_size = soundHandle->sync[number].size;
- *sync_ptr = soundHandle->sync[number].ptr;
- } else {
- sync_size = 0;
- *sync_ptr = NULL;
- }
-}
-
-int ImuseDigiSndMgr::getRegionIdByJumpId(soundStruct *soundHandle, int jumpId) {
- debug(5, "getRegionIdByJumpId() jumpId:%d", jumpId);
- assert(checkForProperHandle(soundHandle));
- assert(jumpId >= 0 && jumpId < soundHandle->numJumps);
- int32 dest = soundHandle->jump[jumpId].dest;
- for (int l = 0; l < soundHandle->numRegions; l++) {
- if (dest == soundHandle->region[l].offset) {
- return l;
- }
- }
-
- return -1;
-}
-
-int ImuseDigiSndMgr::getJumpHookId(soundStruct *soundHandle, int number) {
- debug(5, "getJumpHookId() number:%d", number);
- assert(checkForProperHandle(soundHandle));
- assert(number >= 0 && number < soundHandle->numJumps);
- return soundHandle->jump[number].hookId;
-}
-
-int ImuseDigiSndMgr::getJumpFade(soundStruct *soundHandle, int number) {
- debug(5, "getJumpFade() number:%d", number);
- assert(checkForProperHandle(soundHandle));
- assert(number >= 0 && number < soundHandle->numJumps);
- return soundHandle->jump[number].fadeDelay;
-}
-
-int32 ImuseDigiSndMgr::getDataFromRegion(soundStruct *soundHandle, int region, byte **buf, int32 offset, int32 size) {
- debug(5, "getDataFromRegion() region:%d, offset:%d, size:%d, numRegions:%d", region, offset, size, soundHandle->numRegions);
- assert(checkForProperHandle(soundHandle));
- assert(buf && offset >= 0 && size >= 0);
- assert(region >= 0 && region < soundHandle->numRegions);
-
- int32 region_offset = soundHandle->region[region].offset;
- int32 region_length = soundHandle->region[region].length;
- int32 offset_data = soundHandle->offsetData;
- int32 start = region_offset - offset_data;
-
- if (offset + size + offset_data > region_length) {
- size = region_length - offset;
- soundHandle->endFlag = true;
- } else {
- soundHandle->endFlag = false;
- }
-
- int header_size = soundHandle->offsetData;
- bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
- if ((soundHandle->bundle) && (!soundHandle->compressed)) {
- size = soundHandle->bundle->decompressSampleByCurIndex(start + offset, size, buf, header_size, header_outside);
- } else if (soundHandle->resPtr) {
- *buf = (byte *)malloc(size);
- memcpy(*buf, soundHandle->resPtr + start + offset + header_size, size);
- } else if ((soundHandle->bundle) && (soundHandle->compressed)) {
- *buf = (byte *)malloc(size);
- char fileName[24];
- sprintf(fileName, "%s_reg%03d", soundHandle->name, region);
- if (scumm_stricmp(fileName, soundHandle->lastFileName) != 0) {
- int32 offs = 0, len = 0;
- Common::File *cmpFile;
- bool oggMode = false;
- sprintf(fileName, "%s_reg%03d.mp3", soundHandle->name, region);
- cmpFile = soundHandle->bundle->getFile(fileName, offs, len);
-#ifndef USE_MAD
- if (len)
- error("Mad library compiled support needed!");
-#endif
- if (!len) {
- sprintf(fileName, "%s_reg%03d.ogg", soundHandle->name, region);
- cmpFile = soundHandle->bundle->getFile(fileName, offs, len);
-#ifndef USE_VORBIS
- if (len)
- error("Vorbis library compiled support needed!");
-#endif
- assert(len);
- oggMode = true;
- }
- if (!soundHandle->compressedStream) {
-#ifdef USE_VORBIS
- if (oggMode)
- soundHandle->compressedStream = makeVorbisStream(cmpFile, len);
-#endif
-#ifdef USE_MAD
- if (!oggMode)
- soundHandle->compressedStream = makeMP3Stream(cmpFile, len);
-#endif
- assert(soundHandle->compressedStream);
- }
- strcpy(soundHandle->lastFileName, fileName);
- }
- size = soundHandle->compressedStream->readBuffer((int16 *)*buf, size / 2) * 2;
- if (soundHandle->compressedStream->endOfData()) {
- delete soundHandle->compressedStream;
- soundHandle->compressedStream = NULL;
- soundHandle->lastFileName[0] = 0;
- }
- }
-
- return size;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/imuse_digi/dimuse_sndmgr.h b/scumm/imuse_digi/dimuse_sndmgr.h
deleted file mode 100644
index 5844fa0c1b..0000000000
--- a/scumm/imuse_digi/dimuse_sndmgr.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef IMUSE_DIGI_SNDMGR_H
-#define IMUSE_DIGI_SNDMGR_H
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-#include "sound/audiostream.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-
-namespace Scumm {
-
-class ScummEngine;
-class BundleMgr;
-
-class ImuseDigiSndMgr {
-public:
-
-#define MAX_IMUSE_SOUNDS 16
-
-#define IMUSE_RESOURCE 1
-#define IMUSE_BUNDLE 2
-
-#define IMUSE_VOLGRP_VOICE 1
-#define IMUSE_VOLGRP_SFX 2
-#define IMUSE_VOLGRP_MUSIC 3
-
-private:
- struct _region {
- int32 offset; // offset of region
- int32 length; // lenght of region
- };
-
- struct _jump {
- int32 offset; // jump offset position
- int32 dest; // jump to dest position
- byte hookId; // id of hook
- int16 fadeDelay; // fade delay in ms
- };
-
- struct _sync {
- int32 size; // size of sync
- byte *ptr; // pointer to sync
- };
-
-public:
-
- struct soundStruct {
- uint16 freq; // frequency
- byte channels; // stereo or mono
- byte bits; // 8, 12, 16
- int numJumps; // number of Jumps
- int numRegions; // number of Regions
- int numSyncs; // number of Syncs
- _region *region;
- _jump *jump;
- _sync *sync;
- bool endFlag;
- bool inUse;
- byte *allData;
- int32 offsetData;
- byte *resPtr;
- char name[15];
- int16 soundId;
- BundleMgr *bundle;
- int type;
- int volGroupId;
- int disk;
- AudioStream *compressedStream;
- bool compressed;
- char lastFileName[24];
- };
-
-private:
-
- soundStruct _sounds[MAX_IMUSE_SOUNDS];
-
- bool checkForProperHandle(soundStruct *soundHandle);
- soundStruct *allocSlot();
- void prepareSound(byte *ptr, soundStruct *sound);
- void prepareSoundFromRMAP(Common::File *file, soundStruct *sound, int32 offset, int32 size);
-
- ScummEngine *_vm;
- byte _disk;
- BundleDirCache *_cacheBundleDir;
-
- bool openMusicBundle(soundStruct *sound, int disk);
- bool openVoiceBundle(soundStruct *sound, int disk);
-
- void countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs);
-
-public:
-
- ImuseDigiSndMgr(ScummEngine *scumm);
- ~ImuseDigiSndMgr();
-
- soundStruct *openSound(int32 soundId, const char *soundName, int soundType, int volGroupId, int disk);
- void closeSound(soundStruct *soundHandle);
- soundStruct *cloneSound(soundStruct *soundHandle);
-
- bool isCompressed(soundStruct *soundHandle);
- int getFreq(soundStruct *soundHandle);
- int getBits(soundStruct *soundHandle);
- int getChannels(soundStruct *soundHandle);
- bool isEndOfRegion(soundStruct *soundHandle, int region);
- int getNumRegions(soundStruct *soundHandle);
- int getNumJumps(soundStruct *soundHandle);
- int getRegionOffset(soundStruct *soundHandle, int region);
- int getJumpIdByRegionAndHookId(soundStruct *soundHandle, int region, int hookId);
- int getRegionIdByJumpId(soundStruct *soundHandle, int jumpId);
- int getJumpHookId(soundStruct *soundHandle, int number);
- int getJumpFade(soundStruct *soundHandle, int number);
- void getSyncSizeAndPtrById(soundStruct *soundHandle, int number, int32 &sync_size, byte **sync_ptr);
-
- int32 getDataFromRegion(soundStruct *soundHandle, int region, byte **buf, int32 offset, int32 size);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/imuse_digi/dimuse_tables.cpp b/scumm/imuse_digi/dimuse_tables.cpp
deleted file mode 100644
index f4fd25a160..0000000000
--- a/scumm/imuse_digi/dimuse_tables.cpp
+++ /dev/null
@@ -1,881 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "scumm/imuse_digi/dimuse.h"
-
-namespace Scumm {
-
-#ifdef PALMOS_68K
-const imuseRoomMap *_digStateMusicMap;
-const imuseDigTable *_digStateMusicTable;
-const imuseDigTable *_digSeqMusicTable;
-const imuseComiTable *_comiStateMusicTable;
-const imuseComiTable *_comiSeqMusicTable;
-const imuseFtStateTable *_ftStateMusicTable;
-const imuseFtSeqTable *_ftSeqMusicTable;
-const imuseFtNames *_ftSeqNames;
-#else
-const imuseRoomMap _digStateMusicMap[] = {
- {0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0 },
- {2, 2, 0, 0, 0, 0 },
- {4, 3, 0, 0, 0, 0 },
- {5, 3, 0, 0, 0, 0 },
- {6, 3, 0, 0, 0, 0 },
- {7, 3, 0, 0, 0, 0 },
- {8, 4, 0, 0, 0, 0 },
- {9, 5, 0, 0, 0, 0 },
- {10, 4, 0, 0, 0, 0 },
- {12, 5, 0, 0, 0, 0 },
- {14, 5, 0, 0, 0, 0 },
- {15, 6, 29, 7, 0, 0 },
- {16, 8, 0, 0, 0, 0 },
- {17, 1, 0, 0, 0, 0 },
- {18, 9, 0, 0, 0, 0 },
- {19, 9, 0, 0, 0, 0 },
- {20, 6, 0, 0, 0, 0 },
- {21, 6, 0, 0, 0, 0 },
- {22, 44, 0, 0, 0, 0 },
- {23, 10, 7, 0, 0, 0 },
- {24, 26, 0, 0, 0, 0 },
- {25, 17, 0, 0, 0, 0 },
- {26, 17, 0, 0, 0, 0 },
- {27, 18, 0, 0, 0, 0 },
- {28, 1, 0, 0, 0, 0 },
- {29, 20, 0, 0, 0, 0 },
- {30, 22, 0, 0, 0, 0 },
- {31, 23, 0, 0, 0, 0 },
- {32, 22, 0, 0, 0, 0 },
- {33, 26, 0, 0, 0, 0 },
- {34, 24, 0, 0, 0, 0 },
- {35, 1, 0, 0, 0, 0 },
- {36, 1, 0, 0, 0, 0 },
- {37, 42, 0, 0, 0, 0 },
- {38, 43, 0, 0, 0, 0 },
- {39, 44, 0, 0, 0, 0 },
- {40, 1, 0, 0, 0, 0 },
- {41, 43, 0, 0, 0, 0 },
- {42, 44, 0, 0, 0, 0 },
- {43, 43, 0, 0, 0, 0 },
- {44, 45, 117,45, 114,46},
- {47, 1, 0, 0, 0, 0 },
- {48, 43, 0, 0, 0, 0 },
- {49, 44, 0, 0, 0, 0 },
- {51, 1, 0, 0, 0, 0 },
- {53, 28, 0, 0, 0, 0 },
- {54, 28, 0, 0, 0, 0 },
- {55, 29, 0, 0, 0, 0 },
- {56, 29, 0, 0, 0, 0 },
- {57, 29, 0, 0, 0, 0 },
- {58, 31, 0, 0, 0, 0 },
- {59, 1, 0, 0, 0, 0 },
- {60, 37, 0, 0, 0, 0 },
- {61, 39, 0, 0, 0, 0 },
- {62, 38, 0, 0, 0, 0 },
- {63, 39, 0, 0, 0, 0 },
- {64, 39, 0, 0, 0, 0 },
- {65, 40, 0, 0, 0, 0 },
- {67, 40, 0, 0, 0, 0 },
- {68, 39, 0, 0, 0, 0 },
- {69, 1, 0, 0, 0, 0 },
- {70, 49, 0, 0, 0, 0 },
- {73, 50, 0, 0, 0, 0 },
- {75, 51, 0, 0, 0, 0 },
- {76, 1, 0, 0, 0, 0 },
- {77, 52, 7, 0, 0, 0 },
- {78, 63, 0, 0, 0, 0 },
- {79, 1, 0, 0, 0, 0 },
- {82, 21, 0, 0, 0, 0 },
- {85, 1, 0, 0, 0, 0 },
- {86, 0, 0, 0, 0, 0 },
- {89, 33, 6, 35, 5, 34},
- {90, 16, 0, 0, 0, 0 },
- {91, 57, 0, 0, 0, 0 },
- {88, 32, 0, 0, 0, 0 },
- {92, 25, 0, 0, 0, 0 },
- {93, 0, 0, 0, 0, 0 },
- {95, 19, 0, 0, 0, 0 },
- {80, 41, 0, 0, 0, 0 },
- {81, 48, 0, 0, 0, 0 },
- {83, 27, 0, 0, 0, 0 },
- {94, 36, 0, 0, 0, 0 },
- {40, 1, 0, 0, 0, 0 },
- {96, 13, 0, 0, 0, 0 },
- {97, 14, 0, 0, 0, 0 },
- {98, 11, 0, 0, 0, 0 },
- {99, 15, 0, 0, 0, 0 },
- {100, 17, 0, 0, 0, 0 },
- {101, 38, 0, 0, 0, 0 },
- {103, 0, 0, 0, 0, 0 },
- {104, 0, 0, 0, 0, 0 },
- {11, 44, 0, 0, 0, 0 },
- {3, 47, 0, 0, 0, 0 },
- {105, 30, 128,29, 0, 0 },
- {106, 0, 0, 0, 0, 0 },
- {107, 1, 0, 0, 0, 0 },
- {108, 1, 0, 0, 0, 0 },
- {47, 1, 0, 0, 0, 0 },
- {50, 1, 0, 0, 0, 0 },
- {52, 0, 0, 0, 0, 0 },
- {71, 1, 0, 0, 0, 0 },
- {13, 1, 0, 0, 0, 0 },
- {72, 1, 0, 0, 0, 0 },
- {46, 33, 6, 35, 5, 34},
- {74, 1, 0, 0, 0, 0 },
- {84, 1, 0, 0, 0, 0 },
- {66, 1, 0, 0, 0, 0 },
- {102, 1, 0, 0, 0, 0 },
- {109, 1, 0, 0, 0, 0 },
- {110, 2, 0, 0, 0, 0 },
- {45, 1, 0, 0, 0, 0 },
- {87, 1, 0, 0, 0, 0 },
- {111, 1, 0, 0, 0, 0 },
- {-1, 1, 0, 0, 0, 0 }
-};
-
-const imuseDigTable _digStateMusicTable[] = {
- {0, 1000, "STATE_NULL", 0, 0, ""}, /* 00 */
- {0, 1001, "stateNoChange", 0, 0, ""}, /* 01 */
- {3, 1100, "stateAstShip", 2, 0, "ASTERO~1.IMU"}, /* 02 */
- {3, 1120, "stateAstClose", 2, 0, "ASTERO~2.IMU"}, /* 03 */
- {3, 1140, "stateAstInside", 0, 0, "ASTERO~3.IMU"}, /* 04 */
- {3, 1150, "stateAstCore", 0, 2, "ASTERO~4.IMU"}, /* 05 */
- {3, 1200, "stateCanyonClose", 0, 1, "CANYON~1.IMU"}, /* 06 */
- {3, 1205, "stateCanyonClose_m", 0, 0, "CANYON~2.IMU"}, /* 07 */
- {3, 1210, "stateCanyonOver", 0, 1, "CANYON~3.IMU"}, /* 08 */
- {3, 1220, "stateCanyonWreck", 0, 1, "CANYON~4.IMU"}, /* 09 */
- {3, 1300, "stateNexusCanyon", 10, 0, "NEXUS(~1.IMU"}, /* 10 */
- {3, 1310, "stateNexusPlan", 10, 0, "NEXUS(~1.IMU"}, /* 11 */
- {3, 1320, "stateNexusRamp", 10, 0, "NEXUS(~2.IMU"}, /* 12 */
- {3, 1330, "stateNexusMuseum", 10, 0, "NEXUS(~3.IMU"}, /* 13 */
- {3, 1340, "stateNexusMap", 10, 0, "NEXUS(~4.IMU"}, /* 14 */
- {3, 1350, "stateNexusTomb", 10, 0, "NE3706~5.IMU"}, /* 15 */
- {3, 1360, "stateNexusCath", 10, 0, "NE3305~5.IMU"}, /* 16 */
- {3, 1370, "stateNexusAirlock", 0, 0, "NE2D3A~5.IMU"}, /* 17 */
- {3, 1380, "stateNexusPowerOff", 0, 1, "NE8522~5.IMU"}, /* 18 */
- {3, 1400, "stateMuseumTramNear", 0, 1, "TRAM(M~1.IMU"}, /* 19 */
- {3, 1410, "stateMuseumTramFar", 0, 0, "TRAM(M~2.IMU"}, /* 20 */
- {3, 1420, "stateMuseumLockup", 0, 0, "MUSEUM~1.IMU"}, /* 21 */
- {3, 1433, "stateMuseumPool", 22, 1, "MUSEUM~2.IMU"}, /* 22 */
- {3, 1436, "stateMuseumSpire", 22, 2, "MUSEUM~3.IMU"}, /* 23 */
- {3, 1440, "stateMuseumMuseum", 22, 2, "MUSEUM~4.IMU"}, /* 24 */
- {3, 1450, "stateMuseumLibrary", 0, 0, "MUB575~5.IMU"}, /* 25 */
- {3, 1460, "stateMuseumCavern", 0, 0, "MUF9BE~5.IMU"}, /* 26 */
- {3, 1500, "stateTombTramNear", 0, 1, "TRAM(T~1.IMU"}, /* 27 */
- {3, 1510, "stateTombBase", 28, 2, "TOMB(A~1.IMU"}, /* 28 */
- {3, 1520, "stateTombSpire", 28, 2, "TOMB(A~2.IMU"}, /* 29 */
- {3, 1530, "stateTombCave", 28, 2, "TOMB(A~3.IMU"}, /* 30 */
- {3, 1540, "stateTombCrypt", 31, 1, "TOMB(C~1.IMU"}, /* 31 */
- {3, 1550, "stateTombGuards", 31, 1, "TOMB(C~2.IMU"}, /* 32 */
- {3, 1560, "stateTombInner", 0, 1, "TOMB(I~1.IMU"}, /* 33 */
- {3, 1570, "stateTombCreator1", 0, 0, "TOMB(C~3.IMU"}, /* 34 */
- {3, 1580, "stateTombCreator2", 0, 0, "TOMB(C~4.IMU"}, /* 35 */
- {3, 1600, "statePlanTramNear", 0, 1, "TRAM(P~1.IMU"}, /* 36 */
- {3, 1610, "statePlanTramFar", 0, 0, "TRAM(P~2.IMU"}, /* 37 */
- {3, 1620, "statePlanBase", 38, 2, "PLAN(A~1.IMU"}, /* 38 */
- {3, 1630, "statePlanSpire", 38, 2, "PLAN(A~2.IMU"}, /* 39 */
- {3, 1650, "statePlanDome", 0, 0, "PLAN(D~1.IMU"}, /* 40 */
- {3, 1700, "stateMapTramNear", 0, 1, "TRAM(M~3.IMU"}, /* 41 */
- {3, 1710, "stateMapTramFar", 0, 0, "TRAM(M~4.IMU"}, /* 42 */
- {3, 1720, "stateMapCanyon", 43, 2, "MAP(AM~1.IMU"}, /* 43 */
- {3, 1730, "stateMapExposed", 43, 2, "MAP(AM~2.IMU"}, /* 44 */
- {3, 1750, "stateMapNestEmpty", 43, 2, "MAP(AM~4.IMU"}, /* 45 */
- {3, 1760, "stateMapNestMonster", 0, 0, "MAP(MO~1.IMU"}, /* 46 */
- {3, 1770, "stateMapKlein", 0, 0, "MAP(KL~1.IMU"}, /* 47 */
- {3, 1800, "stateCathTramNear", 0, 1, "TRAM(C~1.IMU"}, /* 48 */
- {3, 1810, "stateCathTramFar", 0, 0, "TRAM(C~2.IMU"}, /* 49 */
- {3, 1820, "stateCathLab", 50, 1, "CATH(A~1.IMU"}, /* 50 */
- {3, 1830, "stateCathOutside", 50, 1, "CATH(A~2.IMU"}, /* 51 */
- {3, 1900, "stateWorldMuseum", 52, 0, "WORLD(~1.IMU"}, /* 52 */
- {3, 1901, "stateWorldPlan", 52, 0, "WORLD(~2.IMU"}, /* 53 */
- {3, 1902, "stateWorldTomb", 52, 0, "WORLD(~3.IMU"}, /* 54 */
- {3, 1903, "stateWorldMap", 52, 0, "WORLD(~4.IMU"}, /* 55 */
- {3, 1904, "stateWorldCath", 52, 0, "WO3227~5.IMU"}, /* 56 */
- {3, 1910, "stateEye1", 0, 0, "EYE1~1.IMU"}, /* 57 */
- {3, 1911, "stateEye2", 0, 0, "EYE2~1.IMU"}, /* 58 */
- {3, 1912, "stateEye3", 0, 0, "EYE3~1.IMU"}, /* 59 */
- {3, 1913, "stateEye4", 0, 0, "EYE4~1.IMU"}, /* 60 */
- {3, 1914, "stateEye5", 0, 0, "EYE5~1.IMU"}, /* 61 */
- {3, 1915, "stateEye6", 0, 0, "EYE6~1.IMU"}, /* 62 */
- {3, 1916, "stateEye7", 0, 0, "EYE7~1.IMU"}, /* 63 */
- {0, -1, "", 0, 0, ""}
-};
-
-const imuseDigTable _digSeqMusicTable[] = {
- {0, 2000, "SEQ_NULL", 0, 0, ""},
- {0, 2005, "seqLogo", 0, 0, ""},
- {0, 2010, "seqIntro", 0, 0, ""},
- {6, 2020, "seqExplosion1b", 0, 0, ""},
- {3, 2030, "seqAstTunnel1a", 0, 0, "SEQ(AS~1.IMU"},
- {6, 2031, "seqAstTunnel2b", 0, 0, ""},
- {4, 2032, "seqAstTunnel3a", 0, 0, "SEQ(AS~2.IMU"},
- {5, 2040, "seqToPlanet1b", 0, 0, ""},
- {4, 2045, "seqArgBegin", 0, 0, "SEQ(AR~1.IMU"},
- {4, 2046, "seqArgEnd", 0, 0, "SEQ(AR~2.IMU"},
- {4, 2050, "seqWreckGhost", 0, 0, "SEQ(GH~1.IMU"},
- {4, 2060, "seqCanyonGhost", 0, 0, "SEQ(GH~2.IMU"},
- {0, 2070, "seqBrinkFall", 0, 0, ""},
- {4, 2080, "seqPanUpCanyon", 0, 0, "SEQ(PA~1.IMU"},
- {6, 2091, "seqAirlockTunnel1b", 0, 0, ""},
- {6, 2100, "seqTramToMu", 0, 0, ""},
- {6, 2101, "seqTramFromMu", 0, 0, ""},
- {6, 2102, "seqTramToTomb", 0, 0, ""},
- {6, 2103, "seqTramFromTomb", 0, 0, ""},
- {6, 2104, "seqTramToPlan", 0, 0, ""},
- {6, 2105, "seqTramFromPlan", 0, 0, ""},
- {6, 2106, "seqTramToMap", 0, 0, ""},
- {6, 2107, "seqTramFromMap", 0, 0, ""},
- {6, 2108, "seqTramToCath", 0, 0, ""},
- {6, 2109, "seqTramFromCath", 0, 0, ""},
- {0, 2110, "seqMuseumGhost", 0, 0, ""},
- {0, 2120, "seqSerpentAppears", 0, 0, ""},
- {0, 2130, "seqSerpentEats", 0, 0, ""},
- {6, 2140, "seqBrinkRes1b", 0, 0, ""},
- {4, 2141, "seqBrinkRes2a", 0, 0, "SEQ(BR~1.IMU"},
- {3, 2150, "seqLockupEntry", 0, 0, "SEQ(BR~1.IMU"},
- {0, 2160, "seqSerpentExplodes", 0, 0, ""},
- {4, 2170, "seqSwimUnderwater", 0, 0, "SEQ(DE~1.IMU"},
- {4, 2175, "seqWavesPlunge", 0, 0, "SEQ(PL~1.IMU"},
- {0, 2180, "seqCryptOpens", 0, 0, ""},
- {0, 2190, "seqGuardsFight", 0, 0, ""},
- {3, 2200, "seqCreatorRes1.1a", 0, 0, "SEQ(CR~1.IMU"},
- {6, 2201, "seqCreatorRes1.2b", 0, 0, ""},
- {6, 2210, "seqMaggieCapture1b", 0, 0, ""},
- {3, 2220, "seqStealCrystals", 0, 0, "SEQ(BR~1.IMU"},
- {0, 2230, "seqGetByMonster", 0, 0, ""},
- {6, 2240, "seqKillMonster1b", 0, 0, ""},
- {3, 2250, "seqCreatorRes2.1a", 0, 0, "SEQ(CR~2.IMU"},
- {6, 2251, "seqCreatorRes2.2b", 0, 0, ""},
- {4, 2252, "seqCreatorRes2.3a", 0, 0, "SEQ(CR~3.IMU"},
- {0, 2260, "seqMaggieInsists", 0, 0, ""},
- {0, 2270, "seqBrinkHelpCall", 0, 0, ""},
- {3, 2280, "seqBrinkCrevice1a", 0, 0, "SEQ(BR~2.IMU"},
- {3, 2281, "seqBrinkCrevice2a", 0, 0, "SEQ(BR~3.IMU"},
- {6, 2290, "seqCathAccess1b", 0, 0, ""},
- {4, 2291, "seqCathAccess2a", 0, 0, "SEQ(CA~1.IMU"},
- {3, 2300, "seqBrinkAtGenerator", 0, 0, "SEQ(BR~1.IMU"},
- {6, 2320, "seqFightBrink1b", 0, 0, ""},
- {6, 2340, "seqMaggieDies1b", 0, 0, ""},
- {6, 2346, "seqMaggieRes1b", 0, 0, ""},
- {4, 2347, "seqMaggieRes2a", 0, 0, "SEQ(MA~1.IMU"},
- {0, 2350, "seqCreatureFalls", 0, 0, ""},
- {5, 2360, "seqFinale1b", 0, 0, ""},
- {3, 2370, "seqFinale2a", 0, 0, "SEQ(FI~1.IMU"},
- {6, 2380, "seqFinale3b1", 0, 0, ""},
- {6, 2390, "seqFinale3b2", 0, 0, ""},
- {3, 2400, "seqFinale4a", 0, 0, "SEQ(FI~2.IMU"},
- {3, 2410, "seqFinale5a", 0, 0, "SEQ(FI~3.IMU"},
- {3, 2420, "seqFinale6a", 0, 0, "SEQ(FI~4.IMU"},
- {3, 2430, "seqFinale7a", 0, 0, "SE3D2B~5.IMU"},
- {6, 2440, "seqFinale8b", 0, 0, ""},
- {4, 2450, "seqFinale9a", 0, 0, "SE313B~5.IMU"},
- {0, -1, "", 0, 0, ""}
-};
-
-const imuseComiTable _comiStateMusicTable[] = {
- {0, 1000, "STATE_NULL", 0, 0, 0, ""}, /* 00 */
- {0, 1001, "stateNoChange", 0, 0, 0, ""}, /* 01 */
- {3, 1098, "stateCredits1", 0, 0, 60, "1098-C~1.IMX"}, /* 02 */
- {3, 1099, "stateMenu", 0, 0, 60, "1099-M~1.IMX"}, /* 03 */
- {3, 1100, "stateHold1", 4, 0, 60, "1100-H~1.IMX"}, /* 04 */
- {3, 1101, "stateWaterline1", 4, 0, 60, "1101-W~1.IMX"}, /* 05 */
- {3, 1102, "stateHold2", 6, 1, 60, "1102-H~1.IMX"}, /* 06 */
- {3, 1103, "stateWaterline2", 6, 0, 60, "1103-W~1.IMX"}, /* 07 */
- {3, 1104, "stateCannon", 0, 0, 60, "1104-C~1.IMX"}, /* 08 */
- {3, 1105, "stateTreasure", 0, 0, 60, "1105-T~1.IMX"}, /* 09 */
- {3, 1200, "stateFortBase", 10, 1, 60, "1200-F~1.IMX"}, /* 10 */
- {3, 1201, "statePreFort", 10, 1, 60, "1201-P~1.IMX"}, /* 11 */
- {3, 1202, "statePreVooOut", 12, 0, 60, "1202-P~1.IMX"}, /* 12 */
- {3, 1203, "statePreVooIn", 12, 0, 60, "1203-P~1.IMX"}, /* 13 */
- {3, 1204, "statePreVooLady", 12, 0, 60, "1204-P~1.IMX"}, /* 14 */
- {3, 1205, "stateVoodooOut", 0, 0, 60, "1205-V~1.IMX"}, /* 15 */
- {3, 1210, "stateVoodooIn", 0, 0, 60, "1210-V~1.IMX"}, /* 16 */
- {12,1212, "stateVoodooInAlt", 0, 1, 42, "1210-V~1.IMX"}, /* 17 */
- {3, 1215, "stateVoodooLady", 0, 0, 60, "1215-V~1.IMX"}, /* 18 */
- {3, 1219, "statePrePlundermap", 0, 0, 60, "1219-P~1.IMX"}, /* 19 */
- {3, 1220, "statePlundermap", 0, 0, 60, "1220-P~1.IMX"}, /* 20 */
- {3, 1222, "statePreCabana", 0, 0, 60, "1222-P~1.IMX"}, /* 21 */
- {3, 1223, "stateCabana", 0, 0, 60, "1223-C~1.IMX"}, /* 22 */
- {3, 1224, "statePostCabana", 23, 0, 60, "1224-P~1.IMX"}, /* 23 */
- {3, 1225, "stateBeachClub", 23, 0, 60, "1225-B~1.IMX"}, /* 24 */
- {3, 1230, "stateCliff", 0, 0, 60, "1230-C~1.IMX"}, /* 25 */
- {3, 1232, "stateBelly", 0, 0, 48, "1232-B~1.IMX"}, /* 26 */
- {3, 1235, "stateQuicksand", 0, 0, 60, "1235-Q~1.IMX"}, /* 27 */
- {3, 1240, "stateDangerBeach", 0, 0, 48, "1240-D~1.IMX"}, /* 28 */
- {12,1241, "stateDangerBeachAlt",0, 2, 48, "1240-D~1.IMX"}, /* 29 */
- {3, 1245, "stateRowBoat", 0, 0, 60, "1245-R~1.IMX"}, /* 30 */
- {3, 1247, "stateAlongside", 0, 0, 48, "1247-A~1.IMX"}, /* 31 */
- {12,1248, "stateAlongsideAlt", 0, 1, 48, "1247-A~1.IMX"}, /* 32 */
- {3, 1250, "stateChimpBoat", 0, 0, 30, "1250-C~1.IMX"}, /* 33 */
- {3, 1255, "stateMrFossey", 0, 0, 48, "1255-M~1.IMX"}, /* 34 */
- {3, 1259, "statePreTown", 0, 0, 60, "1259-P~1.IMX"}, /* 35 */
- {3, 1260, "stateTown", 0, 0, 60, "1260-T~1.IMX"}, /* 36 */
- {3, 1264, "statePreMeadow", 0, 0, 60, "1264-P~1.IMX"}, /* 37 */
- {3, 1265, "stateMeadow", 0, 0, 60, "1265-M~1.IMX"}, /* 38 */
- {3, 1266, "stateMeadowAmb", 0, 0, 60, "1266-M~1.IMX"}, /* 39 */
- {3, 1270, "stateWardrobePre", 40, 0, 60, "1270-W~1.IMX"}, /* 40 */
- {3, 1272, "statePreShow", 40, 0, 60, "1272-P~1.IMX"}, /* 41 */
- {3, 1274, "stateWardrobeShow", 42, 0, 60, "1274-W~1.IMX"}, /* 42 */
- {3, 1276, "stateShow", 42, 0, 60, "1276-S~1.IMX"}, /* 43 */
- {3, 1277, "stateWardrobeJug", 44, 0, 60, "1277-W~1.IMX"}, /* 44 */
- {3, 1278, "stateJuggling", 44, 0, 60, "1278-J~1.IMX"}, /* 45 */
- {3, 1279, "statePostShow", 0, 0, 60, "1279-P~1.IMX"}, /* 46 */
- {3, 1280, "stateChickenShop", 0, 0, 60, "1280-C~1.IMX"}, /* 47 */
- {3, 1285, "stateBarberShop", 48, 0, 60, "1285-B~1.IMX"}, /* 48 */
- {3, 1286, "stateVanHelgen", 48, 0, 60, "1286-V~1.IMX"}, /* 49 */
- {3, 1287, "stateBill", 48, 0, 60, "1287-B~1.IMX"}, /* 50 */
- {3, 1288, "stateHaggis", 48, 0, 60, "1288-H~1.IMX"}, /* 51 */
- {3, 1289, "stateRottingham", 48, 0, 60, "1289-R~1.IMX"}, /* 52 */
- {3, 1305, "stateDeck", 0, 0, 60, "1305-D~1.IMX"}, /* 53 */
- {3, 1310, "stateCombatMap", 0, 0, 60, "1310-C~1.IMX"}, /* 54 */
- {3, 1320, "stateShipCombat", 0, 0, 60, "1320-S~1.IMX"}, /* 55 */
- {3, 1325, "stateSwordfight", 0, 0, 60, "1325-S~1.IMX"}, /* 56 */
- {3, 1327, "stateSwordRott", 0, 0, 60, "1327-S~1.IMX"}, /* 57 */
- {3, 1330, "stateTownEdge", 0, 0, 60, "1330-T~1.IMX"}, /* 58 */
- {3, 1335, "stateSwordLose", 0, 0, 60, "1335-S~1.IMX"}, /* 59 */
- {3, 1340, "stateSwordWin", 0, 0, 60, "1340-S~1.IMX"}, /* 60 */
- {3, 1345, "stateGetMap", 0, 0, 60, "1345-G~1.IMX"}, /* 61 */
- {3, 1400, "stateWreckBeach", 0, 0, 60, "1400-W~1.IMX"}, /* 62 */
- {3, 1405, "stateBloodMap", 63, 0, 60, "1405-B~1.IMX"}, /* 63 */
- {3, 1410, "stateClearing", 0, 0, 60, "1410-C~1.IMX"}, /* 64 */
- {3, 1415, "stateLighthouse", 63, 0, 60, "1415-L~1.IMX"}, /* 65 */
- {3, 1420, "stateVillage", 66, 0, 60, "1420-V~1.IMX"}, /* 66 */
- {3, 1423, "stateVolcano", 66, 0, 60, "1423-V~1.IMX"}, /* 67 */
- {3, 1425, "stateAltar", 66, 0, 60, "1425-A~1.IMX"}, /* 68 */
- {3, 1430, "stateHotelOut", 0, 0, 60, "1430-H~1.IMX"}, /* 69 */
- {3, 1435, "stateHotelBar", 70, 0, 60, "1435-H~1.IMX"}, /* 70 */
- {3, 1440, "stateHotelIn", 70, 0, 60, "1440-H~1.IMX"}, /* 71 */
- {3, 1445, "stateTarotLady", 70, 0, 60, "1445-T~1.IMX"}, /* 72 */
- {3, 1447, "stateGoodsoup", 70, 0, 60, "1447-G~1.IMX"}, /* 73 */
- {3, 1448, "stateGuestRoom", 0, 0, 60, "1448-G~1.IMX"}, /* 74 */
- {3, 1450, "stateWindmill", 63, 0, 60, "1450-W~1.IMX"}, /* 75 */
- {3, 1455, "stateCemetary", 0, 0, 60, "1455-C~1.IMX"}, /* 76 */
- {3, 1460, "stateCrypt", 77, 0, 60, "1460-C~1.IMX"}, /* 77 */
- {3, 1463, "stateGraveDigger", 77, 0, 60, "1463-G~1.IMX"}, /* 78 */
- {3, 1465, "stateMonkey1", 0, 0, 60, "1465-M~1.IMX"}, /* 79 */
- {3, 1475, "stateStanDark", 0, 0, 60, "1475-S~1.IMX"}, /* 80 */
- {3, 1477, "stateStanLight", 0, 0, 60, "1477-S~1.IMX"}, /* 81 */
- {3, 1480, "stateEggBeach", 63, 0, 60, "1480-E~1.IMX"}, /* 82 */
- {3, 1485, "stateSkullIsland", 0, 0, 60, "1485-S~1.IMX"}, /* 83 */
- {3, 1490, "stateSmugglersCave", 0, 0, 60, "1490-S~1.IMX"}, /* 84 */
- {3, 1500, "stateLeChuckTalk", 0, 0, 60, "1500-L~1.IMX"}, /* 85 */
- {3, 1505, "stateCarnival", 0, 0, 60, "1505-C~1.IMX"}, /* 86 */
- {3, 1511, "stateHang", 87, 0, 60, "1511-H~1.IMX"}, /* 87 */
- {3, 1512, "stateRum", 87, 0, 60, "1512-RUM.IMX"}, /* 88 */
- {3, 1513, "stateTorture", 87, 0, 60, "1513-T~1.IMX"}, /* 89 */
- {3, 1514, "stateSnow", 87, 0, 60, "1514-S~1.IMX"}, /* 90 */
- {3, 1515, "stateCredits", 0, 0, 60, "1515-C~1.IMX"}, /* 91 */
- {3, 1520, "stateCarnAmb", 0, 0, 60, "1520-C~1.IMX"}, /* 92 */
- {0, -1, "", 0, 0, 0, ""}
-};
-
-const imuseComiTable _comiSeqMusicTable[] = {
- {0, 2000, "SEQ_NULL", 0, 0, 0, ""},
- {0, 2100, "seqINTRO", 0, 0, 0, ""},
- {3, 2105, "seqInterlude1", 0, 0, 60, "2105-I~1.IMX"},
- {8, 2110, "seqLastBoat", 0, 1, 0, ""},
- {0, 2115, "seqSINK_SHIP", 0, 0, 0, ""},
- {0, 2120, "seqCURSED_RING", 0, 0, 60, ""},
- {3, 2200, "seqInterlude2", 0, 0, 60, "2200-I~1.IMX"},
- {3, 2210, "seqKidnapped", 0, 0, 60, "2210-K~1.IMX"},
- {8, 2220, "seqSnakeVomits", 0, 1, 0, ""},
- {8, 2222, "seqPopBalloon", 0, 1, 0, ""},
- {3, 2225, "seqDropBalls", 0, 0, 60, "2225-D~1.IMX"},
- {4, 2232, "seqArriveBarber", 0, 0, 60, "2232-A~1.IMX"},
- {3, 2233, "seqAtonal", 0, 0, 60, "2233-A~1.IMX"},
- {3, 2235, "seqShaveHead1", 0, 0, 60, "2235-S~1.IMX"},
- {2, 2236, "seqShaveHead2", 0, 2, 60, "2235-S~1.IMX"},
- {3, 2245, "seqCaberLose", 0, 0, 60, "2245-C~1.IMX"},
- {3, 2250, "seqCaberWin", 0, 0, 60, "2250-C~1.IMX"},
- {3, 2255, "seqDuel1", 0, 0, 60, "2255-D~1.IMX"},
- {2, 2256, "seqDuel2", 0, 2, 60, "2255-D~1.IMX"},
- {2, 2257, "seqDuel3", 0, 3, 60, "2255-D~1.IMX"},
- {3, 2260, "seqBlowUpTree1", 0, 0, 60, "2260-B~1.IMX"},
- {2, 2261, "seqBlowUpTree2", 0, 2, 60, "2260-B~1.IMX"},
- {3, 2275, "seqMonkeys", 0, 0, 60, "2275-M~1.IMX"},
- {9, 2277, "seqAttack", 0, 1, 0, ""},
- {3, 2285, "seqSharks", 0, 0, 60, "2285-S~1.IMX"},
- {3, 2287, "seqTowelWalk", 0, 0, 60, "2287-T~1.IMX"},
- {0, 2293, "seqNICE_BOOTS", 0, 0, 0, ""},
- {0, 2295, "seqBIG_BONED", 0, 0, 0, ""},
- {3, 2300, "seqToBlood", 0, 0, 60, "2300-T~1.IMX"},
- {3, 2301, "seqInterlude3", 0, 0, 60, "2301-I~1.IMX"},
- {3, 2302, "seqRott1", 0, 0, 60, "2302-R~1.IMX"},
- {2, 2304, "seqRott2", 0, 2, 60, "2302-R~1.IMX"},
- {2, 2305, "seqRott2b", 0,21, 60, "2302-R~1.IMX"},
- {2, 2306, "seqRott3", 0, 3, 60, "2302-R~1.IMX"},
- {2, 2308, "seqRott4", 0, 4, 60, "2302-R~1.IMX"},
- {2, 2309, "seqRott5", 0, 5, 60, "2302-R~1.IMX"},
- {3, 2311, "seqVerse1", 0, 0, 60, "2311-S~1.IMX"},
- {2, 2312, "seqVerse2", 0, 2, 60, "2311-S~1.IMX"},
- {2, 2313, "seqVerse3", 0, 3, 60, "2311-S~1.IMX"},
- {2, 2314, "seqVerse4", 0, 4, 60, "2311-S~1.IMX"},
- {2, 2315, "seqVerse5", 0, 5, 60, "2311-S~1.IMX"},
- {2, 2316, "seqVerse6", 0, 6, 60, "2311-S~1.IMX"},
- {2, 2317, "seqVerse7", 0, 7, 60, "2311-S~1.IMX"},
- {2, 2318, "seqVerse8", 0, 8, 60, "2311-S~1.IMX"},
- {2, 2319, "seqSongEnd", 0, 9, 60, "2311-S~1.IMX"},
- {2, 2336, "seqRiposteLose", 0, 0, 60, "2336-R~1.IMX"},
- {2, 2337, "seqRiposteWin", 0, 0, 60, "2337-R~1.IMX"},
- {2, 2338, "seqInsultLose", 0, 0, 60, "2338-I~1.IMX"},
- {2, 2339, "seqInsultWin", 0, 0, 60, "2339-I~1.IMX"},
- {3, 2340, "seqSwordLose", 0, 0, 60, "1335-S~1.IMX"},
- {3, 2345, "seqSwordWin", 0, 0, 60, "1340-S~1.IMX"},
- {3, 2347, "seqGetMap", 0, 0, 60, "1345-G~1.IMX"},
- {3, 2400, "seqInterlude4", 0, 0, 60, "2400-I~1.IMX"},
- {0, 2405, "seqSHIPWRECK", 0, 0, 0, ""},
- {3, 2408, "seqFakeCredits", 0, 0, 60, "2408-F~1.IMX"},
- {3, 2410, "seqPassOut", 0, 0, 60, "2410-P~1.IMX"},
- {3, 2414, "seqGhostTalk", 0, 0, 60, "2414-G~1.IMX"},
- {2, 2415, "seqGhostWedding", 0, 1, 60, "2414-G~1.IMX"},
- {3, 2420, "seqEruption", 0, 0, 60, "2420-E~1.IMX"},
- {3, 2425, "seqSacrifice", 0, 0, 60, "2425-S~1.IMX"},
- {2, 2426, "seqSacrificeEnd", 0, 1, 60, "2425-S~1.IMX"},
- {3, 2430, "seqScareDigger", 0, 0, 60, "2430-S~1.IMX"},
- {3, 2445, "seqSkullArrive", 0, 0, 60, "2445-S~1.IMX"},
- {3, 2450, "seqFloat", 0, 0, 60, "2450-C~1.IMX"},
- {2, 2451, "seqFall", 0, 1, 60, "2450-C~1.IMX"},
- {2, 2452, "seqUmbrella", 0, 0, 60, "2450-C~1.IMX"},
- {3, 2460, "seqFight", 0, 0, 60, "2460-F~1.IMX"},
- {0, 2465, "seqLAVE_RIDE", 0, 0, 0, ""},
- {0, 2470, "seqMORE_SLAW", 0, 0, 0, ""},
- {0, 2475, "seqLIFT_CURSE", 0, 0, 0, ""},
- {3, 2500, "seqInterlude5", 0, 0, 60, "2500-I~1.IMX"},
- {3, 2502, "seqExitSkycar", 0, 0, 60, "2502-E~1.IMX"},
- {3, 2504, "seqGrow1", 0, 0, 60, "2504-G~1.IMX"},
- {2, 2505, "seqGrow2", 0, 1, 60, "2504-G~1.IMX"},
- {3, 2508, "seqInterlude6", 0, 0, 60, "2508-I~1.IMX"},
- {0, 2515, "seqFINALE", 0, 0, 0, ""},
- {3, 2520, "seqOut", 0, 0, 60, "2520-OUT.IMX"},
- {3, 2530, "seqZap1a", 0, 0, 60, "2530-Z~1.IMX"},
- {2, 2531, "seqZap1b", 0, 1, 60, "2530-Z~1.IMX"},
- {2, 2532, "seqZap1c", 0, 2, 60, "2530-Z~1.IMX"},
- {2, 2540, "seqZap2a", 0, 0, 60, "2540-Z~1.IMX"},
- {2, 2541, "seqZap2b", 0, 1, 60, "2540-Z~1.IMX"},
- {2, 2542, "seqZap2c", 0, 2, 60, "2540-Z~1.IMX"},
- {3, 2550, "seqZap3a", 0, 0, 60, "2550-Z~1.IMX"},
- {2, 2551, "seqZap3b", 0, 1, 60, "2550-Z~1.IMX"},
- {2, 2552, "seqZap3c", 0, 2, 60, "2550-Z~1.IMX"},
- {3, 2560, "seqZap4a", 0, 0, 60, "2560-Z~1.IMX"},
- {2, 2561, "seqZap4b", 0, 1, 60, "2560-Z~1.IMX"},
- {2, 2562, "seqZap4c", 0, 2, 60, "2560-Z~1.IMX"},
- {0, -1, "", 0, 0, 0, ""}
-};
-
-const imuseFtStateTable _ftStateMusicTable[] = {
- {"", 0, 0, "STATE_NULL" },
- {"", 4, 127, "stateKstandOutside" },
- {"kinside", 2, 127, "stateKstandInside" },
- {"moshop", 3, 64, "stateMoesInside" },
- {"melcut", 2, 127, "stateMoesOutside" },
- {"mellover", 2, 127, "stateMellonAbove" },
- {"radloop", 3, 28, "stateTrailerOutside" },
- {"radloop", 3, 58, "stateTrailerInside" },
- {"radloop", 3, 127, "stateTodShop" },
- {"junkgate", 2, 127, "stateJunkGate" },
- {"junkover", 3, 127, "stateJunkAbove" },
- {"gastower", 2, 127, "stateGasTower" },
- {"", 4, 0, "stateTowerAlarm" },
- {"melcut", 2, 127, "stateCopsOnGround" },
- {"melcut", 2, 127, "stateCopsAround" },
- {"melcut", 2, 127, "stateMoesRuins" },
- {"melcut", 2, 127, "stateKstandNight" },
- {"trukblu2", 2, 127, "stateTruckerTalk" },
- {"stretch", 2, 127, "stateMumblyPeg" },
- {"kstand", 2, 100, "stateRanchOutside" },
- {"kinside", 2, 127, "stateRanchInside" },
- {"desert", 2, 127, "stateWreckedTruck" },
- {"opening", 2, 100, "stateGorgeVista" },
- {"caveopen", 2, 127, "stateCaveOpen" },
- {"cavecut1", 2, 127, "stateCaveOuter" },
- {"cavecut1", 1, 127, "stateCaveMiddle" },
- {"cave", 2, 127, "stateCaveInner" },
- {"corville", 2, 127, "stateCorvilleFront" },
- {"mines", 2, 127, "stateMineField" },
- {"bunyman3", 2, 127, "stateBunnyStore" },
- {"stretch", 2, 127, "stateStretchBen" },
- {"saveme", 2, 127, "stateBenPleas" },
- {"", 4, 0, "stateBenConvinces" },
- {"derby", 3, 127, "stateDemoDerby" },
- {"fire", 3, 127, "stateLightMyFire" },
- {"derby", 3, 127, "stateDerbyChase" },
- {"carparts", 2, 127, "stateVultureCarParts"},
- {"cavecut1", 2, 127, "stateVulturesInside" },
- {"mines", 2, 127, "stateFactoryRear" },
- {"croffice", 2, 127, "stateCorleyOffice" },
- {"melcut", 2, 127, "stateCorleyHall" },
- {"", 4, 0, "stateProjRoom" },
- {"", 4, 0, "stateMMRoom" },
- {"bumper", 2, 127, "stateBenOnBumper" },
- {"benump", 2, 127, "stateBenOnBack" },
- {"plane", 2, 127, "stateInCargoPlane" },
- {"saveme", 2, 127, "statePlaneControls" },
- {"", 4, 0, "stateCliffHanger1" },
- {"", 4, 0, "stateCliffHanger2" },
-};
-
-const imuseFtNames _ftSeqNames[] = {
- {"SEQ_NULL" },
- {"seqLogo" },
- {"seqOpenFlick" },
- {"seqBartender" },
- {"seqBenWakes" },
- {"seqPhotoScram" },
- {"seqClimbChain" },
- {"seqDogChase" },
- {"seqDogSquish" },
- {"seqDogHoist" },
- {"seqCopsArrive" },
- {"seqCopsLand" },
- {"seqCopsLeave" },
- {"seqCopterFlyby" },
- {"seqCopterCrash" },
- {"seqMoGetsParts" },
- {"seqMoFixesBike" },
- {"seqFirstGoodbye" },
- {"seqCopRoadblock" },
- {"seqDivertCops" },
- {"seqMurder" },
- {"seqCorleyDies" },
- {"seqTooLateAtMoes" },
- {"seqPicture" },
- {"seqNewsReel" },
- {"seqCopsInspect" },
- {"seqHijack" },
- {"seqNestolusAtRanch" },
- {"seqRipLimo" },
- {"seqGorgeTurn" },
- {"seqCavefishTalk" },
- {"seqArriveCorville" },
- {"seqSingleBunny" },
- {"seqBunnyArmy" },
- {"seqArriveAtMines" },
- {"seqArriveAtVultures"},
- {"seqMakePlan" },
- {"seqShowPlan" },
- {"seqDerbyStart" },
- {"seqLightBales" },
- {"seqNestolusBBQ" },
- {"seqCallSecurity" },
- {"seqFilmFail" },
- {"seqFilmBurn" },
- {"seqRipSpeech" },
- {"seqExposeRip" },
- {"seqRipEscape" },
- {"seqRareMoment" },
- {"seqFanBunnies" },
- {"seqRipDead" },
- {"seqFuneral" },
- {"seqCredits" }
-};
-
-const imuseFtSeqTable _ftSeqMusicTable[] = {
- {"", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"opening", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"barbeat", 2, 127},
- {"barwarn", 2, 127},
- {"", 0, 0 },
- {"", 0, 0, },
-
- {"benwakes", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"barwarn", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"swatben", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"dogattak", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"", 4, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"", 4, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"cops2", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"cops2", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"cops2", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"bunymrch", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"", 4, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"", 0, 0 },
- {"melcut", 2, 127},
- {"tada", 2, 127},
- {"", 0, 0 },
-
- {"", 4, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"trucker", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"cops2", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"barwarn", 2, 127},
- {"murder", 2, 127},
- {"murder2", 2, 127},
- {"", 0, 0 },
-
- {"corldie", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"barwarn", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"picture", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"ripintro", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"trucker", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"hosed", 2, 127},
-
- {"ripdead", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"nesranch", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"scolding", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"desert", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"cavecut1", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"caveamb", 2, 80 },
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"castle", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"bunymrch", 2, 105},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"valkyrs", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"melcut", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"veltures", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"sorry", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"makeplan", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"castle", 2, 127},
- {"derby", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"fire", 3, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"saveme", 3, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"scolding", 2, 127},
-
- {"cops2", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"sorry", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"sorry", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"caveamb", 2, 85 },
- {"tada", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"expose", 2, 127},
- {"", 4, 0 },
- {"", 0, 0 },
- {"mocoup", 2, 127},
-
- {"ripscram", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"valkyrs", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"ripdead", 2, 127},
- {"", 0, 0 },
- {"", 0, 0 },
- {"", 0, 0 },
-
- {"funeral", 2, 127},
- {"", 2, 127},
- {"moshop", 3, 64 },
- {"", 0, 0 },
-
- {"bornbad", 2, 127},
- {"hammvox", 2, 127},
- {"legavox", 2, 127},
- {"chances", 2, 90 },
-};
-#endif
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(DimuseTables)
-_GSETPTR(Scumm::_digStateMusicMap, GBVARS_DIGSTATEMUSICMAP_INDEX, Scumm::imuseRoomMap , GBVARS_SCUMM)
-_GSETPTR(Scumm::_digStateMusicTable, GBVARS_DIGSTATEMUSICTABLE_INDEX, Scumm::imuseDigTable , GBVARS_SCUMM)
-_GSETPTR(Scumm::_digSeqMusicTable, GBVARS_DIGSEQMUSICTABLE_INDEX, Scumm::imuseDigTable , GBVARS_SCUMM)
-_GSETPTR(Scumm::_comiStateMusicTable, GBVARS_COMISTATEMUSICTABLE_INDEX, Scumm::imuseComiTable , GBVARS_SCUMM)
-_GSETPTR(Scumm::_comiSeqMusicTable, GBVARS_COMISEQMUSICTABLE_INDEX, Scumm::imuseComiTable , GBVARS_SCUMM)
-_GSETPTR(Scumm::_ftStateMusicTable, GBVARS_FTSTATEMUSICTABLE_INDEX, Scumm::imuseFtStateTable, GBVARS_SCUMM)
-_GSETPTR(Scumm::_ftSeqMusicTable, GBVARS_FTSEQMUSICTABLE_INDEX, Scumm::imuseFtSeqTable , GBVARS_SCUMM)
-_GSETPTR(Scumm::_ftSeqNames, GBVARS_FTSEQNAMES_INDEX, Scumm::imuseFtNames , GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(DimuseTables)
-_GRELEASEPTR(GBVARS_DIGSTATEMUSICMAP_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_DIGSTATEMUSICTABLE_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_DIGSEQMUSICTABLE_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_COMISTATEMUSICTABLE_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_COMISEQMUSICTABLE_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FTSTATEMUSICTABLE_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FTSEQMUSICTABLE_INDEX , GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FTSEQNAMES_INDEX , GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/imuse_digi/dimuse_track.cpp b/scumm/imuse_digi/dimuse_track.cpp
deleted file mode 100644
index d1bd5b8923..0000000000
--- a/scumm/imuse_digi/dimuse_track.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "common/timer.h"
-
-#include "scumm/actor.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse_digi/dimuse_bndmgr.h"
-
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-int IMuseDigital::allocSlot(int priority) {
- int l, lowest_priority = 127;
- int trackId = -1;
-
- for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- if (!_track[l]->used) {
- trackId = l;
- break;
- }
- }
-
- if (trackId == -1) {
- debug(5, "IMuseDigital::startSound(): All slots are full");
- for (l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved &&
- (lowest_priority > track->priority) && !track->stream2) {
- lowest_priority = track->priority;
- trackId = l;
- }
- }
- if (lowest_priority <= priority) {
- assert(trackId != -1);
- _track[trackId]->toBeRemoved = true;
- debug(5, "IMuseDigital::startSound(): Removed sound %d from track %d", _track[trackId]->soundId, trackId);
- } else {
- debug(5, "IMuseDigital::startSound(): Priority sound too low");
- return -1;
- }
- }
-
- return trackId;
-}
-
-void IMuseDigital::startSound(int soundId, const char *soundName, int soundType, int volGroupId, AudioStream *input, int hookId, int volume, int priority) {
- debug(5, "IMuseDigital::startSound(%d)", soundId);
-
- int l = allocSlot(priority);
- if (l == -1) {
- warning("IMuseDigital::startSound() Can't start sound - no free slots");
- return;
- }
-
- Track *track = _track[l];
- while (track->used) {
- // The designated track is not yet available. So, we call flushTracks()
- // to get it processed (and thus made ready for us). Since the actual
- // processing is done by another thread, we also call parseEvents to
- // give it some time (and to avoid busy waiting/looping).
- flushTracks();
-#ifndef __PLAYSTATION2__
- _vm->parseEvents();
-#endif
- }
-
- track->pan = 64;
- track->vol = volume * 1000;
- track->volFadeDest = 0;
- track->volFadeStep = 0;
- track->volFadeDelay = 0;
- track->volFadeUsed = false;
- track->soundId = soundId;
- track->started = false;
- track->volGroupId = volGroupId;
- track->curHookId = hookId;
- track->priority = priority;
- track->curRegion = -1;
- track->dataOffset = 0;
- track->regionOffset = 0;
- track->mod = 0;
- track->mixerFlags = 0;
- track->toBeRemoved = false;
- track->readyToRemove = false;
- track->soundType = soundType;
-
- int bits = 0, freq = 0, channels = 0;
-
- if (input) {
- track->iteration = 0;
- track->souStream = true;
- track->soundName[0] = 0;
- } else {
- track->souStream = false;
- strcpy(track->soundName, soundName);
- track->soundHandle = _sound->openSound(soundId, soundName, soundType, volGroupId, -1);
-
- if (track->soundHandle == NULL)
- return;
-
- track->compressed = _sound->isCompressed(track->soundHandle);
-
- bits = _sound->getBits(track->soundHandle);
- channels = _sound->getChannels(track->soundHandle);
- freq = _sound->getFreq(track->soundHandle);
-
- if ((soundId == kTalkSoundID) && (soundType == IMUSE_BUNDLE)) {
- if (_vm->_actorToPrintStrFor != 0xFF && _vm->_actorToPrintStrFor != 0) {
- Actor *a = _vm->derefActor(_vm->_actorToPrintStrFor, "IMuseDigital::startSound");
- freq = (freq * a->_talkFrequency) / 256;
- track->pan = a->_talkPan;
- track->vol = a->_talkVolume * 1000;
- }
- }
-
- assert(bits == 8 || bits == 12 || bits == 16);
- assert(channels == 1 || channels == 2);
- assert(0 < freq && freq <= 65535);
-
- track->iteration = freq * channels;
- if (channels == 2)
- track->mixerFlags = Audio::Mixer::FLAG_STEREO | Audio::Mixer::FLAG_REVERSE_STEREO;
-
- if ((bits == 12) || (bits == 16)) {
- track->mixerFlags |= Audio::Mixer::FLAG_16BITS;
- track->iteration *= 2;
- } else if (bits == 8) {
- track->mixerFlags |= Audio::Mixer::FLAG_UNSIGNED;
- } else
- error("IMuseDigital::startSound(): Can't handle %d bit samples", bits);
-
-#ifdef SCUMM_LITTLE_ENDIAN
- if (track->compressed)
- track->mixerFlags |= Audio::Mixer::FLAG_LITTLE_ENDIAN;
-#endif
- }
-
- if (input) {
- track->stream2 = input;
- track->stream = NULL;
- track->started = false;
- } else {
- const int pan = (track->pan != 64) ? 2 * track->pan - 127 : 0;
- const int vol = track->vol / 1000;
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
-
- if (track->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (track->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (track->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- // setup 1 second stream wrapped buffer
- int32 streamBufferSize = track->iteration;
- track->stream2 = NULL;
- track->stream = makeAppendableAudioStream(freq, track->mixerFlags, streamBufferSize);
- _vm->_mixer->playInputStream(type, &track->handle, track->stream, -1, vol, pan, false);
- track->started = true;
- }
-
- track->used = true;
-}
-
-void IMuseDigital::setPriority(int soundId, int priority) {
- Common::StackLock lock(_mutex, "IMuseDigital::setPriority()");
- debug(5, "IMuseDigital::setPriority(%d, %d)", soundId, priority);
- assert ((priority >= 0) && (priority <= 127));
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->priority = priority;
- }
- }
-}
-
-void IMuseDigital::setVolume(int soundId, int volume) {
- Common::StackLock lock(_mutex, "IMuseDigital::setVolume()");
- debug(5, "IMuseDigital::setVolume(%d, %d)", soundId, volume);
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->vol = volume * 1000;
- }
- }
-}
-
-void IMuseDigital::setHookId(int soundId, int hookId) {
- Common::StackLock lock(_mutex, "IMuseDigital::setHookId()");
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->curHookId = hookId;
- }
- }
-}
-
-int IMuseDigital::getCurMusicSoundId() {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicSoundId()");
- int soundId = -1;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- soundId = track->soundId;
- }
- }
-
- return soundId;
-}
-
-char *IMuseDigital::getCurMusicSoundName() {
- Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicSoundName()");
- char *soundName = NULL;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- soundName = track->soundName;
- }
- }
-
- return soundName;
-}
-
-void IMuseDigital::setPan(int soundId, int pan) {
- Common::StackLock lock(_mutex, "IMuseDigital::setPan()");
- debug(5, "IMuseDigital::setPan(%d, %d)", soundId, pan);
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->pan = pan;
- }
- }
-}
-
-void IMuseDigital::selectVolumeGroup(int soundId, int volGroupId) {
- Common::StackLock lock(_mutex, "IMuseDigital::selectVolumeGroup()");
- debug(5, "IMuseDigital::setGroupVolume(%d, %d)", soundId, volGroupId);
- assert((volGroupId >= 1) && (volGroupId <= 4));
-
- if (volGroupId == 4)
- volGroupId = 3;
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->volGroupId = volGroupId;
- }
- }
-}
-
-void IMuseDigital::setFade(int soundId, int destVolume, int delay60HzTicks) {
- Common::StackLock lock(_mutex, "IMuseDigital::setFade()");
- debug(5, "IMuseDigital::setFade(%d, %d, %d)", soundId, destVolume, delay60HzTicks);
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if ((track->soundId == soundId) && track->used && !track->toBeRemoved) {
- track->volFadeDelay = delay60HzTicks;
- track->volFadeDest = destVolume * 1000;
- track->volFadeStep = (track->volFadeDest - track->vol) * 60 * (1000 / _callbackFps) / (1000 * delay60HzTicks);
- track->volFadeUsed = true;
- }
- }
-}
-
-void IMuseDigital::fadeOutMusic(int fadeDelay) {
- Common::StackLock lock(_mutex, "IMuseDigital::fadeOutMusic()");
- debug(5, "IMuseDigital::fadeOutMusic");
-
- for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
- Track *track = _track[l];
- if (track->used && !track->toBeRemoved && (track->volGroupId == IMUSE_VOLGRP_MUSIC)) {
- cloneToFadeOutTrack(track, fadeDelay);
- track->toBeRemoved = true;
- }
- }
-}
-
-IMuseDigital::Track *IMuseDigital::cloneToFadeOutTrack(Track *track, int fadeDelay) {
- Common::StackLock lock(_mutex, "IMuseDigital::cloneToFadeOutTrack()");
- assert(track);
- Track *fadeTrack = 0;
-
- debug(5, "IMuseDigital::cloneToFadeOutTrack(%d, %d)", track->trackId, fadeDelay);
-
- if (_track[track->trackId + MAX_DIGITAL_TRACKS]->used) {
- warning("IMuseDigital::cloneToFadeOutTrack: Not free fade track");
- return NULL;
- }
-
- fadeTrack = _track[track->trackId + MAX_DIGITAL_TRACKS];
- fadeTrack->pan = track->pan;
- fadeTrack->vol = track->vol;
- fadeTrack->volGroupId = track->volGroupId;
- fadeTrack->priority = track->priority;
- fadeTrack->soundId = track->soundId;
- fadeTrack->dataOffset = track->dataOffset;
- fadeTrack->regionOffset = track->regionOffset;
- fadeTrack->curRegion = track->curRegion;
- fadeTrack->curHookId = track->curHookId;
- fadeTrack->iteration = track->iteration;
- fadeTrack->mixerFlags = track->mixerFlags;
- fadeTrack->mod = track->mod;
- fadeTrack->toBeRemoved = track->toBeRemoved;
- fadeTrack->readyToRemove = track->readyToRemove;
- fadeTrack->souStream = track->souStream;
- fadeTrack->started = track->started;
- fadeTrack->stream2 = track->stream2;
- strcpy(fadeTrack->soundName, track->soundName);
- fadeTrack->soundType = track->soundType;
- fadeTrack->soundHandle = _sound->cloneSound(track->soundHandle);
- assert(fadeTrack->soundHandle);
-
- fadeTrack->volFadeDelay = fadeDelay;
- fadeTrack->volFadeDest = 0;
- fadeTrack->volFadeStep = (fadeTrack->volFadeDest - fadeTrack->vol) * 60 * (1000 / _callbackFps) / (1000 * fadeDelay);
- fadeTrack->volFadeUsed = true;
-
- Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
-
- if (fadeTrack->volGroupId == 1)
- type = Audio::Mixer::kSpeechSoundType;
- if (fadeTrack->volGroupId == 2)
- type = Audio::Mixer::kSFXSoundType;
- if (fadeTrack->volGroupId == 3)
- type = Audio::Mixer::kMusicSoundType;
-
- // setup 1 second stream wrapped buffer
- int32 streamBufferSize = fadeTrack->iteration;
- fadeTrack->stream = makeAppendableAudioStream(_sound->getFreq(fadeTrack->soundHandle), fadeTrack->mixerFlags, streamBufferSize);
- _vm->_mixer->playInputStream(type, &fadeTrack->handle, fadeTrack->stream, -1, fadeTrack->vol / 1000, fadeTrack->pan, false);
- fadeTrack->started = true;
- fadeTrack->used = true;
-
- return fadeTrack;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/imuse_internal.h b/scumm/imuse_internal.h
deleted file mode 100644
index aa9b49cb00..0000000000
--- a/scumm/imuse_internal.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef DEFINED_IMUSE_INTERNAL
-#define DEFINED_IMUSE_INTERNAL
-
-#include "common/scummsys.h"
-#include "scumm/instrument.h"
-#include "scumm/saveload.h"
-#include "sound/mididrv.h"
-
-class MidiParser;
-class OSystem;
-
-namespace Scumm {
-
-// Unremark this statement to activate some of
-// the most common iMuse diagnostic messages.
-// #define IMUSE_DEBUG
-
-struct ParameterFader;
-struct DeferredCommand;
-struct ImTrigger;
-struct SustainingNotes;
-struct CommandQueue;
-struct IsNoteCmdData;
-class Player;
-struct Part;
-class IMuseInternal;
-
-// Some entities also referenced
-class ScummEngine;
-
-
-
-//////////////////////////////////////////////////
-//
-// Some constants
-//
-//////////////////////////////////////////////////
-
-#define TICKS_PER_BEAT 480
-
-#define TRIGGER_ID 0
-#define COMMAND_ID 1
-
-#define MDPG_TAG "MDpg"
-
-
-////////////////////////////////////////
-//
-// Helper functions
-//
-////////////////////////////////////////
-
-inline int clamp(int val, int min, int max) {
- if (val < min)
- return min;
- if (val > max)
- return max;
- return val;
-}
-
-inline int transpose_clamp(int a, int b, int c) {
- if (b > a)
- a += (b - a + 11) / 12 * 12;
- if (c < a)
- a -= (a - c + 11) / 12 * 12;
- return a;
-}
-
-
-
-//////////////////////////////////////////////////
-//
-// Entity declarations
-//
-//////////////////////////////////////////////////
-
-struct HookDatas {
- byte _jump[2];
- byte _transpose;
- byte _part_onoff[16];
- byte _part_volume[16];
- byte _part_program[16];
- byte _part_transpose[16];
-
- int query_param(int param, byte chan);
- int set(byte cls, byte value, byte chan);
- HookDatas() { memset(this, 0, sizeof(HookDatas)); }
-};
-
-struct ParameterFader {
- enum {
- pfVolume = 1,
- pfTranspose = 3,
- pfSpeed = 4
- };
-
- int param;
- int start;
- int end;
- uint32 total_time;
- uint32 current_time;
-
- ParameterFader() { param = 0; }
- void init() { param = 0; }
-};
-
-struct DeferredCommand {
- uint32 time_left;
- int a, b, c, d, e, f;
- DeferredCommand() { memset(this, 0, sizeof(DeferredCommand)); }
-};
-
-struct ImTrigger {
- int sound;
- byte id;
- uint16 expire;
- int command [8];
- ImTrigger() { memset(this, 0, sizeof(ImTrigger)); }
-};
-
-struct CommandQueue {
- uint16 array[8];
- CommandQueue() { memset(this, 0, sizeof(CommandQueue)); }
-};
-
-class Player : public MidiDriver {
-protected:
- // Moved from IMuseInternal.
- // This is only used by one player at a time.
- static uint16 _active_notes[128];
-
-protected:
- MidiDriver *_midi;
- MidiParser *_parser;
- bool _passThrough; // Only respond to EOT, all else direct to MidiDriver
-
- Part *_parts;
- bool _active;
- bool _scanning;
- int _id;
- byte _priority;
- byte _volume;
- int8 _pan;
- int8 _transpose;
- int8 _detune;
- byte _vol_eff;
-
- uint _track_index;
- uint _loop_to_beat;
- uint _loop_from_beat;
- uint _loop_counter;
- uint _loop_to_tick;
- uint _loop_from_tick;
- byte _speed;
- bool _abort;
-
- // This does not get used by us! It is only
- // here for save/load purposes, and gets
- // passed on to the MidiParser during
- // fixAfterLoad().
- uint32 _music_tick;
-
- HookDatas _hook;
- ParameterFader _parameterFaders[4];
-
- bool _isMT32;
- bool _isMIDI;
-
-protected:
- // Player part
- void hook_clear();
- void uninit_parts();
- byte *parse_midi(byte *s);
- void part_set_transpose(uint8 chan, byte relative, int8 b);
- void parse_sysex(byte *p, uint len);
- void maybe_jump(byte cmd, uint track, uint beat, uint tick);
- void maybe_set_transpose(byte *data);
- void maybe_part_onoff(byte *data);
- void maybe_set_volume(byte *data);
- void maybe_set_program(byte *data);
- void maybe_set_transpose_part(byte *data);
- void turn_off_pedals();
- int query_part_param(int param, byte chan);
- void turn_off_parts();
- void play_active_notes();
-
- void transitionParameters();
-
- static void decode_sysex_bytes(const byte *src, byte *dst, int len);
-
- // Sequencer part
- int start_seq_sound(int sound, bool reset_vars = true);
- int query_param(int param);
-
-public:
- IMuseInternal *_se;
- uint _vol_chan;
-
-public:
- Player();
- virtual ~Player();
-
- int addParameterFader(int param, int target, int time);
- void clear();
- void clearLoop();
- void fixAfterLoad();
- Part * getActivePart(uint8 part);
- uint getBeatIndex();
- int8 getDetune() const { return _detune; }
- byte getEffectiveVolume() const { return _vol_eff; }
- int getID() const { return _id; }
- MidiDriver *getMidiDriver() const { return _midi; }
- int getParam(int param, byte chan);
- int8 getPan() const { return _pan; }
- Part * getPart(uint8 part);
- byte getPriority() const { return _priority; }
- uint getTicksPerBeat() const { return TICKS_PER_BEAT; }
- int8 getTranspose() const { return _transpose; }
- byte getVolume() const { return _volume; }
- bool isActive() const { return _active; }
- bool isFadingOut() const;
- bool isMIDI() const { return _isMIDI; }
- bool isMT32() const { return _isMT32; }
- bool jump(uint track, uint beat, uint tick);
- void onTimer();
- void removePart(Part *part);
- int scan(uint totrack, uint tobeat, uint totick);
- void saveLoadWithSerializer(Serializer *ser);
- int setHook(byte cls, byte value, byte chan) { return _hook.set(cls, value, chan); }
- void setDetune(int detune);
- bool setLoop(uint count, uint tobeat, uint totick, uint frombeat, uint fromtick);
- void setPan(int pan);
- void setPriority(int pri);
- void setSpeed(byte speed);
- int setTranspose(byte relative, int b);
- int setVolume(byte vol);
- bool startSound(int sound, MidiDriver *midi, bool passThrough);
- int getMusicTimer() const;
-
-public:
- // MidiDriver interface
- int open() { return 0; }
- void close() { }
- void send(uint32 b);
- const char *getErrorName(int error_code) { return "Unknown"; }
- void sysEx(byte *msg, uint16 length);
- void metaEvent(byte type, byte *data, uint16 length);
- void setTimerCallback(void *timer_param, void(*timer_proc)(void *)) { }
- uint32 getBaseTempo();
- MidiChannel *allocateChannel() { return 0; }
- MidiChannel *getPercussionChannel() { return 0; }
-};
-
-struct Part : public Serializable {
- IMuseInternal *_se;
- int _slot;
- Part *_next, *_prev;
- MidiChannel *_mc;
- Player *_player;
- int16 _pitchbend;
- byte _pitchbend_factor;
- int8 _transpose, _transpose_eff;
- byte _vol, _vol_eff;
- int8 _detune, _detune_eff;
- int8 _pan, _pan_eff;
- bool _on;
- byte _modwheel;
- bool _pedal;
- int8 _pri;
- byte _pri_eff;
- byte _chan;
- byte _effect_level;
- byte _chorus;
- byte _percussion;
- byte _bank;
-
- // New abstract instrument definition
- Instrument _instrument;
- bool _unassigned_instrument; // For diagnostic reporting purposes only
-
- // MidiChannel interface
- // (We don't currently derive from MidiChannel,
- // but if we ever do, this will make it easy.)
- void noteOff(byte note);
- void noteOn(byte note, byte velocity);
- void programChange(byte value);
- void pitchBend(int16 value);
- void modulationWheel(byte value);
- void volume(byte value);
- void pitchBendFactor(byte value);
- void sustain(bool value);
- void effectLevel(byte value);
- void chorusLevel(byte value);
- void allNotesOff();
-
- void set_param(byte param, int value) { }
- void init();
- void setup(Player *player);
- void uninit();
- void off();
- void set_instrument(uint b);
- void set_instrument(byte *data);
- void load_global_instrument(byte b);
-
- void set_transpose(int8 transpose);
- void set_detune(int8 detune);
- void set_pri(int8 pri);
- void set_pan(int8 pan);
-
- void set_onoff(bool on);
- void fix_after_load();
-
- void sendAll();
- void sendPitchBend();
- bool clearToTransmit();
-
- Part();
-
- void saveLoadWithSerializer(Serializer *ser);
-};
-
-// WARNING: This is the internal variant of the IMUSE class.
-// imuse.h contains a public version of the same class.
-// the public version, only contains a set of methods.
-class IMuseInternal {
- friend class Player;
- friend struct Part;
-
-protected:
- bool _native_mt32;
- bool _enable_gs;
- bool _sc55;
- MidiDriver *_midi_adlib;
- MidiDriver *_midi_native;
-
- byte **_base_sounds;
-
-protected:
- bool _paused;
- bool _initialized;
-
- int _tempoFactor;
-
- int _player_limit; // Limits how many simultaneous music tracks are played
- bool _recycle_players; // Can we stop a player in order to start another one?
- bool _direct_passthrough; // Pass data direct to MidiDriver (no interactivity)
-
- uint _queue_end, _queue_pos, _queue_sound;
- byte _queue_adding;
-
- byte _queue_marker;
- byte _queue_cleared;
- byte _master_volume; // Master volume. 0-255
- byte _music_volume; // Global music volume. 0-255
-
- uint16 _trigger_count;
- ImTrigger _snm_triggers[16]; // Sam & Max triggers
- uint16 _snm_trigger_index;
-
- uint16 _channel_volume[8];
- uint16 _channel_volume_eff[8]; // No Save
- uint16 _volchan_table[8];
-
- Player _players[8];
- Part _parts[32];
-
- Instrument _global_adlib_instruments[32];
- CommandQueue _cmd_queue[64];
- DeferredCommand _deferredCommands[4];
-
-protected:
- byte *findStartOfSound(int sound);
- bool isMT32(int sound);
- bool isMIDI(int sound);
- int get_queue_sound_status(int sound) const;
- void handle_marker(uint id, byte data);
- int get_channel_volume(uint a);
- void initMidiDriver(MidiDriver *midi);
- void initGM(MidiDriver *midi);
- void initMT32(MidiDriver *midi);
- void init_players();
- void init_parts();
- void init_queue();
-
- void sequencer_timers(MidiDriver *midi);
-
- MidiDriver *getBestMidiDriver(int sound);
- Player *allocate_player(byte priority);
- Part *allocate_part(byte pri, MidiDriver *midi);
-
- int32 ImSetTrigger(int sound, int id, int a, int b, int c, int d, int e, int f, int g, int h);
- int32 ImClearTrigger(int sound, int id);
- int32 ImFireAllTriggers(int sound);
-
- void addDeferredCommand(int time, int a, int b, int c, int d, int e, int f);
- void handleDeferredCommands(MidiDriver *midi);
-
- int enqueue_command(int a, int b, int c, int d, int e, int f, int g);
- int enqueue_trigger(int sound, int marker);
- int query_queue(int param);
- Player *findActivePlayer(int id);
-
- int get_volchan_entry(uint a);
- int set_volchan_entry(uint a, uint b);
- int set_channel_volume(uint chan, uint vol);
- void update_volumes();
- void reset_tick();
-
- int set_volchan(int sound, int volchan);
-
- void fix_parts_after_load();
- void fix_players_after_load(ScummEngine *scumm);
-
- static void midiTimerCallback(void *data);
-
-public:
- IMuseInternal();
-
- int initialize(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver);
- void reallocateMidiChannels(MidiDriver *midi);
- void setGlobalAdlibInstrument(byte slot, byte *data);
- void copyGlobalAdlibInstrument(byte slot, Instrument *dest);
- bool isNativeMT32() { return _native_mt32; }
-
- // IMuse interface
-
- void on_timer(MidiDriver *midi);
- void pause(bool paused);
- int terminate1();
- int terminate2();
- int save_or_load(Serializer *ser, ScummEngine *scumm);
- int setMusicVolume(uint vol);
- int setImuseMasterVolume(uint vol);
- bool startSound(int sound);
- int stopSound(int sound);
- int stopAllSounds();
- int getSoundStatus(int sound, bool ignoreFadeouts = true) const;
- int getMusicTimer() const;
- int32 doCommand (int a, int b, int c, int d, int e, int f, int g, int h);
- int32 doCommand (int numargs, int args[]);
- int clear_queue();
- void setBase(byte **base);
- uint32 property(int prop, uint32 value);
-
- static IMuseInternal *create(OSystem *syst, MidiDriver *nativeMidiDriver, MidiDriver *adlibMidiDriver);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/imuse_player.cpp b/scumm/imuse_player.cpp
deleted file mode 100644
index 06ebd289cd..0000000000
--- a/scumm/imuse_player.cpp
+++ /dev/null
@@ -1,1241 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-
-#include "common/util.h"
-#include "base/engine.h"
-
-#include "scumm/imuse_internal.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-
-#include "sound/midiparser.h"
-
-namespace Scumm {
-
-////////////////////////////////////////
-//
-// Miscellaneous
-//
-////////////////////////////////////////
-
-#define IMUSE_SYSEX_ID 0x7D
-#define YM2612_SYSEX_ID 0x7C
-#define ROLAND_SYSEX_ID 0x41
-#define PERCUSSION_CHANNEL 9
-
-extern MidiParser *MidiParser_createRO();
-extern MidiParser *MidiParser_createEUP();
-
-uint16 Player::_active_notes[128];
-
-
-
-//////////////////////////////////////////////////
-//
-// IMuse Player implementation
-//
-//////////////////////////////////////////////////
-
-Player::Player() :
- _midi(0),
- _parser(0),
- _passThrough(0),
- _parts(0),
- _active(false),
- _scanning(false),
- _id(0),
- _priority(0),
- _volume(0),
- _pan(0),
- _transpose(0),
- _detune(0),
- _vol_eff(0),
- _track_index(0),
- _loop_to_beat(0),
- _loop_from_beat(0),
- _loop_counter(0),
- _loop_to_tick(0),
- _loop_from_tick(0),
- _speed(128),
- _isMT32(false),
- _isMIDI(false),
- _se(0),
- _vol_chan(0){
-}
-
-Player::~Player() {
- if (_parser) {
- delete _parser;
- _parser = 0;
- }
-}
-
-bool Player::startSound(int sound, MidiDriver *midi, bool passThrough) {
- void *ptr;
- int i;
-
- // Not sure what the old code was doing,
- // but we'll go ahead and do a similar check.
- ptr = _se->findStartOfSound(sound);
- if (!ptr) {
- error("Player::startSound(): Couldn't find start of sound %d!", sound);
- return false;
- }
-
- _isMT32 = _se->isMT32(sound);
- _isMIDI = _se->isMIDI(sound);
-
- _parts = NULL;
- _active = true;
- _midi = midi;
- _id = sound;
- _priority = 0x80;
- _volume = 0x7F;
- _vol_chan = 0xFFFF;
- _vol_eff = (_se->get_channel_volume(0xFFFF) << 7) >> 7;
- _pan = 0;
- _transpose = 0;
- _detune = 0;
- _passThrough = passThrough;
-
- for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i)
- _parameterFaders[i].init();
- hook_clear();
-
- if (start_seq_sound(sound) != 0) {
- _active = false;
- _midi = NULL;
- return false;
- }
-
-#ifdef IMUSE_DEBUG
- debug(0, "Starting music %d", sound);
-#endif
- return true;
-}
-
-int Player::getMusicTimer() const {
- return _parser ? (_parser->getTick() * 2 / _parser->getPPQN()) : 0;
-}
-
-bool Player::isFadingOut() const {
- int i;
- for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) {
- if (_parameterFaders[i].param == ParameterFader::pfVolume &&
- _parameterFaders[i].end == 0) {
- return true;
- }
- }
- return false;
-}
-
-void Player::clear() {
- if (!_active)
- return;
-
-#ifdef IMUSE_DEBUG
- debug(0, "Stopping music %d", _id);
-#endif
-
- if (_parser) {
- _parser->unloadMusic();
- delete _parser;
- _parser = 0;
- }
- uninit_parts();
- _se->ImFireAllTriggers(_id);
- _active = false;
- _midi = NULL;
- _id = 0;
-}
-
-void Player::hook_clear() {
- memset(&_hook, 0, sizeof(_hook));
-}
-
-int Player::start_seq_sound(int sound, bool reset_vars) {
- byte *ptr;
-
- if (reset_vars) {
- _loop_to_beat = 1;
- _loop_from_beat = 1;
- _track_index = 0;
- _loop_counter = 0;
- _loop_to_tick = 0;
- _loop_from_tick = 0;
- }
-
- ptr = _se->findStartOfSound(sound);
- if (ptr == NULL)
- return -1;
- if (_parser)
- delete _parser;
-
- if (!memcmp(ptr, "RO", 2)) {
- // Old style 'RO' resource
- _parser = MidiParser_createRO();
- } else if (!memcmp(ptr, "SO", 2)) {
- // Euphony (FM-TOWNS) resource
- _parser = MidiParser_createEUP();
- } else if (!memcmp(ptr, "FORM", 4)) {
- // Humongous Games XMIDI resource
- _parser = MidiParser::createParser_XMIDI();
- } else {
- // SCUMM SMF resource
- _parser = MidiParser::createParser_SMF();
- }
-
- _parser->setMidiDriver(this);
- _parser->property(MidiParser::mpSmartJump, 1);
- _parser->loadMusic(ptr, 0);
- _parser->setTrack(_track_index);
- setSpeed(reset_vars ? 128 : _speed);
-
- return 0;
-}
-
-void Player::uninit_parts() {
- if (_parts && _parts->_player != this)
- error("asd");
- while (_parts)
- _parts->uninit();
-
- // In case another player is waiting to allocate parts
- if (_midi)
- _se->reallocateMidiChannels(_midi);
-}
-
-void Player::setSpeed(byte speed) {
- _speed = speed;
- if (_parser)
- _parser->setTimerRate(((_midi->getBaseTempo() * speed) >> 7) * _se->_tempoFactor / 100);
-}
-
-void Player::send(uint32 b) {
- if (_passThrough) {
- _midi->send(b);
- return;
- }
-
- byte cmd = (byte)(b & 0xF0);
- byte chan = (byte)(b & 0x0F);
- byte param1 = (byte)((b >> 8) & 0xFF);
- byte param2 = (byte)((b >> 16) & 0xFF);
- Part *part;
-
- switch (cmd >> 4) {
- case 0x8: // Key Off
- if (!_scanning) {
- if ((part = getPart(chan)) != 0)
- part->noteOff(param1);
- } else {
- _active_notes[param1] &= ~(1 << chan);
- }
- break;
-
- case 0x9: // Key On
- if (!_scanning) {
- if (_isMT32 && !_se->isNativeMT32())
- param2 = (((param2 * 3) >> 2) + 32) & 0x7F;
- if ((part = getPart(chan)) != 0)
- part->noteOn(param1, param2);
- } else {
- _active_notes[param1] |= (1 << chan);
- }
- break;
-
- case 0xB: // Control Change
- part = (param1 == 123 ? getActivePart(chan) : getPart(chan));
- if (!part)
- break;
-
- switch (param1) {
- case 0: // Bank select. Not supported
- break;
- case 1: // Modulation Wheel
- part->modulationWheel(param2);
- break;
- case 7: // Volume
- part->volume(param2);
- break;
- case 10: // Pan Position
- part->set_pan(param2 - 0x40);
- break;
- case 16: // Pitchbend Factor(non-standard)
- part->pitchBendFactor(param2);
- break;
- case 17: // GP Slider 2
- part->set_detune(param2 - 0x40);
- break;
- case 18: // GP Slider 3
- part->set_pri(param2 - 0x40);
- _se->reallocateMidiChannels(_midi);
- break;
- case 64: // Sustain Pedal
- part->sustain(param2 != 0);
- break;
- case 91: // Effects Level
- part->effectLevel(param2);
- break;
- case 93: // Chorus Level
- part->chorusLevel(param2);
- break;
- case 116: // XMIDI For Loop. Not supported
- // Used in the ending sequence of puttputt
- break;
- case 117: // XMIDI Next/Break. Not supported
- // Used in the ending sequence of puttputt
- break;
- case 123: // All Notes Off
- part->allNotesOff();
- break;
- default:
- error("Player::send(): Invalid control change %d", param1);
- }
- break;
-
- case 0xC: // Program Change
- part = getPart(chan);
- if (part) {
- if (_isMIDI) {
- if (param1 < 128)
- part->programChange(param1);
- } else {
- if (param1 < 32)
- part->load_global_instrument(param1);
- }
- }
- break;
-
- case 0xE: // Pitch Bend
- part = getPart(chan);
- if (part)
- part->pitchBend(((param2 << 7) | param1) - 0x2000);
- break;
-
- case 0xA: // Aftertouch
- case 0xD: // Channel Pressure
- case 0xF: // Sequence Controls
- break;
-
- default:
- if (!_scanning) {
- error("Player::send(): Invalid command %d", cmd);
- clear();
- }
- }
- return;
-}
-
-void Player::sysEx(byte *p, uint16 len) {
- byte code;
- byte a;
- uint b;
- byte buf[128];
- Part *part;
-
- if (_passThrough) {
- _midi->sysEx(p, len);
- return;
- }
-
- // Check SysEx manufacturer.
- a = *p++;
- --len;
- if (a != IMUSE_SYSEX_ID) {
- if (a == ROLAND_SYSEX_ID) {
- // Roland custom instrument definition.
- part = getPart(p[0] & 0x0F);
- if (part) {
- part->_instrument.roland(p - 1);
- if (part->clearToTransmit())
- part->_instrument.send(part->_mc);
- }
- } else if (a == YM2612_SYSEX_ID) {
- // FM-TOWNS custom instrument definition
- _midi->sysEx_customInstrument(p[0], 'EUP ', p + 1);
- } else {
- error("Unknown SysEx manufacturer 0x%02X", (int)a);
- }
- return;
- }
- --len;
-
- // Too big?
- if (len >= sizeof(buf) * 2)
- return;
-
-#ifdef IMUSE_DEBUG
- if (!_scanning) {
- for (a = 0; a < len + 1 && a < 19; ++a) {
- sprintf((char *)&buf[a*3], " %02X", p[a]);
- } // next for
- if (a < len + 1) {
- buf[a*3] = buf[a*3+1] = buf[a*3+2] = '.';
- ++a;
- } // end if
- buf[a*3] = '\0';
- debug(0, "[%02d] SysEx:%s", _id, buf);
- }
-#endif
-
- switch (code = *p++) {
- case 0:
- if (g_scumm->_gameId != GID_SAMNMAX) {
- // There are 17 bytes of useful information beyond
- // what we've read so far. All we know about them is
- // as follows:
- // BYTE 00: Channel #
- // BYTE 02: BIT 01(0x01): Part on?(1 = yes)
- // BYTE 04: Priority adjustment [guessing]
- // BYTE 05: Volume(upper 4 bits) [guessing]
- // BYTE 06: Volume(lower 4 bits) [guessing]
- // BYTE 09: BIT 04(0x08): Percussion?(1 = yes)
- // BYTE 15: Program(upper 4 bits)
- // BYTE 16: Program(lower 4 bits)
- part = getPart(p[0] & 0x0F);
- if (part) {
- part->set_onoff(p[2] & 0x01);
- part->set_pri(p[4]);
- part->volume((p[5] & 0x0F) << 4 |(p[6] & 0x0F));
- part->_percussion = _isMIDI ? ((p[9] & 0x08) > 0) : false;
- if (part->_percussion) {
- if (part->_mc) {
- part->off();
- _se->reallocateMidiChannels(_midi);
- }
- } else {
- // Even in cases where a program does not seem to be specified,
- // i.e. bytes 15 and 16 are 0, we send a program change because
- // 0 is a valid program number. MI2 tests show that in such
- // cases, a regular program change message always seems to follow
- // anyway.
- if (_isMIDI)
- part->_instrument.program((p[15] & 0x0F) << 4 |(p[16] & 0x0F), _isMT32);
- part->sendAll();
- }
- }
- } else {
- // Sam & Max: Trigger Event
- // Triggers are set by doCommand(ImSetTrigger).
- // When a SysEx marker is encountered whose sound
- // ID and marker ID match what was set by ImSetTrigger,
- // something magical is supposed to happen....
- for (a = 0; a < ARRAYSIZE(_se->_snm_triggers); ++a) {
- if (_se->_snm_triggers[a].sound == _id &&
- _se->_snm_triggers[a].id == *p)
- {
- _se->_snm_triggers[a].sound = _se->_snm_triggers[a].id = 0;
- _se->doCommand(8, _se->_snm_triggers[a].command);
- break;
- }
- }
- } // end if
- break;
-
- case 1:
- // This SysEx is used in Sam & Max for maybe_jump.
- if (_scanning)
- break;
- maybe_jump(p[0], p[1] - 1, (READ_BE_UINT16(p + 2) - 1) * 4 + p[4], ((p[5] * TICKS_PER_BEAT) >> 2) + p[6]);
- break;
-
- case 2: // Start of song. Ignore for now.
- break;
-
- case 16: // Adlib instrument definition(Part)
- a = *p++ & 0x0F;
- ++p; // Skip hardware type
- part = getPart(a);
- if (part) {
- if (len == 63) {
- decode_sysex_bytes(p, buf, len - 3);
- part->set_instrument((byte *)buf);
- } else {
- // SPK tracks have len == 49 here, and are not supported
- part->programChange(254); // Must be invalid, but not 255 (which is reserved)
- }
- }
- break;
-
- case 17: // Adlib instrument definition(Global)
- p += 2; // Skip hardware type and... whatever came right before it
- a = *p++;
- decode_sysex_bytes(p, buf, len - 4);
- _se->setGlobalAdlibInstrument(a, buf);
- break;
-
- case 33: // Parameter adjust
- a = *p++ & 0x0F;
- ++p; // Skip hardware type
- decode_sysex_bytes(p, buf, len - 3);
- part = getPart(a);
- if (part)
- part->set_param(READ_BE_UINT16(buf), READ_BE_UINT16(buf + 2));
- break;
-
- case 48: // Hook - jump
- if (_scanning)
- break;
- decode_sysex_bytes(p + 1, buf, len - 2);
- maybe_jump(buf[0], READ_BE_UINT16(buf + 1), READ_BE_UINT16(buf + 3), READ_BE_UINT16(buf + 5));
- break;
-
- case 49: // Hook - global transpose
- decode_sysex_bytes(p + 1, buf, len - 2);
- maybe_set_transpose(buf);
- break;
-
- case 50: // Hook - part on/off
- buf[0] = *p++ & 0x0F;
- decode_sysex_bytes(p, buf + 1, len - 2);
- maybe_part_onoff(buf);
- break;
-
- case 51: // Hook - set volume
- buf[0] = *p++ & 0x0F;
- decode_sysex_bytes(p, buf + 1, len - 2);
- maybe_set_volume(buf);
- break;
-
- case 52: // Hook - set program
- buf[0] = *p++ & 0x0F;
- decode_sysex_bytes(p, buf + 1, len - 2);
- maybe_set_program(buf);
- break;
-
- case 53: // Hook - set transpose
- buf[0] = *p++ & 0x0F;
- decode_sysex_bytes(p, buf + 1, len - 2);
- maybe_set_transpose_part(buf);
- break;
-
- case 64: // Marker
- p++;
- len -= 2;
- while (len--) {
- _se->handle_marker(_id, *p++);
- }
- break;
-
- case 80: // Loop
- decode_sysex_bytes(p + 1, buf, len - 2);
- setLoop(READ_BE_UINT16(buf), READ_BE_UINT16(buf + 2),
- READ_BE_UINT16(buf + 4), READ_BE_UINT16(buf + 6),
- READ_BE_UINT16(buf + 8));
- break;
-
- case 81: // End loop
- clearLoop();
- break;
-
- case 96: // Set instrument
- part = getPart(p[0] & 0x0F);
- b = (p[1] & 0x0F) << 12 |(p[2] & 0x0F) << 8 |(p[4] & 0x0F) << 4 |(p[4] & 0x0F);
- if (part)
- part->set_instrument(b);
- break;
-
- default:
- error("Unknown SysEx command %d", (int)code);
- }
-}
-
-void Player::decode_sysex_bytes(const byte *src, byte *dst, int len) {
- while (len >= 0) {
- *dst++ = ((src[0] << 4)&0xFF) | (src[1] & 0xF);
- src += 2;
- len -= 2;
- }
-}
-
-void Player::maybe_jump(byte cmd, uint track, uint beat, uint tick) {
- // Is this the hook I'm waiting for?
- if (cmd && _hook._jump[0] != cmd)
- return;
-
- // Reset hook?
- if (cmd != 0 && cmd < 0x80) {
- _hook._jump[0] = _hook._jump[1];
- _hook._jump[1] = 0;
- }
-
- jump(track, beat, tick);
-}
-
-void Player::maybe_set_transpose(byte *data) {
- byte cmd;
-
- cmd = data[0];
-
- // Is this the hook I'm waiting for?
- if (cmd && _hook._transpose != cmd)
- return;
-
- // Reset hook?
- if (cmd != 0 && cmd < 0x80)
- _hook._transpose = 0;
-
- setTranspose(data[1], (int8)data[2]);
-}
-
-void Player::maybe_part_onoff(byte *data) {
- byte cmd, *p;
- uint chan;
- Part *part;
-
- cmd = data[1];
- chan = data[0];
-
- p = &_hook._part_onoff[chan];
-
- // Is this the hook I'm waiting for?
- if (cmd && *p != cmd)
- return;
-
- if (cmd != 0 && cmd < 0x80)
- *p = 0;
-
- part = getPart(chan);
- if (part)
- part->set_onoff(data[2] != 0);
-}
-
-void Player::maybe_set_volume(byte *data) {
- byte cmd;
- byte *p;
- uint chan;
- Part *part;
-
- cmd = data[1];
- chan = data[0];
-
- p = &_hook._part_volume[chan];
-
- // Is this the hook I'm waiting for?
- if (cmd && *p != cmd)
- return;
-
- // Reset hook?
- if (cmd != 0 && cmd < 0x80)
- *p = 0;
-
- part = getPart(chan);
- if (part)
- part->volume(data[2]);
-}
-
-void Player::maybe_set_program(byte *data) {
- byte cmd;
- byte *p;
- uint chan;
- Part *part;
-
- cmd = data[1];
- chan = data[0];
-
- // Is this the hook I'm waiting for?
- p = &_hook._part_program[chan];
-
- if (cmd && *p != cmd)
- return;
-
- if (cmd != 0 && cmd < 0x80)
- *p = 0;
-
- part = getPart(chan);
- if (part)
- part->programChange(data[2]);
-}
-
-void Player::maybe_set_transpose_part(byte *data) {
- byte cmd;
- byte *p;
- uint chan;
-
- cmd = data[1];
- chan = data[0];
-
- // Is this the hook I'm waiting for?
- p = &_hook._part_transpose[chan];
-
- if (cmd && *p != cmd)
- return;
-
- // Reset hook?
- if (cmd != 0 && cmd < 0x80)
- *p = 0;
-
- part_set_transpose(chan, data[2], (int8)data[3]);
-}
-
-int Player::setTranspose(byte relative, int b) {
- Part *part;
-
- if (b > 24 || b < -24 || relative > 1)
- return -1;
- if (relative)
- b = transpose_clamp(_transpose + b, -24, 24);
-
- _transpose = b;
-
- for (part = _parts; part; part = part->_next) {
- part->set_transpose(part->_transpose);
- }
-
- return 0;
-}
-
-void Player::part_set_transpose(uint8 chan, byte relative, int8 b) {
- Part *part;
-
- if (b > 24 || b < -24)
- return;
-
- part = getPart(chan);
- if (!part)
- return;
- if (relative)
- b = transpose_clamp(b + part->_transpose, -7, 7);
- part->set_transpose(b);
-}
-
-bool Player::jump(uint track, uint beat, uint tick) {
- if (!_parser)
- return false;
- if (_parser->setTrack(track))
- _track_index = track;
- if (!_parser->jumpToTick((beat - 1) * TICKS_PER_BEAT + tick))
- return false;
- turn_off_pedals();
- return true;
-}
-
-bool Player::setLoop(uint count, uint tobeat, uint totick, uint frombeat, uint fromtick) {
- if (tobeat + 1 >= frombeat)
- return false;
-
- if (tobeat == 0)
- tobeat = 1;
-
- _loop_counter = 0; // Because of possible interrupts
- _loop_to_beat = tobeat;
- _loop_to_tick = totick;
- _loop_from_beat = frombeat;
- _loop_from_tick = fromtick;
- _loop_counter = count;
-
- return true;
-}
-
-void Player::clearLoop() {
- _loop_counter = 0;
-}
-
-void Player::turn_off_pedals() {
- Part *part;
-
- for (part = _parts; part; part = part->_next) {
- if (part->_pedal)
- part->sustain(false);
- }
-}
-
-Part *Player::getActivePart(uint8 chan) {
- Part *part = _parts;
- while (part) {
- if (part->_chan == chan)
- return part;
- part = part->_next;
- }
- return 0;
-}
-
-Part *Player::getPart(uint8 chan) {
- Part *part = getActivePart(chan);
- if (part)
- return part;
-
- part = _se->allocate_part(_priority, _midi);
- if (!part) {
- debug(1, "No parts available");
- return NULL;
- }
-
- // Insert part into front of parts list
- part->_prev = NULL;
- part->_next = _parts;
- if (_parts)
- _parts->_prev = part;
- _parts = part;
-
-
- part->_chan = chan;
- part->setup(this);
-
- return part;
-}
-
-void Player::setPriority(int pri) {
- Part *part;
-
- _priority = pri;
- for (part = _parts; part; part = part->_next) {
- part->set_pri(part->_pri);
- }
- _se->reallocateMidiChannels(_midi);
-}
-
-void Player::setPan(int pan) {
- Part *part;
-
- _pan = pan;
- for (part = _parts; part; part = part->_next) {
- part->set_pan(part->_pan);
- }
-}
-
-void Player::setDetune(int detune) {
- Part *part;
-
- _detune = detune;
- for (part = _parts; part; part = part->_next) {
- part->set_detune(part->_detune);
- }
-}
-
-int Player::scan(uint totrack, uint tobeat, uint totick) {
- if (!_active || !_parser)
- return -1;
-
- if (tobeat == 0)
- tobeat++;
-
- turn_off_parts();
- memset(_active_notes, 0, sizeof(_active_notes));
- _scanning = true;
-
- // If the scan involves a track switch, scan to the end of
- // the current track so that our state when starting the
- // new track is fully up to date.
- if (totrack != _track_index)
- _parser->jumpToTick((uint32)-1, true);
- _parser->setTrack(totrack);
- if (!_parser->jumpToTick((tobeat - 1) * TICKS_PER_BEAT + totick, true)) {
- _scanning = false;
- return -1;
- }
-
- _scanning = false;
- _se->reallocateMidiChannels(_midi);
- play_active_notes();
-
- if (_track_index != totrack) {
- _track_index = totrack;
- _loop_counter = 0;
- }
- return 0;
-}
-
-void Player::turn_off_parts() {
- Part *part;
-
- for (part = _parts; part; part = part->_next)
- part->off();
- _se->reallocateMidiChannels(_midi);
-}
-
-void Player::play_active_notes() {
- int i, j;
- uint mask;
- Part *part;
-
- for (i = 0; i < 16; ++i) {
- part = getPart(i);
- if (part) {
- mask = 1 << i;
- for (j = 0; j < 128; ++j) {
- if (_active_notes[j] & mask)
- part->noteOn(j, 80);
- }
- }
- }
-}
-
-int Player::setVolume(byte vol) {
- Part *part;
-
- if (vol > 127)
- return -1;
-
- _volume = vol;
- _vol_eff = _se->get_channel_volume(_vol_chan) * (vol + 1) >> 7;
-
- for (part = _parts; part; part = part->_next) {
- part->volume(part->_vol);
- }
-
- return 0;
-}
-
-int Player::getParam(int param, byte chan) {
- switch (param) {
- case 0:
- return (byte)_priority;
- case 1:
- return (byte)_volume;
- case 2:
- return (byte)_pan;
- case 3:
- return (byte)_transpose;
- case 4:
- return (byte)_detune;
- case 5:
- return _speed;
- case 6:
- return _track_index;
- case 7:
- return getBeatIndex();
- case 8:
- return (_parser ? _parser->getTick() % TICKS_PER_BEAT : 0); // _tick_index;
- case 9:
- return _loop_counter;
- case 10:
- return _loop_to_beat;
- case 11:
- return _loop_to_tick;
- case 12:
- return _loop_from_beat;
- case 13:
- return _loop_from_tick;
- case 14:
- case 15:
- case 16:
- case 17:
- return query_part_param(param, chan);
- case 18:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- return _hook.query_param(param, chan);
- default:
- return -1;
- }
-}
-
-int Player::query_part_param(int param, byte chan) {
- Part *part;
-
- part = _parts;
- while (part) {
- if (part->_chan == chan) {
- switch (param) {
- case 14:
- return part->_on;
- case 15:
- return part->_vol;
- case 16:
-// FIXME: Need to know where this occurs...
-error("Trying to cast instrument (%d, %d) -- please tell Fingolfin\n", param, chan);
-// In old versions of the code, this used to return part->_program.
-// This was changed in revision 2.29 of imuse.cpp (where this code used
-// to reside).
-// return (int)part->_instrument;
- case 17:
- return part->_transpose;
- default:
- return -1;
- }
- }
- part = part->_next;
- }
- return 129;
-}
-
-void Player::onTimer() {
- // First handle any parameter transitions
- // that are occuring.
- transitionParameters();
-
- // Since the volume parameter can cause
- // the player to be deactivated, check
- // to make sure we're still active.
- if (!_active || !_parser)
- return;
-
- uint32 target_tick = _parser->getTick();
- uint beat_index = target_tick / TICKS_PER_BEAT + 1;
- uint tick_index = target_tick % TICKS_PER_BEAT;
-
- if (_loop_counter &&(beat_index > _loop_from_beat ||
- (beat_index == _loop_from_beat && tick_index >= _loop_from_tick)))
- {
- _loop_counter--;
- jump(_track_index, _loop_to_beat, _loop_to_tick);
- }
- _parser->onTimer();
-}
-
-// "time" is referenced as hundredths of a second.
-// IS THAT CORRECT??
-// We convert it to microseconds before proceeding
-int Player::addParameterFader(int param, int target, int time) {
- int start;
-
- switch (param) {
- case ParameterFader::pfVolume:
- // HACK: If volume is set to 0 with 0 time,
- // set it so immediately but DON'T clear
- // the player. This fixes a problem with
- // music being cleared inappropriately
- // in S&M when playing with the Dinosaur.
- if (!target && !time) {
- setVolume(0);
- return 0;
- }
-
- // Volume fades are handled differently.
- start = _volume;
- break;
-
- case ParameterFader::pfTranspose:
- // FIXME: Is this transpose? And what's the scale?
- // It's set to fade to -2400 in the tunnel of love.
-// debug(0, "parameterTransition(3) outside Tunnel of Love?");
- start = _transpose;
-// target /= 200;
- break;
-
- case ParameterFader::pfSpeed: // impSpeed
- // FIXME: Is the speed from 0-100?
- // Right now I convert it to 0-128.
- start = _speed;
-// target = target * 128 / 100;
- break;
-
- case 127:
- { // FIXME? I *think* this clears all parameter faders.
- ParameterFader *ptr = &_parameterFaders[0];
- int i;
- for (i = ARRAYSIZE(_parameterFaders); i; --i, ++ptr)
- ptr->param = 0;
- return 0;
- }
- break;
-
- default:
- debug(0, "Player::addParameterFader (%d, %d, %d): Unknown parameter", param, target, time);
- return 0; // Should be -1, but we'll let the script think it worked.
- }
-
- ParameterFader *ptr = &_parameterFaders[0];
- ParameterFader *best = 0;
- int i;
- for (i = ARRAYSIZE(_parameterFaders); i; --i, ++ptr) {
- if (ptr->param == param) {
- best = ptr;
- start = ptr->end;
- break;
- } else if (!ptr->param) {
- best = ptr;
- }
- }
-
- if (best) {
- best->param = param;
- best->start = start;
- best->end = target;
- if (!time)
- best->total_time = 1;
- else
- best->total_time = (uint32)time * 10000;
- best->current_time = 0;
- } else {
- debug(0, "IMuse Player %d: Out of parameter faders", _id);
- return -1;
- }
-
- return 0;
-}
-
-void Player::transitionParameters() {
- uint32 advance = _midi->getBaseTempo();
- int value;
-
- ParameterFader *ptr = &_parameterFaders[0];
- int i;
- for (i = ARRAYSIZE(_parameterFaders); i; --i, ++ptr) {
- if (!ptr->param)
- continue;
-
- ptr->current_time += advance;
- if (ptr->current_time > ptr->total_time)
- ptr->current_time = ptr->total_time;
- value = (int32)ptr->start + (int32)(ptr->end - ptr->start) * (int32)ptr->current_time / (int32)ptr->total_time;
-
- switch (ptr->param) {
- case ParameterFader::pfVolume:
- // Volume.
- if (!value && !ptr->end) {
- clear();
- return;
- }
- setVolume((byte)value);
- break;
-
- case ParameterFader::pfTranspose:
- // FIXME: Is this really transpose?
- setTranspose(0, value / 100);
- setDetune(value % 100);
- break;
-
- case ParameterFader::pfSpeed: // impSpeed:
- // Speed.
- setSpeed((byte)value);
- break;
-
- default:
- ptr->param = 0;
- }
-
- if (ptr->current_time >= ptr->total_time)
- ptr->param = 0;
- }
-}
-
-uint Player::getBeatIndex() {
- return (_parser ? (_parser->getTick() / TICKS_PER_BEAT + 1) : 0);
-}
-
-void Player::removePart(Part *part) {
- // Unlink
- if (part->_next)
- part->_next->_prev = part->_prev;
- if (part->_prev)
- part->_prev->_next = part->_next;
- else
- _parts = part->_next;
- part->_next = part->_prev = 0;
-}
-
-void Player::fixAfterLoad() {
- _midi = _se->getBestMidiDriver(_id);
- if (!_midi) {
- clear();
- } else {
- start_seq_sound(_id, false);
- setSpeed(_speed);
- if (_parser)
- _parser->jumpToTick(_music_tick); // start_seq_sound already switched tracks
- _isMT32 = _se->isMT32(_id);
- _isMIDI = _se->isMIDI(_id);
- }
-}
-
-uint32 Player::getBaseTempo() {
- return (_midi ? _midi->getBaseTempo() : 0);
-}
-
-void Player::metaEvent(byte type, byte *msg, uint16 len) {
- if (type == 0x2F)
- clear();
-}
-
-
-
-////////////////////////////////////////
-//
-// Player save/load functions
-//
-////////////////////////////////////////
-
-void Player::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry playerEntries[] = {
- MKLINE(Player, _active, sleByte, VER(8)),
- MKLINE(Player, _id, sleUint16, VER(8)),
- MKLINE(Player, _priority, sleByte, VER(8)),
- MKLINE(Player, _volume, sleByte, VER(8)),
- MKLINE(Player, _pan, sleInt8, VER(8)),
- MKLINE(Player, _transpose, sleByte, VER(8)),
- MKLINE(Player, _detune, sleInt8, VER(8)),
- MKLINE(Player, _vol_chan, sleUint16, VER(8)),
- MKLINE(Player, _vol_eff, sleByte, VER(8)),
- MKLINE(Player, _speed, sleByte, VER(8)),
- MK_OBSOLETE(Player, _song_index, sleUint16, VER(8), VER(19)),
- MKLINE(Player, _track_index, sleUint16, VER(8)),
- MK_OBSOLETE(Player, _timer_counter, sleUint16, VER(8), VER(17)),
- MKLINE(Player, _loop_to_beat, sleUint16, VER(8)),
- MKLINE(Player, _loop_from_beat, sleUint16, VER(8)),
- MKLINE(Player, _loop_counter, sleUint16, VER(8)),
- MKLINE(Player, _loop_to_tick, sleUint16, VER(8)),
- MKLINE(Player, _loop_from_tick, sleUint16, VER(8)),
- MK_OBSOLETE(Player, _tempo, sleUint32, VER(8), VER(19)),
- MK_OBSOLETE(Player, _cur_pos, sleUint32, VER(8), VER(17)),
- MK_OBSOLETE(Player, _next_pos, sleUint32, VER(8), VER(17)),
- MK_OBSOLETE(Player, _song_offset, sleUint32, VER(8), VER(17)),
- MK_OBSOLETE(Player, _tick_index, sleUint16, VER(8), VER(17)),
- MK_OBSOLETE(Player, _beat_index, sleUint16, VER(8), VER(17)),
- MK_OBSOLETE(Player, _ticks_per_beat, sleUint16, VER(8), VER(17)),
- MKLINE(Player, _music_tick, sleUint32, VER(19)),
- MKLINE(Player, _hook._jump[0], sleByte, VER(8)),
- MKLINE(Player, _hook._transpose, sleByte, VER(8)),
- MKARRAY(Player, _hook._part_onoff[0], sleByte, 16, VER(8)),
- MKARRAY(Player, _hook._part_volume[0], sleByte, 16, VER(8)),
- MKARRAY(Player, _hook._part_program[0], sleByte, 16, VER(8)),
- MKARRAY(Player, _hook._part_transpose[0], sleByte, 16, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry parameterFaderEntries[] = {
- MKLINE(ParameterFader, param, sleInt16, VER(17)),
- MKLINE(ParameterFader, start, sleInt16, VER(17)),
- MKLINE(ParameterFader, end, sleInt16, VER(17)),
- MKLINE(ParameterFader, total_time, sleUint32, VER(17)),
- MKLINE(ParameterFader, current_time, sleUint32, VER(17)),
- MKEND()
- };
-
- if (!ser->isSaving() && _parser) {
- delete _parser;
- _parser = 0;
- }
- _music_tick = _parser ? _parser->getTick() : 0;
-
- int num;
- if (ser->isSaving()) {
- num = (_parts ? (_parts - _se->_parts + 1) : 0);
- ser->saveUint16(num);
- } else {
- num = ser->loadUint16();
- _parts = (num ? &_se->_parts[num - 1] : 0);
- }
- ser->saveLoadEntries(this, playerEntries);
- ser->saveLoadArrayOf(_parameterFaders, ARRAYSIZE(_parameterFaders),
- sizeof(ParameterFader), parameterFaderEntries);
- return;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/input.cpp b/scumm/input.cpp
deleted file mode 100644
index ad890604c4..0000000000
--- a/scumm/input.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-#include "common/system.h"
-
-#include "gui/message.h"
-#include "gui/newgui.h"
-
-#include "scumm/debugger.h"
-#include "scumm/dialogs.h"
-#include "scumm/insane/insane.h"
-#include "scumm/imuse.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/logic_he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-
-
-#ifdef _WIN32_WCE
-#define KEY_ALL_SKIP 3457
-#endif
-
-namespace Scumm {
-
-enum MouseButtonStatus {
- msDown = 1,
- msClicked = 2
-};
-
-void ScummEngine::parseEvents() {
- OSystem::Event event;
-
- while (_system->pollEvent(event)) {
-
- switch (event.type) {
- case OSystem::EVENT_KEYDOWN:
- if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9'
- && (event.kbd.flags == OSystem::KBD_ALT ||
- event.kbd.flags == OSystem::KBD_CTRL)) {
- _saveLoadSlot = event.kbd.keycode - '0';
-
- // don't overwrite autosave (slot 0)
- if (_saveLoadSlot == 0)
- _saveLoadSlot = 10;
-
- sprintf(_saveLoadName, "Quicksave %d", _saveLoadSlot);
- _saveLoadFlag = (event.kbd.flags == OSystem::KBD_ALT) ? 1 : 2;
- _saveTemporaryState = false;
- } else if (event.kbd.flags == OSystem::KBD_CTRL) {
- if (event.kbd.keycode == 'f')
- _fastMode ^= 1;
- else if (event.kbd.keycode == 'g')
- _fastMode ^= 2;
- else if (event.kbd.keycode == 'd')
- _debugger->attach();
- else if (event.kbd.keycode == 's')
- res.resourceStats();
- else
- _keyPressed = event.kbd.ascii; // Normal key press, pass on to the game.
- } else if (event.kbd.flags & OSystem::KBD_ALT) {
- // The result must be 273 for Alt-W
- // because that's what MI2 looks for in
- // its "instant win" cheat.
- _keyPressed = event.kbd.keycode + 154;
- } else if (event.kbd.ascii == 315 && (_gameId == GID_CMI && !(_features & GF_DEMO))) {
- // FIXME: support in-game menu screen. For now, this remaps F1 to F5 in COMI
- _keyPressed = 319;
- } else if (event.kbd.ascii < 273 || event.kbd.ascii > 276 || _version >= 7) {
- // don't let game have arrow keys as we currently steal them
- // for keyboard cursor control
- // this fixes bug with up arrow (273) corresponding to
- // "instant win" cheat in MI2 mentioned above
- //
- // This is not applicable to Full Throttle as it processes keyboard
- // cursor control by itself. Also it fixes derby scene
- _keyPressed = event.kbd.ascii; // Normal key press, pass on to the game.
- }
-
- if (_heversion >= 80) {
- // Keyboard is controlled via variable
- int _keyState = 0;
-
- if (event.kbd.ascii == 276) // Left
- _keyState = 1;
-
- if (event.kbd.ascii == 275) // Right
- _keyState |= 2;
-
- if (event.kbd.ascii == 273) // Up
- _keyState |= 4;
-
- if (event.kbd.ascii == 274) // Down
- _keyState |= 8;
-
- if (event.kbd.flags == OSystem::KBD_SHIFT)
- _keyState |= 16;
-
- if (event.kbd.flags == OSystem::KBD_CTRL)
- _keyState |= 32;
-
- VAR(VAR_KEY_STATE) = _keyState;
- }
-
- if (_keyPressed >= 512)
- debugC(DEBUG_GENERAL, "_keyPressed > 512 (%d)", _keyPressed);
- else
- _keyDownMap[_keyPressed] = true;
- break;
-
- case OSystem::EVENT_KEYUP:
- // FIXME: for some reason OSystem::KBD_ALT is set sometimes
- // possible to a bug in sdl-common.cpp
- if (event.kbd.ascii >= 512)
- debugC(DEBUG_GENERAL, "keyPressed > 512 (%d)", event.kbd.ascii);
- else
- _keyDownMap[event.kbd.ascii] = false;
- break;
-
-
- // We update the mouse position whenever the mouse moves or a click occurs.
- // The latter is done to accomodate systems with a touchpad / pen controller.
- case OSystem::EVENT_LBUTTONDOWN:
- case OSystem::EVENT_RBUTTONDOWN:
- case OSystem::EVENT_MOUSEMOVE:
- if (event.type == OSystem::EVENT_LBUTTONDOWN)
- _leftBtnPressed |= msClicked|msDown;
- else if (event.type == OSystem::EVENT_RBUTTONDOWN)
- _rightBtnPressed |= msClicked|msDown;
- _mouse.x = event.mouse.x;
- _mouse.y = event.mouse.y;
-
- if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- _mouse.x -= (Common::kHercW - _screenWidth * 2) / 2;
- _mouse.x /= 2;
- _mouse.y = _mouse.y * 4 / 7;
- }
- break;
- case OSystem::EVENT_LBUTTONUP:
- _leftBtnPressed &= ~msDown;
- break;
-
- case OSystem::EVENT_RBUTTONUP:
- _rightBtnPressed &= ~msDown;
- break;
-
- // The following two cases enable dialog choices to be
- // scrolled through in the SegaCD version of MI
- // as nothing else uses the wheel don't bother
- // checking the gameid
-
- case OSystem::EVENT_WHEELDOWN:
- _keyPressed = 55;
- break;
-
- case OSystem::EVENT_WHEELUP:
- _keyPressed = 54;
- break;
-
- case OSystem::EVENT_QUIT:
- if (_confirmExit)
- confirmExitDialog();
- else
- _quit = true;
- break;
-
- default:
- break;
- }
- }
-}
-
-void ScummEngine::clearClickedStatus() {
- _keyPressed = 0;
-
-#ifndef DISABLE_HE
- if (_heversion >= 98) {
- ((ScummEngine_v90he *)this)->_logicHE->processKeyStroke(_keyPressed);
- }
-#endif
- _mouseAndKeyboardStat = 0;
- _leftBtnPressed &= ~msClicked;
- _rightBtnPressed &= ~msClicked;
-}
-
-void ScummEngine::processKbd(bool smushMode) {
- int saveloadkey;
-
-#ifndef DISABLE_HE
- if (_heversion >= 98) {
- ((ScummEngine_v90he *)this)->_logicHE->processKeyStroke(_keyPressed);
- }
-#endif
-
- _lastKeyHit = _keyPressed;
- _keyPressed = 0;
- if (((_version <= 2) || (_platform == Common::kPlatformFMTowns && _version == 3)) && 315 <= _lastKeyHit && _lastKeyHit < 315+12) {
- // Convert F-Keys for V1/V2 games (they start at 1 instead of at 315)
- _lastKeyHit -= 314;
- }
-
-
- //
- // Clip the mouse coordinates, and compute _virtualMouse.x (and clip it, too)
- //
- if (_mouse.x < 0)
- _mouse.x = 0;
- if (_mouse.x > _screenWidth-1)
- _mouse.x = _screenWidth-1;
- if (_mouse.y < 0)
- _mouse.y = 0;
- if (_mouse.y > _screenHeight-1)
- _mouse.y = _screenHeight-1;
-
- _virtualMouse.x = _mouse.x + virtscr[0].xstart;
- _virtualMouse.y = _mouse.y - virtscr[0].topline;
- if (_features & GF_NEW_CAMERA)
- _virtualMouse.y += _screenTop;
-
- if (_virtualMouse.y < 0)
- _virtualMouse.y = -1;
- if (_virtualMouse.y >= virtscr[0].h)
- _virtualMouse.y = -1;
-
- //
- // Determine the mouse button state.
- //
- _mouseAndKeyboardStat = 0;
-
- // Interpret 'return' as left click and 'tab' as right click
- if (_lastKeyHit && _cursor.state > 0) {
- if (_lastKeyHit == 9) {
- _mouseAndKeyboardStat = MBS_RIGHT_CLICK;
- _lastKeyHit = 0;
- } else if (_lastKeyHit == 13) {
- _mouseAndKeyboardStat = MBS_LEFT_CLICK;
- _lastKeyHit = 0;
- }
- }
-
- if (_leftBtnPressed & msClicked && _rightBtnPressed & msClicked && _version >= 4) {
- // Pressing both mouse buttons is treated as if you pressed
- // the cutscene exit key (i.e. ESC in most games). That mimicks
- // the behaviour of the original engine where pressing both
- // mouse buttons also skips the current cutscene.
- _mouseAndKeyboardStat = 0;
- _lastKeyHit = (uint)VAR(VAR_CUTSCENEEXIT_KEY);
- } else if (_rightBtnPressed & msClicked && (_version <= 3 && _gameId != GID_LOOM)) {
- // Pressing right mouse button is treated as if you pressed
- // the cutscene exit key (i.e. ESC in most games). That mimicks
- // the behaviour of the original engine where pressing right
- // mouse button also skips the current cutscene.
- _mouseAndKeyboardStat = 0;
- _lastKeyHit = (VAR_CUTSCENEEXIT_KEY != 0xFF) ? (uint)VAR(VAR_CUTSCENEEXIT_KEY) : 27;
- } else if (_leftBtnPressed & msClicked) {
- _mouseAndKeyboardStat = MBS_LEFT_CLICK;
- } else if (_rightBtnPressed & msClicked) {
- _mouseAndKeyboardStat = MBS_RIGHT_CLICK;
- }
-
- if (_version >= 6) {
- VAR(VAR_LEFTBTN_HOLD) = (_leftBtnPressed & msDown) != 0;
- VAR(VAR_RIGHTBTN_HOLD) = (_rightBtnPressed & msDown) != 0;
-
- if (_version >= 7) {
- VAR(VAR_LEFTBTN_DOWN) = (_leftBtnPressed & msClicked) != 0;
- VAR(VAR_RIGHTBTN_DOWN) = (_rightBtnPressed & msClicked) != 0;
- }
- }
-
- _leftBtnPressed &= ~msClicked;
- _rightBtnPressed &= ~msClicked;
-
- if (!_lastKeyHit)
- return;
-
- // If a key script was specified (a V8 feature), and it's trigger
- // key was pressed, run it.
- if (_keyScriptNo && (_keyScriptKey == _lastKeyHit)) {
- runScript(_keyScriptNo, 0, 0, 0);
- return;
- }
-
-#ifdef _WIN32_WCE
- if (_lastKeyHit == KEY_ALL_SKIP) {
- // Skip cutscene
- if (smushMode) {
- _lastKeyHit = (VAR_CUTSCENEEXIT_KEY != 0xFF) ? (uint)VAR(VAR_CUTSCENEEXIT_KEY) : 27;
- }
- else
- if (vm.cutScenePtr[vm.cutSceneStackPointer])
- _lastKeyHit = (VAR_CUTSCENEEXIT_KEY != 0xFF) ? (uint)VAR(VAR_CUTSCENEEXIT_KEY) : 27;
- else
- // Skip talk
- if (VAR_TALKSTOP_KEY != 0xFF && _talkDelay > 0)
- _lastKeyHit = (uint)VAR(VAR_TALKSTOP_KEY);
- else
- // Escape
- _lastKeyHit = 27;
- }
-#endif
-
- if (_version >= 6 && _lastKeyHit == 20) {
- char buf[256];
-
- _voiceMode++;
- if (_voiceMode == 3)
- _voiceMode = 0;
-
- switch(_voiceMode) {
- case 0:
- sprintf(buf, "Speech Only");
- ConfMan.set("speech_mute", false);
- ConfMan.set("subtitles", false);
- break;
- case 1:
- sprintf(buf, "Speech and Subtitles");
- ConfMan.set("speech_mute", false);
- ConfMan.set("subtitles", true);
- break;
- case 2:
- sprintf(buf, "Subtitles Only");
- ConfMan.set("speech_mute", true);
- ConfMan.set("subtitles", true);
- break;
- }
-
- if (VAR_VOICE_MODE != 0xFF)
- VAR(VAR_VOICE_MODE) = _voiceMode;
-
- GUI::TimedMessageDialog dialog(buf, 1500);
- runDialog(dialog);
- return;
- }
-
- if (VAR_RESTART_KEY != 0xFF && _lastKeyHit == VAR(VAR_RESTART_KEY) ||
- (((_version <= 2) || (_platform == Common::kPlatformFMTowns && _version == 3)) && _lastKeyHit == 8)) {
- confirmRestartDialog();
- return;
- }
-
- if ((VAR_PAUSE_KEY != 0xFF && _lastKeyHit == VAR(VAR_PAUSE_KEY)) ||
- (VAR_PAUSE_KEY == 0xFF && _lastKeyHit == ' ')) {
- pauseGame();
- return;
- }
-
- // COMI version string is hard coded
- // Dig/FT version strings are partly hard coded too
- if (_version == 7 && _lastKeyHit == VAR(VAR_VERSION_KEY)) {
- versionDialog();
- return;
- }
-
- if ((_version <= 2) || (_platform == Common::kPlatformFMTowns && _version == 3))
- saveloadkey = 5; // F5
- else if ((_version <= 3) || (_gameId == GID_SAMNMAX) || (_gameId == GID_CMI) || (_heversion >= 72))
- saveloadkey = 319; // F5
- else
- saveloadkey = VAR(VAR_MAINMENU_KEY);
-
- if ((_platform == Common::kPlatformC64 && _gameId == GID_MANIAC && _lastKeyHit == 27) ||
- (VAR_CUTSCENEEXIT_KEY != 0xFF && _lastKeyHit == VAR(VAR_CUTSCENEEXIT_KEY))) {
-#ifndef DISABLE_SCUMM_7_8
- // Skip cutscene (or active SMUSH video). For the V2 games, which
- // normally use F4 for this, we add in a hack that makes escape work,
- // too (just for convenience).
- if (smushMode) {
- if (_gameId == GID_FT)
- _insane->escapeKeyHandler();
- else
- _smushVideoShouldFinish = true;
- }
-#endif
- if (!smushMode || _smushVideoShouldFinish)
- abortCutscene();
- if (_version <= 2) {
- // Ensure that the input script also sees the key press.
- // This is necessary so you can abort the airplane travel
- // in Zak.
- if (VAR_KEYPRESS != 0xFF)
- VAR(VAR_KEYPRESS) = VAR(VAR_CUTSCENEEXIT_KEY);
- }
- } else if (_lastKeyHit == saveloadkey) {
- if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
- runScript(VAR(VAR_SAVELOAD_SCRIPT), 0, 0, 0);
-
- mainMenuDialog(); // Display NewGui
-
- if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
- runScript(VAR(VAR_SAVELOAD_SCRIPT2), 0, 0, 0);
- return;
- } else if (VAR_TALKSTOP_KEY != 0xFF && _lastKeyHit == VAR(VAR_TALKSTOP_KEY)) {
- _talkDelay = 0;
- if (_sound->_sfxMode & 2)
- stopTalk();
- return;
- } else if (_lastKeyHit == '[' || _lastKeyHit == ']') { // Change music volume
- int vol = ConfMan.getInt("music_volume") / 16;
- if (_lastKeyHit == ']' && vol < 16)
- vol++;
- else if (_lastKeyHit == '[' && vol > 0)
- vol--;
-
- // Display the music volume
- ValueDisplayDialog dlg("Music volume: ", 0, 16, vol, ']', '[');
- vol = runDialog(dlg);
-
- vol *= 16;
- if (vol > Audio::Mixer::kMaxMixerVolume)
- vol = Audio::Mixer::kMaxMixerVolume;
-
- ConfMan.set("music_volume", vol);
- setupVolumes();
- } else if (_lastKeyHit == '-' || _lastKeyHit == '+') { // Change text speed
- if (_lastKeyHit == '+' && _defaultTalkDelay > 0)
- _defaultTalkDelay--;
- else if (_lastKeyHit == '-' && _defaultTalkDelay < 9)
- _defaultTalkDelay++;
-
- // Display the talk speed
- ValueDisplayDialog dlg("Text speed: ", 0, 9, 9 - _defaultTalkDelay, '+', '-');
- _defaultTalkDelay = 9 - runDialog(dlg);
-
- if (VAR_CHARINC != 0xFF)
- VAR(VAR_CHARINC) = _defaultTalkDelay;
- } else if (_lastKeyHit == '~' || _lastKeyHit == '#') { // Debug console
- _debugger->attach();
- } else if (_version <= 2) {
- // Store the input type. So far we can't distinguish
- // between 1, 3 and 5.
- // 1) Verb 2) Scene 3) Inv. 4) Key
- // 5) Sentence Bar
-
- if (VAR_KEYPRESS != 0xFF && _lastKeyHit) { // Key Input
- VAR(VAR_KEYPRESS) = _lastKeyHit;
- }
- }
-
- _mouseAndKeyboardStat = _lastKeyHit;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/insane/insane.cpp b/scumm/insane/insane.cpp
deleted file mode 100644
index 08c982b65f..0000000000
--- a/scumm/insane/insane.cpp
+++ /dev/null
@@ -1,1466 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/engine.h"
-
-#include "common/system.h"
-
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/sound.h"
-
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-
-#include "scumm/smush/smush_player.h"
-#include "scumm/smush/smush_font.h"
-#include "scumm/smush/chunk_type.h"
-#include "scumm/smush/chunk.h"
-
-#include "scumm/insane/insane.h"
-
-// TODO (in no particular order):
-// o Code review/cleanup
-
-namespace Scumm {
-
-static const int actorAnimationData[21] = {20, 21, 22, 23, 24, 25, 26, 13, 14, 15, 16, 17,
- 18, 19, 6, 7, 8, 9, 10, 11, 12};
-
-
-Insane::Insane(ScummEngine_v6 *scumm) {
- _vm = scumm;
-
- initvars();
-
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
- readFileToMem("roadrash.rip", &_smush_roadrashRip);
- readFileToMem("roadrsh2.rip", &_smush_roadrsh2Rip);
- readFileToMem("roadrsh3.rip", &_smush_roadrsh3Rip);
- readFileToMem("goglpalt.rip", &_smush_goglpaltRip);
- readFileToMem("tovista1.flu", &_smush_tovista1Flu);
- readFileToMem("tovista2.flu", &_smush_tovista2Flu);
- readFileToMem("toranch.flu", &_smush_toranchFlu);
- readFileToMem("minedriv.flu", &_smush_minedrivFlu);
- readFileToMem("minefite.flu", &_smush_minefiteFlu);
- _smush_bensgoggNut = new NutRenderer(_vm);
- _smush_bensgoggNut->loadFont("bensgogg.nut");
- _smush_bencutNut = new NutRenderer(_vm);
- _smush_bencutNut->loadFont("bencut.nut");
- }
-
- _smush_iconsNut = new NutRenderer(_vm);
- _smush_iconsNut->loadFont("icons.nut");
- _smush_icons2Nut = new NutRenderer(_vm);
- _smush_icons2Nut->loadFont("icons2.nut");
-}
-
-Insane::~Insane(void) {
- free(_smush_roadrashRip);
- free(_smush_roadrsh2Rip);
- free(_smush_roadrsh3Rip);
- free(_smush_goglpaltRip);
- free(_smush_tovista1Flu);
- free(_smush_tovista2Flu);
- free(_smush_toranchFlu);
- free(_smush_minedrivFlu);
- free(_smush_minefiteFlu);
-
- delete _smush_bencutNut;
- delete _smush_bensgoggNut;
- delete _smush_iconsNut;
- delete _smush_icons2Nut;
-}
-
-void Insane::setSmushParams(int speed) {
- _speed = speed;
-}
-
-void Insane::initvars(void) {
- int i, j;
-
- _speed = 12;
- _insaneIsRunning = false;
-
- _numberArray = 0;
- _emulateInterrupt = 0;
- _flag1d = 0;
- _objArray1Idx = 0;
- _objArray1Idx2 = 0;
- _objArray2Idx = 0;
- _objArray2Idx2 = 0;
- _currSceneId = 1;
- _timer6Id = 0;
- _timerSpriteId = 0;
- _temp2SceneId = 0;
- _tempSceneId = 0;
- _currEnemy = -1;
- _currScenePropIdx = 0;
- _currScenePropSubIdx = 0;
- _currTrsMsg = 0;
- _sceneData2Loaded = 0;
- _sceneData1Loaded = 0;
- _keyboardDisable = 0;
- _needSceneSwitch = false;
- _idx2Exceeded = 0;
- _lastKey = 0;
- _tiresRustle = false;
- _keybOldDx = 0;
- _keybOldDy = 0;
- _velocityX = 0;
- _velocityY = 0;
- _keybX = 0;
- _keybY = 0;
- _firstBattle = false;
- _battleScene = true;
- _kickBenProgress = false;
- _weaponBenJustSwitched = false;
- _kickEnemyProgress = false;
- _weaponEnemyJustSwitched = false;
- _beenCheated = 0;
- _posBrokenTruck = 0;
- _posBrokenCar = 0;
- _posFatherTorque = 0;
- _posCave = 0;
- _posVista = 0;
- _roadBranch = false;
- _roadStop = false;
- _carIsBroken = false;
- _benHasGoggles = false;
- _mineCaveIsNear = false;
- _objectDetected = false;
- _approachAnim = -1;
- _val54d = 0;
- _val57d = 0;
- _val115_ = false;
- _roadBumps = false;
- _val211d = 0;
- _val213d = 0;
- _metEnemiesListTail = 0;
- _smlayer_room = 0;
- _smlayer_room2 = 0;
- _isBenCut = 0;
- _continueFrame = 0;
- _continueFrame1 = 0;
- _counter1 = 0;
- _iactSceneId = 0;
- _iactSceneId2 = 0;
-
- for (i = 0; i < 12; i++)
- _metEnemiesList[i] = 0;
-
- for (i = 0; i < 9; i++)
- for (j = 0; j < 9; j++)
- _enHdlVar[i][j] = 0;
-
- for (i = 0; i < 0x80; i++)
- _iactBits[i] = 0;
-
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- init_enemyStruct(EN_ROTT1, EN_ROTT1, 0, 0, 160, 0, INV_MACE, 63, "endcrshr.san",
- 25, 15, 16, 26, 11, 3);
- } else {
- init_enemyStruct(EN_ROTT1, EN_ROTT1, 0, 0, 160, 0, INV_MACE, 90, "wr2_rott.san",
- 26, 16, 17, 27, 11, 3);
- }
-
- init_enemyStruct(EN_ROTT2, EN_ROTT2, 1, 0, 250, 0, INV_2X4, 90, "wr2_rott.san",
- 28, 16, 17, 42, 11, 3);
- init_enemyStruct(EN_ROTT3, EN_ROTT3, 2, 0, 120, 0, INV_HAND, 90, "wr2_rott.san",
- 15, 16, 17, 43, 11, 3);
- init_enemyStruct(EN_VULTF1, EN_VULTF1, 3, 0, 60, 0, INV_HAND, 91, "wr2_vltp.san",
- 29, 33, 32, 37, 12, 4);
- init_enemyStruct(EN_VULTM1, EN_VULTM1, 4, 0, 100, 0, INV_CHAIN, 91, "wr2_vltc.san",
- 30, 33, 32, 36, 12, 4);
- init_enemyStruct(EN_VULTF2, EN_VULTF2, 5, 0, 250, 0, INV_CHAINSAW, 91, "wr2_vlts.san",
- 31, 33, 32, 35, 12, 4);
- init_enemyStruct(EN_VULTM2, EN_VULTM2, 6, 0, 900, 0, INV_BOOT, 91, "wr2_rott.san",
- 34, 33, 32, 45, 16, 4);
- init_enemyStruct(EN_CAVEFISH, EN_CAVEFISH, 7, 0, 60, 0, INV_DUST, 92, "wr2_cave.san",
- 39, 0, 0, 41, 13, 2);
- init_enemyStruct(EN_TORQUE, EN_TORQUE, 8, 0, 900, 0, INV_HAND, 93, "wr2_vltp.san",
- 57, 0, 0, 37, 12, 1);
-
- init_fluConfStruct(1, 1, &_smush_minedrivFlu, "minedriv.san", 235, 1300);
- init_fluConfStruct(2, 1, &_smush_minedrivFlu, "minedriv.san", 355, 1300);
- init_fluConfStruct(3, 1, &_smush_minedrivFlu, "minedriv.san", 1255, 1300);
- init_fluConfStruct(4, 1, &_smush_minedrivFlu, "minedriv.san", 565, 1300);
- init_fluConfStruct(5, 1, &_smush_minedrivFlu, "minedriv.san", 1040, 1300);
- init_fluConfStruct(8, 1, &_smush_minedrivFlu, "minedriv.san", 1040, 1300);
- init_fluConfStruct(9, 1, &_smush_minedrivFlu, "minedriv.san", 655, 1300);
- init_fluConfStruct(10, 1, &_smush_minedrivFlu, "minedriv.san", 115, 1300);
- init_fluConfStruct(11, 1, &_smush_minedrivFlu, "minedriv.san", 315, 1300);
- init_fluConfStruct(12, 1, &_smush_minedrivFlu, "minedriv.san", 235, 1300);
- init_fluConfStruct(15, 6, &_smush_toranchFlu, "toranch.san", 115, 530);
- init_fluConfStruct(16, 5, &_smush_tovista2Flu, "tovista2.san", 235, 290);
- init_fluConfStruct(17, 4, &_smush_tovista1Flu, "tovista1.san", 175, 230);
- init_fluConfStruct(18, 4, &_smush_tovista1Flu, "tovista1.san", 175, 230);
- init_fluConfStruct(19, 6, &_smush_toranchFlu, "toranch.san", 115, 530);
- init_fluConfStruct(20, 6, &_smush_toranchFlu, "toranch.san", 115, 530);
-
- init_scenePropStruct( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
- init_scenePropStruct( 1, 0, 1, 128, 2001, 0, 0, 0, 0, 56, 2);
- init_scenePropStruct( 2, 0, 0, 125, 1002, 0, 0, 0, 0, 35, 3);
- init_scenePropStruct( 3, 0, 1, 129, 2002, 0, 0, 0, 0, 23, 4);
- init_scenePropStruct( 4, 0, 1, 130, 2003, 0, 0, 0, 0, 40, 5);
- init_scenePropStruct( 5, 0, 0, 126, 1005, 0, 0, 0, 0, 46, 6);
- init_scenePropStruct( 6, 0, 1, 131, 2004, 0, 0, 0, 0, 39, 7);
- init_scenePropStruct( 7, 0, 1, 132, 2005, 0, 0, 0, 0, 45, 8);
- init_scenePropStruct( 8, 0, 1, 133, 2006, 0, 0, 0, 0, 14, 9);
- init_scenePropStruct( 9, 0, 0, 127, 1009, 0, 0, 0, 0, 15, 10);
- init_scenePropStruct( 10, 0, 1, 134, 501, 0, 0, 0, 0, 25, 11);
- init_scenePropStruct( 11, 0, 1, 135, 502, 0, 0, 0, 0, 15, 0);
- init_scenePropStruct( 12, 1, -1, 0, 0, 0xFF, 0xFF, 0xFF, 0, 0, 1);
- init_scenePropStruct( 13, 1, 0, 291, 135, 0xFF, 0xFF, 0xFF, 0, 25, 0);
- init_scenePropStruct( 14, 2, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 15, 2, 1, 277, 17, 0xFC, 0, 0xFC, 0, 56, 2);
- init_scenePropStruct( 16, 2, 0, 288, 18, 0xFF, 0xFF, 0xFF, 0, 56, 3);
- init_scenePropStruct( 17, 2, 1, 278, 19, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 18, 3, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 19, 3, 1, 282, 23, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 20, 4, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 21, 4, 1, 283, 24, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 22, 5, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 23, 5, 1, 284, 25, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 24, 6, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 25, 6, 1, 285, 26, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 26, 7, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 27, 7, 1, 286, 27, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 28, 8, -1, 0, 0, 0xFC, 0, 0xFC, 0, 0, 1);
- init_scenePropStruct( 29, 8, 1, 287, 28, 0xFC, 0, 0xFC, 0, 56, 0);
- init_scenePropStruct( 30, 9, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 31, 9, 1, 261, 1, 0xFC, 0, 0, 0, 40, 2);
- init_scenePropStruct( 32, 9, 1, 262, 2, 0xFC, 0, 0, 0, 40, 3);
- init_scenePropStruct( 33, 9, 1, 263, 3, 0xFC, 0, 0, 0, 40, 0);
- init_scenePropStruct( 34, 10, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 35, 10, 1, 263, 3, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 36, 11, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 37, 11, 1, 264, 4, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 38, 12, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 39, 12, 1, 265, 5, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 40, 13, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 41, 13, 1, 266, 6, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 42, 14, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 43, 14, 1, 267, 7, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 44, 15, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 45, 15, 1, 268, 8, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 46, 16, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 47, 16, 1, 274, 14, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 48, 17, -1, 0, 0, 0xFC, 0, 0, 0, 0, 1);
- init_scenePropStruct( 49, 17, 1, 270, 10, 0xFC, 0, 0, 0, 30, 0);
- init_scenePropStruct( 50, 18, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 51, 18, 0, 289, 45, 0xFF, 0xFF, 0xFF, 0, 40, 2);
- init_scenePropStruct( 52, 18, 1, 177, 49, 0xFC, 0xFC, 0x54, 0, 40, 3);
- init_scenePropStruct( 53, 18, 1, 178, 50, 0xFC, 0xFC, 0x54, 0, 40, 4);
- init_scenePropStruct( 54, 18, 0, 290, 47, 0xFF, 0xFF, 0xFF, 0, 40, 0);
- init_scenePropStruct( 55, 19, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 56, 19, 1, 179, 51, 0xFC, 0xFC, 0x54, 0, 40, 0);
- init_scenePropStruct( 57, 20, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 58, 20, 1, 183, 55, 0xFC, 0xFC, 0x54, 0, 40, 0);
- init_scenePropStruct( 59, 21, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 60, 21, 1, 184, 56, 0xFC, 0xFC, 0x54, 0, 40, 0);
- init_scenePropStruct( 61, 22, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 62, 22, 1, 186, 58, 0xFC, 0xFC, 0x54, 0, 40, 0);
- init_scenePropStruct( 63, 23, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 64, 23, 1, 191, 63, 0xFC, 0xFC, 0x54, 0, 40, 0);
- init_scenePropStruct( 65, 24, -1, 0, 0, 0xFC, 0xFC, 0x54, 0, 0, 1);
- init_scenePropStruct( 66, 24, 1, 192, 64, 0xFC, 0xFC, 0x54, 0, 40, 0);
- init_scenePropStruct( 67, 25, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 68, 25, 1, 220, 93, 0xBC, 0x78, 0x48, 0, 40, 2);
- init_scenePropStruct( 69, 25, 1, 221, 94, 0xBC, 0x78, 0x48, 0, 40, 3);
- init_scenePropStruct( 70, 25, 1, 222, 95, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 71, 26, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 72, 26, 1, 223, 96, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 73, 27, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 74, 27, 1, 224, 97, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 75, 28, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 76, 28, 1, 225, 98, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 77, 29, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 78, 29, 1, 226, 99, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 79, 30, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 80, 30, 1, 228, 101, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 81, 31, -1, 0, 0, 0xBC, 0x78, 0x48, 0, 0, 1);
- init_scenePropStruct( 82, 31, 1, 229, 102, 0xBC, 0x78, 0x48, 0, 40, 0);
- init_scenePropStruct( 83, 32, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct( 84, 32, 1, 233, 106, 0xA8, 0xA8, 0xA8, 0, 40, 2);
- init_scenePropStruct( 85, 32, 1, 234, 107, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct( 86, 33, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct( 87, 33, 1, 241, 114, 0xA8, 0xA8, 0xA8, 0, 40, 2);
- init_scenePropStruct( 88, 33, 1, 242, 115, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct( 89, 34, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct( 90, 34, 1, 237, 110, 0xA8, 0xA8, 0xA8, 0, 40, 2);
- init_scenePropStruct( 91, 34, 1, 238, 111, 0xA8, 0xA8, 0xA8, 0, 40, 3);
- init_scenePropStruct( 92, 34, 1, 239, 112, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct( 93, 35, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct( 94, 35, 1, 258, 131, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct( 95, 36, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct( 96, 36, 1, 260, 133, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct( 97, 37, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct( 98, 37, 1, 252, 125, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct( 99, 38, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct(100, 38, 1, 254, 127, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct(101, 39, -1, 0, 0, 0xA8, 0xA8, 0xA8, 0, 0, 1);
- init_scenePropStruct(102, 39, 1, 236, 109, 0xA8, 0xA8, 0xA8, 0, 40, 0);
- init_scenePropStruct(103, 40, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(104, 40, 1, 174, 42, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(105, 41, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(106, 41, 1, 167, 36, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(107, 42, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(108, 42, 1, 160, 29, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(109, 43, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(110, 43, 1, 161, 30, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(111, 44, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(112, 44, 1, 163, 32, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(113, 45, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(114, 45, 1, 164, 33, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(115, 46, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(116, 46, 1, 170, 39, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(117, 47, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(118, 47, 1, 166, 35, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(119, 48, -1, 0, 0, 4, 0xBC, 0, 0, 0, 1);
- init_scenePropStruct(120, 48, 1, 175, 43, 4, 0xBC, 0, 0, 40, 0);
- init_scenePropStruct(121, 49, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(122, 49, 1, 203, 75, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(123, 50, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(124, 50, 1, 194, 66, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(125, 51, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(126, 51, 1, 195, 67, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(127, 52, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(128, 52, 1, 199, 71, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(129, 53, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(130, 53, 1, 205, 77, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(131, 54, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(132, 54, 1, 212, 85, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(133, 55, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(134, 55, 1, 201, 73, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(135, 56, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(136, 56, 1, 198, 70, 0x40, 0x40, 0xFC, 0, 40, 0);
- init_scenePropStruct(137, 57, -1, 0, 0, 0x40, 0x40, 0xFC, 0, 0, 1);
- init_scenePropStruct(138, 57, 0, 59, 134, 0xFF, 0xFF, 0xFF, 0, 30, 0);
-
- _actor[0].damage = 0;
- _actor[0].maxdamage = 80;
- _actor[0].field_8 = 1;
- _actor[0].frame = 0;
- _actor[0].tilt = 0;
- _actor[0].cursorX = 0;
- _actor[0].speed = 0;
- _actor[0].x = 160;
- _actor[0].y = 0;
- _actor[0].y1 = -1;
- _actor[0].x1 = -1;
- _actor[0].weaponClass = 2;
- _actor[0].animWeaponClass = 0;
- _actor[0].newFacingFlag = 2;
- _actor[0].curFacingFlag = 0;
- _actor[0].lost = false;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- _actor[0].field_48 = false;
- _actor[0].defunct = 0;
- _actor[0].scenePropSubIdx = 0;
- _actor[0].field_54 = 0;
- _actor[0].runningSound = 0;
- _actor[0].weapon = INV_HAND;
- _actor[0].inventory[INV_CHAIN] = 0;
- _actor[0].inventory[INV_CHAINSAW] = 0;
- _actor[0].inventory[INV_MACE] = 0;
- _actor[0].inventory[INV_2X4] = 0;
- _actor[0].inventory[INV_WRENCH] = 1;
- _actor[0].inventory[INV_BOOT] = 1;
- _actor[0].inventory[INV_HAND] = 1;
- _actor[0].inventory[INV_DUST] = 0;
- _actor[0].probability = 5;
- _actor[0].enemyHandler = EN_BEN;
- init_actStruct(0, 0, 11, 1, 1, 0, 0, 0);
- init_actStruct(0, 1, 12, 1, 1, 0, 0, 0);
- init_actStruct(0, 2, 1, 1, 1, 0, 0, 0);
- init_actStruct(0, 3, 1, 1, 1, 0, 0, 0);
-
- _actor[1].damage = 0;
- _actor[1].maxdamage = -1;
- _actor[1].field_8 = 1;
- _actor[1].frame = 0;
- _actor[1].tilt = 0;
- _actor[1].cursorX = 0;
- _actor[1].speed = 0;
- _actor[1].x = 160;
- _actor[1].y = 0;
- _actor[1].y1 = -1;
- _actor[1].x1 = -1;
- _actor[1].weaponClass = 2;
- _actor[1].animWeaponClass = 0;
- _actor[1].newFacingFlag = 0;
- _actor[1].curFacingFlag = 0;
- _actor[1].lost = false;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- _actor[1].field_48 = false;
- _actor[1].defunct = 0;
- _actor[1].scenePropSubIdx = 0;
- _actor[1].field_54 = 0;
- _actor[1].runningSound = 0;
- _actor[1].weapon = INV_HAND;
- _actor[1].inventory[INV_CHAIN] = 0;
- _actor[1].inventory[INV_CHAINSAW] = 0;
- _actor[1].inventory[INV_MACE] = 1;
- _actor[1].inventory[INV_2X4] = 0;
- _actor[1].inventory[INV_WRENCH] = 0;
- _actor[1].inventory[INV_BOOT] = 0;
- _actor[1].inventory[INV_HAND] = 0;
- _actor[1].inventory[INV_DUST] = 0;
- _actor[1].probability = 5;
- _actor[1].enemyHandler = -1;
-
- init_actStruct(1, 0, 14, 1, 1, 0, 0, 0);
- init_actStruct(1, 1, 15, 1, 1, 0, 0, 0);
- init_actStruct(1, 2, 13, 1, 1, 0, 0, 0);
- init_actStruct(1, 3, 13, 1, 1, 0, 0, 0);
-
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10; j++)
- _enemyState[i][j] = 0;
-}
-
-void Insane::init_actStruct(int actornum, int actnum, int32 actorval, byte state,
- int32 room, int32 animTilt, int32 tilt, int32 frame) {
- _actor[actornum].act[actnum].actor = actorval;
- _actor[actornum].act[actnum].state = state;
- _actor[actornum].act[actnum].room = room;
- _actor[actornum].act[actnum].animTilt = animTilt;
- _actor[actornum].act[actnum].tilt = tilt;
- _actor[actornum].act[actnum].frame = frame;
-}
-
-void Insane::init_enemyStruct(int n, int32 handler, int32 initializer,
- int16 occurences, int32 maxdamage, int32 isEmpty,
- int32 weapon, int32 sound, const char *filename,
- int32 costume4, int32 costume6, int32 costume5,
- int16 costumevar, int32 maxframe, int32 apprAnim) {
- assert(strlen(filename) < 20);
-
- _enemy[n].handler = handler;
- _enemy[n].initializer = initializer;
- _enemy[n].occurences = occurences;
- _enemy[n].maxdamage = maxdamage;
- _enemy[n].isEmpty = isEmpty;
- _enemy[n].weapon = weapon;
- _enemy[n].sound = sound;
- strncpy(_enemy[n].filename, filename, 20);
- _enemy[n].costume4 = costume4;
- _enemy[n].costume6 = costume6;
- _enemy[n].costume5 = costume5;
- _enemy[n].costumevar = costumevar;
- _enemy[n].maxframe = maxframe;
- _enemy[n].apprAnim = apprAnim;
-}
-
-void Insane::init_fluConfStruct(int n, int sceneId, byte **fluPtr,
- const char *filenamePtr, int startFrame, int numFrames) {
- _fluConf[n].sceneId = sceneId;
- _fluConf[n].fluPtr = fluPtr;
- _fluConf[n].filenamePtr = filenamePtr;
- _fluConf[n].startFrame = startFrame;
- _fluConf[n].numFrames = numFrames;
-}
-
-void Insane::init_scenePropStruct(int32 n, int32 n1, int32 actornum, int32 sound, int32 trsId,
- byte r, byte g, byte b, int32 counter, int32 maxCounter,
- int32 index) {
- _sceneProp[n].actor = actornum; // main actor number, -1 if not applicable
- _sceneProp[n].sound = sound;
- _sceneProp[n].trsId = trsId;
- _sceneProp[n].r = r;
- _sceneProp[n].g = g;
- _sceneProp[n].b = b;
- _sceneProp[n].counter = counter;
- _sceneProp[n].maxCounter = maxCounter;
- _sceneProp[n].index = index;
-}
-
-void Insane::setBenAnimation(int32 actornum, int anim) {
- if (anim <= 12)
- smlayer_setActorFacing(actornum, 1,
- actorAnimationData[_actor[actornum].weaponClass * 7 + anim - 6], 180);
-}
-
-void Insane::setEnemyAnimation(int32 actornum, int anim) {
- int d = 0;
-
- if (_currEnemy == EN_VULTM1)
- d = 14;
-
- if (anim <= 12)
- smlayer_setActorFacing(actornum, 1,
- actorAnimationData[_actor[actornum].weaponClass * 7 + anim - 6] + d, 180);
-}
-
-int32 Insane::processMouse(void) {
- int32 buttons = 0;
-
- _enemyState[EN_BEN][0] = _vm->_mouse.x;
- _enemyState[EN_BEN][1] = _vm->_mouse.y;
-
- buttons = _vm->VAR(_vm->VAR_LEFTBTN_HOLD) ? 1 : 0;
- buttons |= _vm->VAR(_vm->VAR_RIGHTBTN_HOLD) ? 2 : 0;
-
- return buttons;
-}
-
-int32 Insane::processKeyboard(void) {
- int32 retval = 0;
- int dx = 0, dy = 0;
- int tmpx, tmpy;
-
- if (_vm->getKeyState(0x14f) || _vm->getKeyState(0x14b) || _vm->getKeyState(0x147))
- dx--;
-
- if (_vm->getKeyState(0x151) || _vm->getKeyState(0x14d) || _vm->getKeyState(0x149))
- dx++;
-
- if (_vm->getKeyState(0x147) || _vm->getKeyState(0x148) || _vm->getKeyState(0x149))
- dy--;
-
- if (_vm->getKeyState(0x14f) || _vm->getKeyState(0x150) || _vm->getKeyState(0x151))
- dy++;
-
- if (dx == _keybOldDx)
- _velocityX += 4;
- else
- _velocityX = 3;
-
- if (dy == _keybOldDy)
- _velocityY += 4;
- else
- _velocityY = 2;
-
- _keybOldDx = dx;
- _keybOldDy = dy;
-
- if (_velocityX > 48)
- _velocityX = 48;
-
- if (_velocityY > 32)
- _velocityY = 32;
-
- _keybX += dx * _velocityX;
- _keybY += dy * _velocityY;
-
- tmpx = _keybX / 4;
- tmpy = _keybY / 4;
-
- _keybX -= tmpx * 4;
- _keybY -= tmpy * 4;
-
- if (tmpx || tmpy) {
- _enemyState[EN_BEN][0] += tmpx;
- _enemyState[EN_BEN][1] += tmpy;
- }
-
- if (_vm->getKeyState(0x0d))
- retval |= 1;
-
- if (_vm->getKeyState(0x09))
- retval |= 2;
-
- return retval;
-}
-
-void Insane::readFileToMem(const char *name, byte **buf) {
- ScummFile in;
- uint32 len;
-
- _vm->openFile(in, name);
- len = in.size();
- *buf = (byte *)malloc(len);
- in.read(*buf, len);
-}
-
-void Insane::startVideo(const char *filename, int num, int argC, int frameRate,
- int doMainLoop, byte *fluPtr, int32 startFrame) {
- int32 offset = 0;
-
- _smush_curFrame = 0;
- _smush_isSanFileSetup = 0;
- _smush_setupsan4 = 0;
- _smush_smushState = 0;
- _smush_setupsan1 = 0;
- _smush_setupsan17 = 0;
-
- if (fluPtr) {
- offset = smush_setupSanWithFlu(filename, 0, -1, -1, 0, fluPtr, startFrame);
- } else {
- smush_setupSanFromStart(filename, 0, -1, -1, 0);
- }
-
- _player->play(filename, offset, startFrame);
-}
-
-void Insane::smush_warpMouse(int x, int y, int buttons) {
- _player->warpMouse(x, y, buttons);
-}
-
-void Insane::putActors(void) {
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1, _smlayer_room);
- smlayer_putActor(0, 0, _actor[0].x, _actor[0].y1, _smlayer_room);
- smlayer_putActor(0, 1, _actor[0].x, _actor[0].y1, _smlayer_room);
- smlayer_putActor(1, 2, _actor[0].x, _actor[0].y1, _smlayer_room);
- smlayer_putActor(1, 0, _actor[0].x, _actor[0].y1, _smlayer_room);
- smlayer_putActor(1, 1, _actor[0].x, _actor[0].y1, _smlayer_room);
-}
-
-void Insane::readState(void) { // PATCH
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- _actor[0].inventory[INV_CHAIN] = 0;
- _actor[0].inventory[INV_CHAINSAW] = 0;
- _actor[0].inventory[INV_MACE] = 0;
- _actor[0].inventory[INV_2X4] = 0;
- _actor[0].inventory[INV_WRENCH] = 1;
- _actor[0].inventory[INV_DUST] = 0;
- _actor[0].inventory[INV_HAND] = 1;
- _actor[0].inventory[INV_BOOT] = 0;
- _smlayer_room2 = 13;
- } else {
- _actor[0].inventory[INV_CHAIN] = readArray(50) != 0;
- _actor[0].inventory[INV_CHAINSAW] = readArray(51) != 0;
- _actor[0].inventory[INV_MACE] = readArray(52) != 0;
- _actor[0].inventory[INV_2X4] = readArray(53) != 0;
- _actor[0].inventory[INV_WRENCH] = readArray(54) != 0;
- _actor[0].inventory[INV_DUST] = readArray(55) != 0;
- _actor[0].inventory[INV_HAND] = 1;
- _actor[0].inventory[INV_BOOT] = 1;
- _smlayer_room = readArray(320);
- _smlayer_room2 = readArray(321);
- _posBrokenTruck = readArray(322);
- _posVista = readArray(323);
- _val57d = readArray(324);
- _posCave = readArray(325);
- _posBrokenCar = readArray(326);
- _val54d = readArray(327);
- _posFatherTorque = readArray(328);
- _enemy[EN_TORQUE].occurences = readArray(337);
- _enemy[EN_ROTT1].occurences = readArray(329);
- _enemy[EN_ROTT2].occurences = readArray(330);
- _enemy[EN_ROTT3].occurences = readArray(331);
- _enemy[EN_VULTF1].occurences = readArray(332);
- _enemy[EN_VULTM1].occurences = readArray(333);
- _enemy[EN_VULTF2].occurences = readArray(334);
- _enemy[EN_VULTM2].occurences = readArray(335);
- _enemy[EN_CAVEFISH].occurences = readArray(336);
- _enemy[EN_VULTM2].isEmpty = readArray(340);
- _enemy[EN_VULTF2].isEmpty = readArray(339);
- _enemy[EN_CAVEFISH].isEmpty = readArray(56);
-
- // FIXME
- // Some sanity checks. There were submitted savefiles where these values were wrong
- // Still it is unknown what leads to this state. Most probably it is memory
- // overwrite
- if (_enemy[EN_VULTM2].isEmpty != readArray(7)) {
- warning("Wrong INSANE parameters for EN_VULTM2 (%d %d)",
- _enemy[EN_VULTM2].isEmpty, readArray(7));
- _enemy[EN_VULTM2].isEmpty = readArray(7);
- }
-
- if (_enemy[EN_VULTF2].isEmpty != (_actor[0].inventory[INV_CHAINSAW] != 0)) {
- warning("Wrong INSANE parameters for EN_VULTF2 (%d %d)",
- _enemy[EN_VULTF2].isEmpty, _actor[0].inventory[INV_CHAINSAW]);
- _enemy[EN_VULTF2].isEmpty = (_actor[0].inventory[INV_CHAINSAW] != 0);
- }
-
- // FIXME
- // This used to be here but.
- // - bootparam 551 gives googles without cavefish met
- // - when you get the ramp, googles disappear, but you already won the cavefish
- // Incorrect situation would be
- // you won cavefish, don't have googles, don't have ramp
- //
- // So if you find out what how to check ramp presense, feel free to add check here
- // (beware of FT ver a and ver b. In version b var311 is inserted and all vars >311
- // are shifted),
- //
- //if (_enemy[EN_CAVEFISH].isEmpty != readArray(8))
- // error("Wrong INSANE parameters for EN_CAVEFISH (%d %d). Please, report this",
- // _enemy[EN_CAVEFISH].isEmpty, readArray(8));
- }
-}
-
-void Insane::setupValues(void) {
- _actor[0].x = 160;
- _actor[0].y = 200;
- _actor[0].tilt = 0;
- _actor[0].field_8 = 1;
- _actor[0].frame = 0;
- _actor[0].act[2].state = 1;
- _actor[0].act[0].state = 1;
- _actor[0].act[1].state = 0;
- _actor[0].act[2].room = 1;
- _actor[0].act[1].room = 0;
- _actor[0].act[0].room = 0;
- _actor[0].cursorX = 0;
- _actor[0].lost = false;
- _currEnemy = -1;
- _approachAnim = -1;
- smush_warpMouse(160, 100, -1);
-}
-
-bool Insane::idx1Compare(void) {
- return _objArray1Idx == _objArray1Idx2;
-}
-
-bool Insane::idx2Compare(void) {
- return _objArray2Idx == _objArray2Idx2;
-}
-
-int32 Insane::idx1Tweak(void) {
- _objArray1Idx++;
- if (_objArray1Idx >= 100)
- _objArray1Idx = 0;
-
- return _objArray1[_objArray1Idx];
-}
-
-int32 Insane::idx2Tweak(void) {
- if (!_idx2Exceeded)
- if (_objArray2Idx >= _objArray2Idx2)
- return false;
-
- _objArray2Idx++;
- if (_objArray2Idx >= 100) {
- _idx2Exceeded = 0;
- _objArray2Idx = 0;
- }
- return _objArray2[_objArray2Idx];
-}
-
-void Insane::smush_setToFinish(void) {
- debugC(DEBUG_INSANE, "Video is set to finish");
- _vm->_smushVideoShouldFinish = true;
-}
-
-// smlayer_stopSound
-void Insane::smlayer_stopSound(int idx) {
- _vm->_imuseDigital->stopSound(readArray(idx));
-}
-
-void Insane::switchSceneIfNeeded(void) {
- if (_needSceneSwitch && !_smush_isSanFileSetup) {
- putActors();
- stopSceneSounds(_currSceneId);
- _tempSceneId = _currSceneId;
- _currSceneId = _temp2SceneId;
- _needSceneSwitch = false;
- loadSceneData(_temp2SceneId, 0, 1);
-
- if (loadSceneData(_temp2SceneId, 0, 2)) {
- setSceneCostumes(_temp2SceneId);
- _sceneData2Loaded = 0;
- _sceneData1Loaded = 0;
- return;
- }
-
- _sceneData2Loaded = 1;
- if (_temp2SceneId == 13 || _temp2SceneId == 3)
- _isBenCut = 1;
- }
-
- if (_sceneData2Loaded && !_sceneData1Loaded) {
- setSceneCostumes(_currSceneId);
- _sceneData2Loaded = 0;
- }
-}
-
-void Insane::prepareScenePropScene(int32 scenePropNum, bool arg_4, bool arg_8) {
- static const int scenePropIdx[58] = {0, 12, 14, 18, 20, 22, 24, 26, 28, 30, 34,
- 36, 38, 40, 42, 44, 46, 48, 50, 55, 57, 59, 61, 63, 65, 67, 71,
- 73, 75, 77, 79, 81, 83, 85, 89, 93, 95, 97, 99, 101, 103, 105, 107,
- 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137};
-
- int tmp, idx = scenePropIdx[scenePropNum];
-
- debugC(DEBUG_INSANE, "Insane::prepareScenePropScene(%d, %d, %d)", scenePropNum, arg_4, arg_8);
-
- if (((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) || !loadScenePropSounds(idx))
- return;
-
- _actor[0].defunct = arg_4;
- _actor[1].defunct = arg_8;
- _currScenePropIdx = idx;
- _sceneProp[idx + 1].counter = 0;
- _currScenePropSubIdx = 1;
- if (_sceneProp[idx + 1].trsId)
- _currTrsMsg = handleTrsTag(_sceneProp[idx + 1].trsId);
- else
- _currTrsMsg = 0;
-
- tmp = _sceneProp[idx + 1].actor;
- if (tmp != -1) {
- _actor[tmp].field_54 = 1;
- _actor[tmp].act[3].state = 117;
- _actor[tmp].scenePropSubIdx = _currScenePropSubIdx;
- }
-}
-
-int Insane::smush_changeState(int state) {
- if (state == 2) {
- if (_smush_smushState == 0)
- _smush_smushState = 1;
- else
- _smush_smushState = 0;
- } else if (state == 4) {
- if (_smush_smushState)
- _smush_smushState = 3;
- } else if (state != 5) {
- _smush_smushState = state;
- }
- return _smush_smushState;
-}
-
-void Insane::queueSceneSwitch(int32 sceneId, byte *fluPtr, const char *filename,
- int32 arg_C, int32 arg_10, int32 startFrame, int32 numFrames) {
- int32 tmp;
-
- debugC(DEBUG_INSANE, "queueSceneSwitch(%d, *, %s, %d, %d, %d, %d)", sceneId, filename, arg_C, arg_10,
- startFrame, numFrames);
- if (_needSceneSwitch || _sceneData1Loaded)
- return;
-
- if (fluPtr) {
- tmp = ((int)startFrame/30+1)*30;
- if (tmp >= numFrames)
- tmp = 0;
-
- smush_setupSanWithFlu(filename, arg_C|32, -1, -1, 0, fluPtr, tmp);
- } else {
- smush_setupSanFromStart(filename, arg_C|32, -1, -1, 0);
- }
- _needSceneSwitch = true;
- _temp2SceneId = sceneId;
-}
-
-void Insane::smush_rewindCurrentSan(int arg_0, int arg_4, int arg_8) {
- debugC(DEBUG_INSANE, "smush_rewindCurrentSan(%d, %d, %d)", arg_0, arg_4, arg_8);
- _smush_setupsan2 = arg_0;
-
- smush_setupSanFile(0, 0, 0);
- _smush_isSanFileSetup = 1;
- smush_setFrameSteps(arg_4, arg_8);
-
- _smush_curFrame = 0; // HACK
-}
-
-int32 Insane::weaponMaxRange(int32 actornum) {
- static int map[8] = {135, 125, 130, 125, 120, 104, 104, 104};
-
- if (_actor[actornum].weapon == -1)
- return 104;
-
- return map[_actor[actornum].weapon];
-}
-
-int32 Insane::weaponMinRange(int32 actornum) {
- static int map[8] = {80, 40, 80, 40, 80, 80, 40, 50};
-
- if (_actor[actornum].weapon == -1)
- return 40;
-
- return map[_actor[actornum].weapon];
-}
-
-int32 Insane::weaponDamage(int32 actornum) {
- static int map[8] = {20, 300, 25, 40, 15, 10, 10, 5};
-
- if (_actor[actornum].weapon == -1)
- return 10;
-
- return map[_actor[actornum].weapon];
-}
-
-void Insane::reinitActors(void) {
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- smlayer_setActorCostume(0, 2, readArray(11));
- smlayer_setActorCostume(0, 0, readArray(13));
- smlayer_setActorCostume(0, 1, readArray(12));
- } else {
- smlayer_setActorCostume(0, 2, readArray(12));
- smlayer_setActorCostume(0, 0, readArray(14));
- smlayer_setActorCostume(0, 1, readArray(13));
- }
- smlayer_setActorLayer(0, 1, 1);
- smlayer_setActorLayer(0, 2, 5);
- smlayer_setActorLayer(0, 0, 10);
- _actor[0].weapon = INV_HAND;
- _actor[0].weaponClass = 2;
- _actor[0].animWeaponClass = 0;
- _actor[0].newFacingFlag = 2;
- _actor[0].curFacingFlag = 0;
- _actor[0].tilt = 0;
- _actor[0].field_8 = 1;
- _actor[0].act[2].state = 1;
- _actor[0].act[2].animTilt = 1;
- _actor[0].act[0].state = 0;
- _actor[0].act[1].state = 1;
- _actor[0].act[2].room = 1;
- _actor[0].act[1].room = 1;
- _actor[0].act[0].room = 1;
- _actor[0].cursorX = 0;
-}
-
-int Insane::calcTilt(int speed) {
- const int tilt[7] = {-5, -4, -2, 0, 2, 4, 5};
- if (speed + 3 > 6)
- return 0;
-
- return tilt[speed + 3];
-}
-
-bool Insane::actor1StateFlags(int state) {
- // This is compressed table. It contains indexes where state
- // changes. I.e. 0-33: true, 34-38: false 39-72: true, etc.
- const int spans[] = {0, 34, 39, 73, 89, 90, 92, 93, 99, 100, 117};
- bool retvalue = 0;
- unsigned int i;
-
- for (i = 0; i < sizeof(spans); i++) {
- retvalue = !retvalue;
- if (spans[i] <= state)
- break;
- }
- return retvalue;
-}
-
-void Insane::escapeKeyHandler(void) {
- struct fluConf *flu;
-
- // Demos have just one scene
- if (!_insaneIsRunning || _vm->_features & GF_DEMO) {
- smush_setToFinish();
- return;
- }
-
- if (_needSceneSwitch || _keyboardDisable)
- return;
-
- debugC(DEBUG_INSANE, "scene: %d", _currSceneId);
- switch (_currSceneId) {
- case 1:
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300);
- writeArray(9, 0);
- break;
- case 18:
- queueSceneSwitch(17, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300);
- writeArray(9, 1);
- break;
- case 2:
- flu = &_fluConf[14 + _iactSceneId2];
- queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
- flu->startFrame, flu->numFrames);
- break;
- case 3:
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300);
- break;
- case 4:
- if (_needSceneSwitch)
- return;
-
- if (readArray(6)) {
- if (readArray(4)) {
- queueSceneSwitch(14, 0, "hitdust2.san", 64, 0, 0, 0);
- } else {
- queueSceneSwitch(14, 0, "hitdust4.san", 64, 0, 0, 0);
- }
- } else {
- if (readArray(4)) {
- queueSceneSwitch(14, 0, "hitdust1.san", 64, 0, 0, 0);
- } else {
- queueSceneSwitch(14, 0, "hitdust3.san", 64, 0, 0, 0);
- }
- }
- break;
- case 5:
- if (readArray(4)) {
- if (_needSceneSwitch)
- return;
- queueSceneSwitch(15, 0, "vistthru.san", 64, 0, 0, 0);
- } else {
- writeArray(1, _posVista);
- smush_setToFinish();
- }
- break;
- case 6:
- if (readArray(4)) {
- if (_needSceneSwitch)
- return;
- queueSceneSwitch(15, 0, "chasthru.san", 64, 0, 0, 0);
- } else {
- if (readArray(5)) {
- writeArray(1, _val57d);
- smush_setToFinish();
- } else {
- writeArray(4, 1);
- queueSceneSwitch(15, 0, "chasout.san", 64, 0, 0, 0);
- }
- }
- break;
- case 8:
- flu = &_fluConf[7 + _iactSceneId2];
- queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
- flu->startFrame, flu->numFrames);
- break;
- case 7:
- flu = &_fluConf[0 + _iactSceneId2];
- queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
- flu->startFrame, flu->numFrames);
- break;
- case 23:
- _actor[0].damage = 0;
- queueSceneSwitch(21, 0, "rottfite.san", 64, 0, 0, 0);
- break;
- case 9:
- _actor[0].damage = 0;
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300);
- break;
- case 10:
- _actor[0].damage = 0;
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300);
- break;
- case 13:
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300);
- break;
- case 24:
- queueSceneSwitch(21, 0, "rottfite.san", 64, 0, 0, 0);
- break;
- case 16:
- writeArray(4, 0);
- writeArray(5, 1);
- writeArray(1, _posBrokenCar);
- writeArray(3, _posBrokenTruck);
- smush_setToFinish();
- break;
- case 15:
- switch (_tempSceneId) {
- case 5:
- queueSceneSwitch(6, 0, "toranch.san", 64, 0, 0, 530);
- break;
- case 6:
- queueSceneSwitch(4, 0, "tovista1.san", 64, 0, 0, 230);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-}
-
-bool Insane::actor0StateFlags1(int state) {
- const int spans[] = {0, 2, 34, 35, 39, 69, 98, 100, 117};
- bool retvalue = 1;
- unsigned int i;
-
- for (i = 0; i < sizeof(spans); i++) {
- retvalue = !retvalue;
- if (spans[i] >= state)
- break;
- }
- return retvalue;
-}
-
-bool Insane::actor0StateFlags2(int state) {
- const int spans[] = {0, 10, 14, 34, 39, 73, 75, 79, 81, 90, 93, 94,
- 98, 100, 117, 133, 136, 153, 158, 200, 202, 209, 212, 213, 217,
- 219, 236, 256, 259, 272, 277, 311, 312, 315, 317, 328, 331, 332,
- 336, 338, 355, 379, 382, 391, 396, 440, 441, 447, 450, 451, 455,
- 457, 474, 502, 505, 510, 515, 549, 553, 566, 569, 570, 574, 576,
- 593, 601, 604, 629, 634, 680, 682, 685, 688, 689, 693, 695, 712,
- 716, 718, 748, 753, 787, 788, 804, 807, 808, 812, 814, 831, 863,
- 866, 867, 872, 920, 922, 923, 926, 927, 931, 933, 950};
- bool retvalue = 1;
- unsigned int i;
-
- for (i = 0; i < sizeof(spans); i++) {
- retvalue = !retvalue;
- if (spans[i] >= state)
- break;
- }
- return retvalue;
-}
-
-// smlayer_loadSound1 && smlayer_loadSound2
-int Insane::smlayer_loadSound(int id, int flag, int phase) {
- int resid;
-
- if (phase == 1) {
- if (_idx2Exceeded != 0)
- if (_objArray2Idx >= _objArray2Idx2)
- return 0;
- }
- resid = readArray(id);
-
- if (!resid && phase == 2)
- return 0;
-
- if (phase == 2)
- _vm->ensureResourceLoaded(rtSound, resid);
-
- _vm->res.setResourceCounter(rtSound, resid, 1);
-
- if (phase == 1) {
- _objArray2Idx2++;
- _objArray2[_objArray2Idx2] = id;
- if (_objArray2Idx2 >= 100) {
- _idx2Exceeded = 1;
- _objArray2Idx2 = 0;
- }
- }
- return resid;
-}
-
-// smlayer_loadCostume1 && smlayer_loadCostume2
-int Insane::smlayer_loadCostume(int id, int phase) {
- int resid;
- resid = readArray(id);
-
- if (!resid)
- return 0;
-
- _vm->ensureResourceLoaded(rtCostume, resid);
- _vm->res.setResourceCounter(rtCostume, resid, 1);
-
- // smlayer_lock(rtCostume, resid); // FIXME
-
- if (phase == 1) {
- _objArray1Idx2++;
- _objArray1[_objArray1Idx2] = id;
- if (_objArray1Idx2 == 100)
- _objArray1Idx2 = 0;
- }
-
- return resid;
-}
-
-void Insane::smlayer_setActorCostume(int actornum, int actnum, int costume) {
- Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_setActorCostume");
- a->setActorCostume(costume);
- a->setDirection(180);
- a->startAnimActor(1);
- _actor[actornum].act[actnum].frame = 0;
-}
-
-void Insane::smlayer_putActor(int actornum, int actnum, int x, int y, byte room) {
- Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_putActor");
- a->putActor(x, y, room);
-}
-
-void Insane::smlayer_setActorLayer(int actornum, int actnum, int layer) {
- Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_setActorLayer");
- a->_layer = layer;
-}
-
-void Insane::smlayer_setFluPalette(byte *pal, int shut_flag) {
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- return;
-
- // if (shut_flag)
- // // FIXME: shut colors and make picture appear smoothly
- // SmushPlayer::setPalette(pal);
- // else
- _player->setPalette(pal);
-}
-
-bool Insane::smlayer_isSoundRunning(int32 sound) {
- return _vm->_imuseDigital->getSoundStatus(readArray(sound)) != 0;
-}
-
-bool Insane::smlayer_startSfx(int32 sound) {
- if (smlayer_loadSound(sound, 0, 2)) {
- _vm->_imuseDigital->startSfx(readArray(sound), 40);
- return true;
- } else
- return false;
-}
-
-bool Insane::smlayer_startVoice(int32 sound) {
- if (smlayer_loadSound(sound, 0, 2)) {
- _vm->_imuseDigital->startSfx(readArray(sound), 126);
- return true;
- } else
- return false;
-}
-
-void Insane::smlayer_soundSetPan(int32 soundId, int32 pan) {
- _vm->_imuseDigital->setPan(soundId, pan);
-}
-
-void Insane::smlayer_soundSetPriority(int32 soundId, int32 priority) {
- _vm->_imuseDigital->setPriority(soundId, priority);
-}
-
-void Insane::smlayer_drawSomething(byte *renderBitmap, int32 codecparam,
- int32 x, int32 y, int32 arg_10, NutRenderer *nutfile,
- int32 c, int32 arg_1C, int32 arg_20) {
- nutfile->drawFrame(renderBitmap, c, x, y);
-}
-
-void Insane::smlayer_overrideDrawActorAt(byte *arg_0, byte arg_4, byte arg_8) {
- // FIXME: doublecheck
-
- // noop in current implementation
-}
-
-void Insane::smlayer_showStatusMsg(int32 arg_0, byte *renderBitmap, int32 codecparam,
- int32 pos_x, int32 pos_y, int32 arg_14, int32 arg_18,
- int32 flags, const char *formatString, const char *strng) {
- SmushFont *sf = _player->_sf[0];
- int color = 1;
- int32 top = 0;
- char *str = NULL, *string;
- int len = strlen(formatString) + strlen(strng) + 16;
-
- string = (char *)malloc(len);
- str = string;
-
- while (*strng == '/') {
- strng++; // For text resources
- }
-
- snprintf(str, len, formatString, strng);
-
- while (str[0] == '^') {
- switch (str[1]) {
- case 'f':
- {
- int id = str[3] - '0';
- str += 4;
- sf = _player->_sf[id];
- }
- break;
- case 'c':
- {
- color = str[4] - '0' + 10 *(str[3] - '0');
- str += 5;
- }
- break;
- default:
- error("invalid escape code in text string");
- }
- }
-
- assert(sf != NULL);
- sf->setColor(color);
-
- // flags:
- // bit 0 - center 1
- // bit 1 - not used 2
- // bit 2 - ??? 4
- // bit 3 - wrap around 8
- switch (flags) {
- case 0:
- sf->drawString(str, renderBitmap, _player->_width, _player->_height, pos_x, pos_y, false);
- break;
- case 1:
- sf->drawString(str, renderBitmap, _player->_width, _player->_height, pos_x, MAX(pos_y, top), true);
- break;
- case 5:
- sf->drawStringWrap(str, renderBitmap, _player->_width, _player->_height, pos_x, pos_y, 10, 300, true);
- break;
- default:
- error("Insane::smlayer_showStatusMsg. Not handled flags: %d", flags);
- }
- free (string);
-}
-
-void Insane::procSKIP(Chunk &b) {
- int16 par1, par2;
- _player->_skipNext = false;
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- _player->checkBlock(b, TYPE_SKIP, 2);
- par1 = b.getWord();
- if (isBitSet(par1))
- _player->_skipNext = true;
- return;
- }
-
- _player->checkBlock(b, TYPE_SKIP, 4);
-
- par1 = b.getWord();
- par2 = b.getWord();
-
-
- if (!par2) {
- if (isBitSet(par1))
- _player->_skipNext = true;
- return;
- }
-
- if (isBitSet(par1) != isBitSet(par2)) {
- _player->_skipNext = true;
- return;
- }
-}
-
-bool Insane::isBitSet(int n) {
- assert (n < 0x80);
-
- return (_iactBits[n] != 0);
-}
-
-void Insane::setBit(int n) {
- assert (n < 0x80);
-
- _iactBits[n] = 1;
-}
-
-void Insane::clearBit(int n) {
- assert (n < 0x80);
-
- _iactBits[n] = 0;
-}
-
-void Insane::smlayer_setActorFacing(int actornum, int actnum, int frame, int direction) {
- if (_actor[actornum].act[actnum].room) {
- Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_setActorFacing");
- a->setDirection(direction);
- a->startAnimActor(frame);
- _actor[actornum].act[actnum].frame = 0;
- }
-}
-
-const char *Insane::handleTrsTag(int32 trsId) {
- debugC(DEBUG_INSANE, "Insane::handleTrsTag(%d)", trsId);
- return _player->getString(trsId);
-}
-
-bool Insane::smush_eitherNotStartNewFrame(void) {
- if (_smush_setupsan17)
- return false;
-
- if (_smush_isSanFileSetup) {
- if (_smush_frameStep < 0)
- return false;
-
- if (_smush_curFrame > _smush_frameStep + _smush_frameNum2)
- return true;
- else
- return false;
- } else {
- if (_smush_frameNum1 < 0)
- return false;
-
- if (_smush_curFrame >= _smush_frameNum1) {
- _smush_frameNum1 = -1;
- return false;
- } else
- return true;
- }
-}
-
-int32 Insane::getLastKey(bool arg_0) {
- return _vm->_lastKeyHit;
-}
-
-bool Insane::smlayer_actorNeedRedraw(int actornum, int actnum) {
- Actor *a = _vm->derefActor(_actor[actornum].act[actnum].actor, "smlayer_actorNeedRedraw");
-
- return a->_needRedraw;
-}
-
-int32 Insane::readArray (int item) {
- return _vm->readArray(_numberArray, 0, item);
-}
-
-void Insane::writeArray(int item, int value) {
- _vm->writeArray(_numberArray, 0, item, value);
-}
-
-int32 Insane::smush_setupSanWithFlu(const char *filename, int32 setupsan2, int32 step1,
- int32 step2, int32 setupsan1, byte *fluPtr,
- int32 numFrames) {
- byte *tmp = fluPtr;
- int32 offset;
-
- debugC(DEBUG_INSANE, "smush_setupSanWithFlu(%s, %d, %d, %d, %d, %p, %d)", filename, setupsan2,
- step1, step2, setupsan1, fluPtr, numFrames);
-
- _smush_setupsan1 = setupsan1;
-
- /* skip FLUP marker */
- if (READ_BE_UINT32(fluPtr) == 'FLUP')
- tmp += 8;
-
- _smush_setupsan2 = setupsan2;
-
- if (tmp[2] <= 1) {
- /* 0x300 -- palette, 0x8 -- header */
- offset = READ_LE_UINT32(tmp + 0x308 + numFrames*4);
- smush_setupSanFile(filename, offset, numFrames);
- memcpy(_smush_earlyFluContents, tmp+2, 0x306);
- _smush_earlyFluContents[0x30e] = 0;
- _smush_earlyFluContents[0x30f] = 0;
- _smush_earlyFluContents[0x310] = 0;
- _smush_earlyFluContents[0x311] = 0;
- _smush_earlyFluContents[0x306] = 0;
- _smush_earlyFluContents[0x307] = 0;
- } else {
- offset = READ_LE_UINT32(tmp + 0x31c + numFrames*4);
- smush_setupSanFile(filename, offset, numFrames);
- memcpy(_smush_earlyFluContents, tmp+2, 0x31a);
- }
- _smush_isSanFileSetup = 1;
- _smush_setupsan4 = 1;
- _smush_curFrame = numFrames;
- smush_setFrameSteps(step1, step2);
- smush_warpMouse(160, 100, -1);
-
- return offset;
-}
-
-void Insane::smush_setupSanFromStart(const char *filename, int32 setupsan2, int32 step1,
- int32 step2, int32 setupsan1) {
- debugC(DEBUG_INSANE, "Insane::smush_setupFromStart(%s)", filename);
- _smush_setupsan1 = setupsan1;
- _smush_setupsan2 = setupsan2;
- smush_setupSanFile(filename, 0, 0);
- _smush_isSanFileSetup = 1;
- smush_setFrameSteps(step1, step2);
- smush_warpMouse(160, 100, -1);
-}
-
-void Insane::smush_setFrameSteps(int32 step1, int32 step2) {
- _smush_frameNum2 = _smush_curFrame;
- _smush_frameNum1 = step2;
- _smush_frameStep = step1;
-}
-
-void Insane::smush_setupSanFile(const char *filename, int32 offset, int32 contFrame) {
- debugC(DEBUG_INSANE, "Insane::smush_setupSanFile(%s, %x, %d)", filename, offset, contFrame);
-
- _player->seekSan(filename, offset, contFrame);
-}
-
-}
diff --git a/scumm/insane/insane.h b/scumm/insane/insane.h
deleted file mode 100644
index 36567ae06e..0000000000
--- a/scumm/insane/insane.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(INSANE_H) && !defined(DISABLE_SCUMM_7_8)
-#define INSANE_H
-
-#include "base/engine.h"
-#include "scumm/intern.h"
-#include "scumm/nut_renderer.h"
-
-#include "scumm/smush/smush_player.h"
-#include "scumm/smush/chunk.h"
-
-namespace Scumm {
-
-#define INV_CHAIN 0
-#define INV_CHAINSAW 1
-#define INV_MACE 2
-#define INV_2X4 3
-#define INV_WRENCH 4
-#define INV_BOOT 5
-#define INV_HAND 6
-#define INV_DUST 7
-
-#define EN_ROTT1 0 // rottwheeler
-#define EN_ROTT2 1 // rottwheeler
-#define EN_ROTT3 2 // rottwheeler
-#define EN_VULTF1 3 // vulture (redhead female1)
-#define EN_VULTM1 4 // vulture (male with glasses)
-#define EN_VULTF2 5 // vulture (redhead female2)
-#define EN_VULTM2 6 // vulture (initialized as rottwheeler) (male)
-#define EN_CAVEFISH 7 // Cavefish Maximum Fish
-#define EN_TORQUE 8 // Father Torque
-#define EN_BEN 9 // used only with handler
-
-class Insane {
- public:
- Insane(ScummEngine_v6 *scumm);
- ~Insane();
-
- void setSmushParams(int speed);
- void runScene(int arraynum);
-
- void procPreRendering(void);
- void procPostRendering(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- void procSKIP(Chunk &b);
- void escapeKeyHandler(void);
-
- private:
-
- ScummEngine_v6 *_vm;
- SmushPlayer *_player;
-
- int32 _speed;
- bool _insaneIsRunning;
-
- int32 _numberArray;
- int32 _emulTimerId;
- int32 _emulateInterrupt;
- byte _errbuf[0x7d0];
- int32 _flag1d;
- int32 _mainTimerId;
- int32 _objArray1Idx;
- int32 _objArray1Idx2;
- int32 _objArray1[101];
- int32 _objArray2Idx;
- int32 _objArray2Idx2;
- int32 _objArray2[101];
- byte _currSceneId;
- int32 _timer1Flag;
- int32 _timer3Id;
- int32 _timer4Id;
- int32 _timer6Id;
- int32 _timer7Id;
- int32 _timerSpriteId;
- byte _temp2SceneId;
- byte _tempSceneId;
- int32 _currEnemy;
- int32 _currScenePropIdx;
- int32 _currScenePropSubIdx;
- const char *_currTrsMsg;
- int16 _sceneData2Loaded;
- int16 _sceneData1Loaded;
- int16 _keyboardDisable;
- bool _needSceneSwitch;
- int32 _idx2Exceeded;
- int32 _lastKey;
- bool _beenCheated;
- bool _tiresRustle;
- int _keybOldDx;
- int _keybOldDy;
- int _velocityX;
- int _velocityY;
- int _keybX;
- int _keybY;
- int32 _firstBattle;
- bool _weaponBenJustSwitched;
- bool _kickBenProgress;
- int32 _battleScene;
- bool _kickEnemyProgress;
- bool _weaponEnemyJustSwitched;
- int32 _enHdlVar[9][9];
- int32 _smlayer_room;
- int32 _smlayer_room2;
- byte *_smush_roadrashRip; // FIXME: combine them in array
- byte *_smush_roadrsh2Rip;
- byte *_smush_roadrsh3Rip;
- byte *_smush_goglpaltRip;
- byte *_smush_tovista1Flu;
- byte *_smush_tovista2Flu;
- byte *_smush_toranchFlu;
- byte *_smush_minedrivFlu;
- byte *_smush_minefiteFlu;
- NutRenderer *_smush_bencutNut;
- NutRenderer *_smush_bensgoggNut;
- NutRenderer *_smush_iconsNut;
- NutRenderer *_smush_icons2Nut;
- bool _smush_isSanFileSetup;
- bool _isBenCut;
- int _smush_smushState;
- int _continueFrame;
- int _continueFrame1;
- int _counter1;
- int _iactSceneId;
- int _iactSceneId2;
- int _smush_setupsan17;
- int32 _smush_setupsan1;
- int16 _smush_setupsan2;
- int32 _smush_setupsan4;
- int16 _smush_frameStep;
- int16 _smush_curFrame;
- int16 _smush_frameNum1;
- int16 _smush_frameNum2;
- byte _smush_earlyFluContents[0x31a];
- int16 _enemyState[10][10];
- byte _iactBits[0x80];
- int16 _mainRoadPos;
- int16 _posBrokenCar;
- int16 _posBrokenTruck;
- int16 _posFatherTorque;
- int16 _posCave;
- int16 _posVista;
- bool _roadBranch;
- bool _roadStop;
- bool _carIsBroken;
- bool _benHasGoggles;
- bool _mineCaveIsNear;
- bool _objectDetected;
- bool _roadBumps;
- int32 _approachAnim;
- int32 _val54d;
- int32 _val57d;
- bool _val115_;
- int32 _val211d;
- int32 _val213d;
- int32 _metEnemiesListTail;
- int32 _metEnemiesList[12];
-
- struct enemy {
- int32 handler;
- int32 initializer;
- int16 occurences;
- int32 maxdamage;
- int32 isEmpty;
- int32 weapon;
- int32 sound;
- char filename[20];
- int32 costume4;
- int32 costume6;
- int32 costume5;
- int16 costumevar;
- int32 maxframe;
- int32 apprAnim;
- };
-
- struct enemy _enemy[9];
-
- struct fluConf {
- int sceneId;
- byte **fluPtr;
- const char *filenamePtr;
- int startFrame;
- int numFrames;
- };
-
- struct fluConf _fluConf[21];
-
- struct sceneProp {
- int32 actor; // main actor number, -1 if not applicable
- int32 sound;
- int32 trsId;
- byte r;
- byte g;
- byte b;
- int32 counter;
- int32 maxCounter;
- int32 index;
- };
-
- struct sceneProp _sceneProp[139];
-
- struct act {
- int32 actor;
- byte state;
- int32 room;
- int32 animTilt;
- int32 tilt;
- int32 frame;
- };
-
- struct actor {
- int32 damage;
- int32 maxdamage;
- int32 field_8;
- int32 frame;
- int32 tilt;
- int32 cursorX;
- int32 speed;
- int32 x;
- int32 y;
- int32 y1;
- int32 x1;
- int16 weaponClass;
- int16 animWeaponClass;
- int16 newFacingFlag;
- int16 curFacingFlag;
- bool lost;
- bool kicking;
- bool field_44;
- bool field_48; // unused
- bool defunct;
- int32 scenePropSubIdx;
- int32 field_54;
- int32 runningSound;
- int32 weapon;
- bool inventory[8];
- int32 probability;
- int32 enemyHandler;
- struct act act[4];
- };
-
- struct actor _actor[2];
-
- void initvars(void);
- void readFileToMem(const char *name, byte **buf);
- void startVideo(const char *filename, int num, int argC, int frameRate,
- int doMainLoop, byte *fluPtr = 0, int32 startFrame = 0);
- void smush_warpMouse(int x, int y, int buttons);
- void putActors(void);
- void readState(void);
- int initScene(int sceneId);
- void stopSceneSounds(int sceneId);
- void shutCurrentScene(void);
- int loadSceneData(int scene, int flag, int phase);
- void setSceneCostumes(int sceneId);
- void setupValues(void);
- void setEnemyCostumes (void);
- void smlayer_stopSound (int idx);
- int smlayer_loadSound(int id, int flag, int phase);
- int smlayer_loadCostume(int id, int phase);
- void smlayer_setActorCostume(int actornum, int act, int costume);
- void smlayer_putActor(int actornum, int act, int x, int y, byte room);
- void smlayer_setActorLayer(int actornum, int act, int layer);
- void smlayer_setFluPalette(byte *pal, int shut_flag);
-
- int32 readArray(int item);
- void writeArray(int item, int value);
-
- bool idx1Compare(void);
- bool idx2Compare(void);
- int32 idx1Tweak(void);
- int32 idx2Tweak(void);
- void smush_setToFinish(void);
- void postCase11(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase0(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase16(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase2(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase20(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase5(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase8(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase9(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase10(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase12(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase23(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCase14(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCaseAll(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void postCaseMore(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame);
- void switchSceneIfNeeded(void);
- int smush_changeState(int state);
- void init_actStruct(int actornum, int actnum, int32 actorval, byte state,
- int32 room, int32 animtilt, int32 tilt, int32 frame);
- void init_enemyStruct(int n, int32 handler, int32 initializer,
- int16 occurences, int32 maxdamage, int32 isEmpty,
- int32 field_14, int32 sound, const char *filename,
- int32 costume4, int32 costume6, int32 costume5,
- int16 field_2C, int32 field_30, int32 field_34);
- int32 enemyHandler(int n, int32, int32, int32);
- int32 enemyInitializer(int n, int32, int32, int32);
- int32 enemy0handler(int32, int32, int32);
- int32 enemy0initializer(int32, int32, int32);
- int32 enemy1handler(int32, int32, int32);
- int32 enemy1initializer(int32, int32, int32);
- int32 enemy2handler(int32, int32, int32);
- int32 enemy2initializer(int32, int32, int32);
- int32 enemy3handler(int32, int32, int32);
- int32 enemy3initializer(int32, int32, int32);
- int32 enemy4handler(int32, int32, int32);
- int32 enemy4initializer(int32, int32, int32);
- int32 enemy5handler(int32, int32, int32);
- int32 enemy5initializer(int32, int32, int32);
- int32 enemy6handler(int32, int32, int32);
- int32 enemy6initializer(int32, int32, int32);
- int32 enemy7handler(int32, int32, int32);
- int32 enemy7initializer(int32, int32, int32);
- int32 enemy8handler(int32, int32, int32);
- int32 enemy8initializer(int32, int32, int32);
- int32 enemyBenHandler(int32, int32, int32);
- bool smlayer_isSoundRunning(int32 sound);
- bool smlayer_startSfx(int32 sound);
- bool smlayer_startVoice(int32 sound);
- void smlayer_soundSetPan(int32 sound, int32 pan);
- void smlayer_soundSetPriority(int32 sound, int32 priority);
- void smlayer_drawSomething(byte *renderBitmap, int32 codecparam,
- int32 arg_8, int32 arg_C, int32 arg_10, NutRenderer *nutfileptr,
- int32 arg_18, int32 arg_1C, int32 arg_20);
- void smlayer_overrideDrawActorAt(byte *, byte, byte);
- void queueSceneSwitch(int32 sceneId, byte *fluPtr, const char *filename,
- int32 arg_C, int32 arg_10, int32 startFrame, int32 numFrames);
- void turnBen(bool battle);
- void smush_rewindCurrentSan(int arg_0, int arg_4, int arg_8);
- void smlayer_showStatusMsg(int32 arg_0, byte *renderBitmap, int32 codecparam,
- int32 x, int32 y, int32 arg_14, int32 arg_18,
- int32 arg_1C, const char *formatString, const char *str);
- void init_fluConfStruct(int n, int sceneId, byte **fluPtr,
- const char *filenamePtr, int startFrame, int numFrames);
- int32 processBenOnRoad(bool flag);
- void mineChooseRoad(int32 arg_0);
- void actor02Reaction(int32 buttons);
- void actor00Reaction(int32 buttons);
- void actor01Reaction(int32 buttons);
- void actor03Reaction(int32 buttons);
- void turnEnemy(bool battle);
- int32 actionBen(void);
- void chooseBenWeaponAnim(int buttons);
- void setBenAnimation(int32 actornum, int anim);
- int calcTilt(int speed);
- bool smush_eitherNotStartNewFrame(void);
- void smlayer_setActorFacing(int actornum, int actnum, int frame, int direction);
- int32 weaponMaxRange(int32 actornum);
- int32 weaponMinRange(int32 actornum);
- void switchBenWeapon(void);
- void prepareScenePropScene(int32 scenePropNum, bool arg_4, bool arg_8);
- int32 calcBenDamage(bool arg_0, bool arg_4);
- int32 weaponDamage(int32 actornum);
- void proc47(int32 actornum, int32 val);
- bool weaponBenIsEffective(void);
- bool actor1StateFlags(int state);
- bool actor0StateFlags1(int state);
- bool actor0StateFlags2(int state);
- bool loadScenePropSounds(int32 scenePropNum);
- void init_scenePropStruct(int32 n, int32 n1, int32 actornum, int32 sound, int32 trsId,
- byte r, byte g, byte b, int32 counter, int32 maxCounter,
- int32 index);
- int32 setBenState(void);
- bool smlayer_actorNeedRedraw(int actornum, int actnum);
- void reinitActors(void);
- const char *handleTrsTag(int32 trsId);
- void ouchSoundBen(void);
- int32 smush_setupSanWithFlu(const char *filename, int32 setupsan2, int32 step1,
- int32 step2, int32 setupsan1, byte *fluPtr, int32 numFrames);
- void smush_setupSanFromStart(const char *filename, int32 setupsan2, int32 step1,
- int32 step2, int32 setupsan1);
- void smush_setFrameSteps(int32 step1, int32 step2);
- void smush_setupSanFile(const char *filename, int32 offset, int32 contFrame);
- int32 getLastKey(bool arg_0);
- void drawSpeedyActor(int32 arg_0);
- void actor11Reaction(int32 buttons);
- void actor12Reaction(int32 buttons);
- void actor13Reaction(int32 buttons);
- void actor10Reaction(int32 buttons);
- int32 actionEnemy(void);
- int32 processKeyboard(void);
- int32 processMouse(void);
- void setEnemyAnimation(int32 actornum, int anim);
- void chooseEnemyWeaponAnim(int32 buttons);
- void switchEnemyWeapon(void);
- void setEnemyState(void);
- int32 calcEnemyDamage(bool arg_0, bool arg_4);
- void ouchSoundEnemy(void);
- bool weaponEnemyIsEffective(void);
- void iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- void iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- void iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- void iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- void iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- void iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags);
- bool isBitSet(int n);
- void setBit(int n);
- void clearBit(int n);
- void chooseEnemy(void);
- void removeEmptyEnemies(void);
- void removeEnemyFromMetList(int32);
-};
-} // End of namespace Insane
-
-#endif
diff --git a/scumm/insane/insane_ben.cpp b/scumm/insane/insane_ben.cpp
deleted file mode 100644
index 4e58fa14c9..0000000000
--- a/scumm/insane/insane_ben.cpp
+++ /dev/null
@@ -1,2009 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/engine.h"
-
-#include "scumm/insane/insane.h"
-
-namespace Scumm {
-
-int32 Insane::enemyBenHandler(int32 actor1, int32 actor2, int32 probability) {
- int32 retval;
- int32 tmp;
-
- retval = processMouse();
-
- // Joystick support is skipped
-
- retval |= processKeyboard();
-
- tmp = _enemyState[EN_BEN][0] - 160;
- if (tmp < -160)
- tmp = -160;
-
- if (tmp > 160)
- tmp = 160;
-
- _actor[actor1].cursorX = tmp;
-
- smush_warpMouse(_enemyState[EN_BEN][0], _enemyState[EN_BEN][1], -1);
-
- return (retval & 3);
-}
-
-void Insane::turnBen(bool controllable) {
- int32 buttons;
-
- switch (_currSceneId) {
- case 21:
- case 25:
- case 3:
- case 13:
- if (_actor[0].damage < _actor[0].maxdamage) {
- _actor[0].lost = false;
- } else {
- if (!_actor[0].lost && !_actor[1].lost) {
- _actor[0].lost = true;
- _actor[0].act[2].state = 36;
- _actor[0].act[1].state = 36;
- _actor[0].act[1].room = 0;
- _actor[0].act[0].state = 36;
- _actor[0].act[0].room = 0;
-
- if (smlayer_isSoundRunning(95))
- smlayer_stopSound(95);
- }
- }
- buttons = 0;
- if (!_actor[0].lost && controllable) {
- buttons = actionBen();
- if (_currSceneId == 13)
- buttons &= 2;
- if (_currEnemy == EN_TORQUE)
- buttons = 0;
- }
- debug(5, "00:%d 01:%d 02:%d 03:%d", _actor[0].act[0].state,
- _actor[0].act[1].state, _actor[0].act[2].state, _actor[0].act[3].state);
- actor01Reaction(buttons);
- actor02Reaction(buttons);
- actor03Reaction(buttons);
- actor00Reaction(buttons);
- break;
- case 17:
- mineChooseRoad(processBenOnRoad(false));
- break;
- default:
- if (_actor[0].damage < _actor[0].maxdamage) {
- _actor[0].lost = false;
- } else {
- if (!_actor[0].lost && !_actor[1].lost) {
- queueSceneSwitch(10, 0, "wr2_ben.san", 64, 0, 0, 0);
- _actor[0].lost = true;
- _actor[0].act[2].state = 36;
- _actor[0].act[2].room = 0;
- _actor[0].act[0].state = 36;
- _actor[0].act[0].room = 0;
- _actor[0].act[1].state = 36;
- _actor[0].act[1].room = 0;
- mineChooseRoad(0);
- return;
- }
- }
-
- if (!_actor[0].lost && controllable)
- mineChooseRoad(processBenOnRoad(true));
- else
- mineChooseRoad(0);
- break;
- }
-}
-
-int32 Insane::actionBen(void) {
- int32 buttons, tmp;
- bool doDamage = false;
- int sound;
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- sound = 59;
- else
- sound = 95;
-
- if (_actor[0].enemyHandler != -1)
- buttons = enemyHandler(_actor[0].enemyHandler, 0, 1, _actor[0].probability);
- else
- buttons = enemyHandler(EN_TORQUE, 0, 1, _actor[0].probability);
-
- if (_actor[0].tilt) {
- _actor[0].speed += _actor[0].cursorX / 40;
- } else {
- if (_actor[0].speed < 0)
- _actor[0].speed++;
- else
- _actor[0].speed--;
- }
-
- if (_actor[0].speed > 8)
- _actor[0].speed = 8;
-
- if (_actor[0].speed < -8)
- _actor[0].speed = -8;
-
- _actor[0].x += _actor[0].speed;
-
- if (_actor[0].x > 100)
- _actor[0].x--;
- else
- if (_actor[0].x < 100)
- _actor[0].x++;
-
- if (_actor[0].x >= 0) {
- if (_actor[1].x - 90 <= _actor[0].x && !_actor[0].lost && !_actor[1].lost) {
- _val213d++;
- _actor[0].x = _actor[1].x - 90;
-
- tmp = _actor[1].speed;
- _actor[1].speed = _actor[0].speed;
- _actor[0].speed = tmp;
-
- if (_val213d > 50) {
- _actor[0].cursorX = -320;
- _val213d = 0;
- }
-
- if (!smlayer_isSoundRunning(sound))
- smlayer_startSfx(sound);
- } else {
- if (smlayer_isSoundRunning(sound))
- smlayer_stopSound(sound);
-
- _val213d = 0;
- }
- } else {
- _actor[0].x = 0;
- _actor[0].damage++; // FIXME: apparently it is a bug in original
- // and damage is doubled
- doDamage = true;
- }
-
- if (_actor[0].x > 320) {
- _actor[0].x = 320;
- doDamage = true;
- }
-
- if (_actor[0].x < 10 || _actor[0].x > 310 || doDamage) {
- _tiresRustle = 1;
- _actor[0].x1 = -_actor[0].x1;
- _actor[0].damage++; // PATCH
- }
-
- return buttons;
-}
-
-int32 Insane::processBenOnRoad(bool flag) {
- int32 buttons;
-
- if (_actor[0].enemyHandler != -1)
- buttons = enemyHandler(_actor[0].enemyHandler, 0, 1, _actor[0].probability);
- else
- buttons = enemyHandler(EN_TORQUE, 0, 1, _actor[0].probability);
-
- if (flag) {
- _actor[0].speed = _actor[0].tilt;
-
- if (_actor[0].speed > 8)
- _actor[0].speed = 8;
-
- if (_actor[0].speed < -8)
- _actor[0].speed = -8;
-
- _actor[0].x += _actor[0].speed / 2 + _actor[0].speed;
-
- if (_actor[0].x < 0)
- _actor[0].x = 0;
-
- if (_actor[0].x > 320)
- _actor[0].x = 320;
- }
-
- return buttons;
-}
-
-void Insane::mineChooseRoad(int32 buttons) {
- int16 tmp;
-
- if (_actor[0].field_8 < 1)
- return;
-
- if (_actor[0].field_8 == 112) {
- if (_actor[0].frame < 18 || _needSceneSwitch)
- return;
-
- queueSceneSwitch(18, 0, "fishgogg.san", 64, 0, 0, 0);
- } else if (_actor[0].field_8 == 1) {
- tmp = _actor[0].cursorX / 22;
-
- switch (_currSceneId) {
- case 17:
- if (buttons & 1) {
- if (_mineCaveIsNear) {
- writeArray(1, _posCave);
- smush_setToFinish();
- }
-
- if (_roadBranch && !_needSceneSwitch) {
- _iactSceneId2 = _iactSceneId;
- queueSceneSwitch(2, 0, "mineexit.san", 64, 0, 0, 0);
- }
- }
-
- if ((buttons & 2) == 0 || _needSceneSwitch)
- return;
-
- queueSceneSwitch(19, 0, "fishgog2.san", 64, 0, 0, 0);
- break;
- case 1:
- _actor[0].tilt = tmp;
-
- if (tmp < -7)
- _actor[0].tilt = -7;
- if (tmp > 7)
- _actor[0].tilt = 7;
-
- drawSpeedyActor(buttons);
-
- if ((buttons & 1) && _currSceneId == 1 && _roadBranch && !_needSceneSwitch) {
- _iactSceneId2 = _iactSceneId;
- queueSceneSwitch(2, 0, "mineexit.san", 64, 0, 0, 0);
- }
-
- if ((buttons & 2) == 0 || !_benHasGoggles)
- return;
-
- _actor[0].frame = 0;
- _actor[0].field_8 = 112;
- smlayer_setActorFacing(0, 2, 26, 180);
- break;
- case 4:
- case 5:
- _actor[0].tilt = tmp;
-
- if (tmp < -7)
- _actor[0].tilt = -7;
- if (tmp > 7)
- _actor[0].tilt = 7;
-
- drawSpeedyActor(buttons);
-
- if ((buttons & 1) == 0)
- return;
-
- if (_roadBranch && !_needSceneSwitch) {
- _iactSceneId2 = _iactSceneId;
-
- if (readArray(4) && _val211d < 3) {
- _val211d++;
- queueSceneSwitch(8, 0, "fishfear.san", 64, 0, 0, 0);
- } else {
- queueSceneSwitch(8, 0, "tomine.san", 64, 0, 0, 0);
- }
- }
-
- if (_roadStop) {
- writeArray(1, _posBrokenTruck);
- writeArray(3, _val57d);
- smush_setToFinish();
- }
-
- if (!_carIsBroken)
- return;
-
- writeArray(1, _posBrokenCar);
- writeArray(3, _val57d);
- smush_setToFinish();
- break;
- case 6:
- _actor[0].tilt = tmp;
-
- if (tmp < -7)
- _actor[0].tilt = -7;
- if (tmp > 7)
- _actor[0].tilt = 7;
-
- drawSpeedyActor(buttons);
-
- if ((buttons & 1) == 0)
- return;
-
- if (_roadBranch && !_needSceneSwitch) {
- _iactSceneId2 = _iactSceneId;
-
- if (readArray(4) && _val211d < 3) {
- _val211d++;
- queueSceneSwitch(7, 0, "fishfear.san", 64, 0, 0, 0);
- } else {
- queueSceneSwitch(7, 0, "tomine.san", 64, 0, 0, 0);
- }
- }
-
- if (_roadStop) {
- writeArray(1, _posBrokenTruck);
- writeArray(3, _posVista);
- smush_setToFinish();
- }
-
- if (!_carIsBroken)
- return;
-
- writeArray(1, _posBrokenCar);
- writeArray(3, _posVista);
- smush_setToFinish();
- break;
- default:
- break;
- }
- }
-}
-
-void Insane::drawSpeedyActor(int32 buttons) {
- switch (_actor[0].tilt) {
- case -7:
- if (_actor[0].act[2].state != 47) {
- smlayer_setActorFacing(0, 2, 13, 180);
- _actor[0].act[2].state = 47;
- }
- break;
- case -6:
- if (_actor[0].act[2].state != 44) {
- smlayer_setActorFacing(0, 2, 11, 180);
- _actor[0].act[2].state = 44;
- }
- break;
- case -5:
- if (_actor[0].act[2].state != 43) {
- smlayer_setActorFacing(0, 2, 10, 180);
- _actor[0].act[2].state = 43;
- }
- break;
- case -4:
- if (_actor[0].act[2].state != 42) {
- smlayer_setActorFacing(0, 2, 9, 180);
- _actor[0].act[2].state = 42;
- }
- break;
- case -3:
- if (_actor[0].act[2].state != 41) {
- smlayer_setActorFacing(0, 2, 8, 180);
- _actor[0].act[2].state = 41;
- }
- break;
- case -2:
- if (_actor[0].act[2].state != 40) {
- smlayer_setActorFacing(0, 2, 7, 180);
- _actor[0].act[2].state = 40;
- }
- break;
- case -1:
- if (_actor[0].act[2].state != 39) {
- smlayer_setActorFacing(0, 2, 6, 180);
- _actor[0].act[2].state = 39;
- }
- break;
- case 0:
- if (_actor[0].act[2].state != 1) {
- smlayer_setActorFacing(0, 2, 22, 180);
- _actor[0].act[2].state = 1;
- }
- break;
- case 1:
- if (_actor[0].act[2].state != 55) {
- smlayer_setActorFacing(0, 2, 14, 180);
- _actor[0].act[2].state = 55;
- }
- break;
- case 2:
- if (_actor[0].act[2].state != 56) {
- smlayer_setActorFacing(0, 2, 15, 180);
- _actor[0].act[2].state = 56;
- }
- break;
- case 3:
- if (_actor[0].act[2].state != 57) {
- smlayer_setActorFacing(0, 2, 16, 180);
- _actor[0].act[2].state = 57;
- }
- break;
- case 4:
- if (_actor[0].act[2].state != 58) {
- smlayer_setActorFacing(0, 2, 17, 180);
- _actor[0].act[2].state = 58;
- }
- break;
- case 5:
- if (_actor[0].act[2].state != 59) {
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].act[2].state = 59;
- }
- break;
- case 6:
- if (_actor[0].act[2].state != 60) {
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 60;
- }
- break;
- case 7:
- if (_actor[0].act[2].state != 50) {
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 50;
- }
- break;
- default:
- break;
- }
-
- if (!_actor[0].act[2].room)
- return;
-
- smlayer_putActor(0, 2, _actor[0].x + _actor[0].x1, _actor[0].y + _actor[0].y1,
- _smlayer_room2);
-}
-
-bool Insane::weaponBenIsEffective(void) {
- if ((_actor[1].x - _actor[0].x > weaponMaxRange(0)) ||
- (_actor[1].x - _actor[0].x < weaponMinRange(0)) ||
- !_actor[1].kicking)
- return false;
-
- return true;
-}
-
-int32 Insane::calcBenDamage(bool arg_0, bool arg_4) {
- if ((_actor[1].x - _actor[0].x > weaponMaxRange(1)) ||
- (_actor[1].x - _actor[0].x < weaponMinRange(1)))
- return 0;
-
- if (_actor[0].field_44 && arg_4)
- return 1000;
-
- if (!actor1StateFlags(_actor[0].act[2].state))
- return 0;
-
- if (arg_0) {
- ouchSoundBen();
- _actor[0].damage += weaponDamage(1); // PATCH
- }
-
- return 1;
-}
-
-// Ben
-void Insane::actor02Reaction(int32 buttons) {
- int32 tmp, tmp2;
-
- switch(_actor[0].act[2].state) {
- case 1:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 2;
- _actor[0].kicking = false;
-
- switch (_actor[0].tilt) {
- case -3:
- if (_actor[0].act[2].animTilt != -3) {
- smlayer_setActorFacing(0, 2, 6, 180);
- _actor[0].act[2].animTilt = -3;
- }
- break;
- case -2:
- if (_actor[0].field_8 == 48)
- smlayer_setActorFacing(0, 2, 7, 180);
- _actor[0].act[2].animTilt = -2;
- break;
- case -1:
- if (_actor[0].field_8 == 46)
- smlayer_setActorFacing(0, 2, 8, 180);
- _actor[0].act[2].animTilt = -1;
- break;
- case 0:
- if (_actor[0].act[2].animTilt) {
- smlayer_setActorFacing(0, 2, 9, 180);
- _actor[0].act[2].animTilt = 0;
- }
- break;
- case 1:
- if (_actor[0].field_8 == 49)
- smlayer_setActorFacing(0, 2, 10, 180);
- _actor[0].act[2].animTilt = 1;
- break;
- case 2:
- if (_actor[0].field_8 == 51)
- smlayer_setActorFacing(0, 2, 11, 180);
- _actor[0].act[2].animTilt = 2;
- break;
- case 3:
- if (_actor[0].act[2].animTilt != 3) {
- smlayer_setActorFacing(0, 2, 12, 180);
- _actor[0].act[2].animTilt = 3;
- }
- break;
- default:
- break;
- }
- _actor[0].act[2].tilt = 0;
- break;
- case 2:
- smlayer_setActorLayer(0, 2, 4);
- smlayer_setActorFacing(0, 2, 17, 180);
- _actor[0].kicking = true;
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 3;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(63);
- break;
- case 3:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- if (_actor[0].act[2].frame == 2) {
- if (_currEnemy != EN_CAVEFISH) {
- tmp = calcEnemyDamage(1, 1);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- if (tmp == 1)
- smlayer_startSfx(50);
- } else {
- if (tmp == 1)
- smlayer_startSfx(60);
- if (tmp == 1000)
- smlayer_startSfx(62);
- }
- } else {
- if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) &&
- (_actor[1].x - _actor[0].x >= weaponMinRange(0)) &&
- !_actor[0].field_54)
- prepareScenePropScene(1, 0, 0);
- }
- }
- if (_actor[0].act[2].frame >= 4) {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 4;
- }
-
- _actor[0].kicking = true;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 4:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 2) {
- smlayer_setActorFacing(0, 2, 9, 180);
- _actor[0].act[2].state = 1;
- _actor[0].act[2].animTilt = -1000;
- _actor[0].weaponClass = 2;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 5:
- smlayer_setActorLayer(0, 2, 5);
- break;
- case 6:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 2;
- _actor[0].newFacingFlag = 1;
- _actor[0].kicking = false;
- smlayer_setActorCostume(0, 2, readArray(22));
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 7;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(66);
- break;
- case 7:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 2;
- _actor[0].newFacingFlag = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 1) {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 8;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 8:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 2;
- _actor[0].newFacingFlag = 1;
- _actor[0].kicking = false;
- if ((_actor[0].act[2].frame == 3) && (calcEnemyDamage(0, 0) == 1)) {
- _actor[1].damage = weaponDamage(0);
- smlayer_startSfx(64);
- _actor[1].cursorX = 320;
- }
- if (_actor[0].act[2].frame >= 5) {
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 9;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 9:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 2;
- _actor[0].newFacingFlag = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 3) {
- smlayer_setActorCostume(0, 2, readArray(12));
- _actor[0].newFacingFlag = 2;
- _actor[0].act[2].state = 1;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 10:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 11;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(75);
- break;
- case 11:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 2) {
- if (_currEnemy == EN_VULTM2) {
- if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) &&
- (_actor[1].x - _actor[0].x >= weaponMinRange(0)) &&
- calcEnemyDamage(0, 0)) {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 97;
- _actor[0].act[2].room = 0;
- _actor[0].act[1].room = 0;
- _actor[0].act[0].room = 0;
- smlayer_setActorLayer(0, 2, 25);
- smlayer_setActorCostume(1, 2, readArray(45));
- smlayer_setActorFacing(1, 2, 6, 180);
- smlayer_startSfx(101);
- _actor[1].act[2].state = 97;
- _actor[1].lost = true;
- _actor[1].act[2].room = 1;
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- } else {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 12;
- }
- } else {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 12;
- }
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 12:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 1) {
- if (_currEnemy != EN_CAVEFISH) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_DUST:
- tmp = calcEnemyDamage(1, 1);
- if (tmp == 1)
- smlayer_startSfx(73);
- if (tmp == 1000)
- smlayer_startSfx(74);
- break;
- default:
- if (calcEnemyDamage(1, 0) == 1)
- smlayer_startSfx(73);
- break;
- }
- } else {
- if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) &&
- (_actor[1].x - _actor[0].x >= weaponMinRange(0)) &&
- !_actor[0].field_54)
- prepareScenePropScene(1, 0, 0);
-
- }
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 13;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 13:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 3) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 63;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 14:
- smlayer_setActorLayer(0, 2, 8);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 15;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(78);
- break;
- case 15:
- smlayer_setActorLayer(0, 2, 8);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 2) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- if (weaponBenIsEffective()) {
- smlayer_setActorFacing(0, 2, 22, 180);
- _actor[0].act[2].state = 81;
- } else {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 16;
- }
- break;
- case INV_MACE:
- if (!_actor[1].kicking || _actor[1].field_44)
- if (actor1StateFlags(_actor[1].act[2].state)) {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 106;
- break;
- }
- default:
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 16;
- break;
- }
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 16:
- smlayer_setActorLayer(0, 2, 8);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 1) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- tmp = calcEnemyDamage(1, 1);
- if (tmp == 1)
- smlayer_startSfx(76);
- if (tmp == 1000)
- smlayer_startSfx(77);
- break;
- case INV_BOOT:
- calcEnemyDamage(0, 1);
- break;
- case INV_DUST:
- if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) &&
- (_actor[1].x - _actor[0].x >= weaponMinRange(0))) {
- smlayer_startSfx(76);
- _actor[1].damage = weaponDamage(0);
- }
- break;
- default:
- if (calcEnemyDamage(1, 0))
- smlayer_startSfx(76);
- break;
- }
- smlayer_setActorFacing(0, 2, 21,180);
- _actor[0].act[2].state = 17;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 17:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 2) {
- smlayer_setActorFacing(0, 2, 26, 180);
- _actor[0].act[2].state = 64;
- smlayer_stopSound(76);
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 18:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 19;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(69);
- break;
- case 19:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 1) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- if (_actor[1].kicking) {
- _actor[1].act[2].state = 108;
- _actor[0].act[2].state = 110;
- } else {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 20;
- }
- break;
- case INV_CHAINSAW:
- if (_actor[1].kicking || _actor[1].field_44)
- _actor[0].act[2].state = 20;
- else {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 20;
- }
- break;
- case INV_MACE:
- case INV_2X4:
- if (weaponBenIsEffective()) {
- smlayer_setActorFacing(0, 2, 22, 180);
- _actor[0].act[2].state = 77;
- break;
- }
- // break skipped intentionally
- default:
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 20;
- break;
- }
- }
-
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 20:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 1) {
- if (_currEnemy != EN_CAVEFISH) {
- switch (_actor[1].weapon) {
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_BOOT:
- tmp = calcEnemyDamage(1, 1);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- if (tmp == 1)
- smlayer_startSfx(52);
- if (tmp == 1000)
- smlayer_startSfx(56);
- } else {
- if (tmp == 1)
- smlayer_startSfx(67);
- if (tmp == 1000)
- smlayer_startSfx(68);
- }
- break;
- default:
- if (calcEnemyDamage(1, 0))
- smlayer_startSfx(67);
- break;
- }
- } else {
- if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) &&
- (_actor[1].x - _actor[0].x >= weaponMinRange(0)) &&
- !_actor[0].field_54)
- prepareScenePropScene(1, 0, 0);
- }
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 21;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 21:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 6) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 65;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 22:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 0;
- _actor[0].kicking = true;
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 23;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(81);
- break;
- case 23:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 0;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 4) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_BOOT:
- case INV_DUST:
- if (weaponBenIsEffective()) {
- smlayer_setActorFacing(0, 2, 22, 180);
- _actor[0].act[2].state = 83;
- break;
- }
- // break missed intentionally
- default:
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 24;
- break;
- }
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 24:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 0;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 1) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_BOOT:
- case INV_DUST:
- tmp = calcEnemyDamage(1, 1);
- if (tmp == 1) {
- if (_currEnemy == EN_CAVEFISH) {
- _actor[1].lost = true;
- _actor[1].act[2].state = 102;
- _actor[1].damage = _actor[1].maxdamage + 10;
- }
- smlayer_startSfx(79);
- }
- if (tmp == 1000)
- smlayer_startSfx(80);
- break;
- default:
- if (!calcEnemyDamage(1, 0))
- smlayer_startSfx(79);
- break;
- }
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 25;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 25:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 0;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 6) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 66;
- _actor[0].weaponClass = 1;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 26:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 27;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)))
- smlayer_startSfx(72);
- break;
- case 27:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 1) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_BOOT:
- case INV_DUST:
- if (weaponBenIsEffective()) {
- smlayer_setActorFacing(0, 2, 22, 180);
- _actor[0].act[2].state = 75;
- break;
- }
- // break missed intentionaly
- default:
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 28;
- break;
- }
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 28:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 3) {
- if (_currEnemy != EN_CAVEFISH) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_BOOT:
- case INV_DUST:
- tmp = calcEnemyDamage(1, 1);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- if (tmp == 1)
- smlayer_startSfx(58);
- if (tmp == 1000)
- smlayer_startSfx(56);
- } else {
- if (tmp == 1)
- smlayer_startSfx(70);
- if (tmp == 1000)
- smlayer_startSfx(71);
- }
- break;
- case INV_HAND:
- if (!calcEnemyDamage(1, 0))
- smlayer_startSfx(70);
- break;
- default:
- break;
- }
- } else {
- if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) &&
- (_actor[1].x - _actor[0].x >= weaponMinRange(0)) &&
- !_actor[0].field_54)
- prepareScenePropScene(1, 0, 0);
- }
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 29;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 29:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 6) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 62;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 30:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- smlayer_setActorCostume(0, 2, readArray(21));
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].act[2].state = 31;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- smlayer_startSfx(84);
- break;
- case 31:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- if (_actor[0].act[2].frame >= 6) {
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].state = 32;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 32:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- if (_actor[0].act[2].frame >= 5) {
- switch (_currEnemy) {
- case EN_ROTT3:
- if (calcEnemyDamage(0, 0))
- _actor[1].act[2].state = 115;
- break;
- case EN_VULTF2:
- if (calcEnemyDamage(0, 0))
- _actor[1].act[2].state = 113;
- break;
- default:
- tmp = calcEnemyDamage(1, 1);
- if (tmp == 1)
- smlayer_startSfx(82);
- if (tmp == 1000)
- smlayer_startSfx(83);
- break;
- }
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 33;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 33:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 5) {
- smlayer_setActorCostume(0, 2, readArray(12));
- _actor[0].act[2].state = 1;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 34:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].kicking = false;
-
- if (!smlayer_actorNeedRedraw(0, 2)) {
- setBenState();
- _actor[0].act[2].tilt = 0;
- // for some reason there is no break at this
- // place, so tilt gets overriden on next line
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 35:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].kicking = false;
-
- if (!smlayer_actorNeedRedraw(0, 2)) {
- switchBenWeapon();
- _actor[0].act[2].tilt = 0;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 36:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].kicking = false;
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- smlayer_setActorCostume(0, 2, readArray(17));
- else
- smlayer_setActorCostume(0, 2, readArray(18));
- smlayer_setActorFacing(0, 2, 6, 180);
- smlayer_startSfx(96);
- switch (_currEnemy) {
- case EN_ROTT1:
- prepareScenePropScene(33, 0, 0);
- break;
- case EN_ROTT2:
- tmp = _vm->_rnd.getRandomNumber(4);
- if (!tmp)
- prepareScenePropScene(35, 0, 0);
- if (tmp == 3)
- prepareScenePropScene(36, 0, 0);
- break;
- case EN_VULTF1:
- prepareScenePropScene(6, 0, 0);
- break;
- case EN_VULTM1:
- tmp = _vm->_rnd.getRandomNumber(4);
- if (!tmp)
- prepareScenePropScene(40, 0, 0);
- if (tmp == 3)
- prepareScenePropScene(41, 0, 0);
- break;
- default:
- break;
- }
- _actor[0].act[2].state = 37;
- break;
- case 37:
- smlayer_setActorLayer(0, 2, 25);
- _actor[0].cursorX = 0;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 18 ||
- (_actor[0].x < 50 && _actor[0].act[2].frame >= 10) ||
- (_actor[0].x > 270 && _actor[0].act[2].frame >= 10)) {
- if (_currSceneId == 21) {
- queueSceneSwitch(23, 0, "benflip.san", 64, 0, 0, 0);
- } else {
- switch (_currEnemy) {
- case EN_ROTT1:
- case EN_ROTT2:
- case EN_ROTT3:
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- queueSceneSwitch(9, 0, "bencrshe.san", 64, 0, 0, 0);
- else
- queueSceneSwitch(9, 0, "wr2_benr.san", 64, 0, 0, 0);
- break;
- case EN_VULTF1:
- case EN_VULTM1:
- case EN_VULTF2:
- case EN_VULTM2:
- queueSceneSwitch(9, 0, "wr2_benv.san", 64, 0, 0, 0);
- break;
- case EN_CAVEFISH:
- queueSceneSwitch(9, 0, "wr2_benc.san", 64, 0, 0, 0);
- break;
- default:
- queueSceneSwitch(9, 0, "wr2_ben.san", 64, 0, 0, 0);
- break;
- }
- }
- _actor[0].act[2].state = 38;
- }
- break;
- case 38:
- if (_actor[0].act[2].frame >= 36) {
- _actor[0].act[2].frame = 0;
- if (_currSceneId == 21) {
- queueSceneSwitch(23, 0, "benflip.san", 64, 0, 0, 0);
- } else {
- switch (_currEnemy) {
- case EN_ROTT1:
- case EN_ROTT2:
- case EN_ROTT3:
- queueSceneSwitch(9, 0, "wr2_benr.san", 64, 0, 0, 0);
- break;
- case EN_VULTF1:
- case EN_VULTM1:
- case EN_VULTF2:
- case EN_VULTM2:
- queueSceneSwitch(9, 0, "wr2_benv.san", 64, 0, 0, 0);
- break;
- case EN_CAVEFISH:
- queueSceneSwitch(9, 0, "wr2_benc.san", 64, 0, 0, 0);
- break;
- default:
- queueSceneSwitch(9, 0, "wr2_ben.san", 64, 0, 0, 0);
- break;
- }
- }
- _actor[0].act[2].state = 38;
- }
- break;
- case 63:
- smlayer_setActorLayer(0, 2, 5);
- if (_actor[0].act[2].animTilt) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].animTilt = 0;
- }
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 64:
- smlayer_setActorLayer(0, 2, 5);
- if (_actor[0].act[2].animTilt) {
- smlayer_setActorFacing(0, 2, 26, 180);
- _actor[0].act[2].animTilt = 0;
- }
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 65:
- smlayer_setActorLayer(0, 2, 5);
- if (_actor[0].act[2].animTilt) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].animTilt = 0;
- }
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 66:
- smlayer_setActorLayer(0, 2, 5);
- if (_actor[0].act[2].animTilt) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].animTilt = 0;
- }
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 62:
- smlayer_setActorLayer(0, 2, 5);
- if (_actor[0].act[2].animTilt) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].animTilt = 0;
- }
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 73:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = true;
- if (_actor[0].act[2].frame >= 2 && !_kickBenProgress) {
- smlayer_setActorFacing(0, 2, 19, 180);
- _actor[0].act[2].state = 74;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 74:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- if (_actor[0].act[2].frame >= 2) {
- smlayer_setActorFacing(0, 2, 9, 180);
- _actor[0].act[2].state = 1;
- _actor[0].weaponClass = 2;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 75:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = true;
- if (_actor[0].act[2].frame >= 4 && !_kickBenProgress) {
- smlayer_setActorFacing(0, 2, 23, 180);
- _actor[0].act[2].state = 76;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 76:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- if (_actor[0].act[2].frame >= 4) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 62;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 77:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = true;
- if (_actor[0].act[2].frame >= 2) {
- smlayer_setActorFacing(0, 2, 23, 180);
- _actor[0].act[2].state = 78;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 78:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- if (_actor[0].act[2].frame >= 5) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 65;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 79:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = true;
- if (_actor[0].act[2].frame >= 2) {
- smlayer_setActorFacing(0, 2, 23, 180);
- _actor[0].act[2].state = 80;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 80:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- if (_actor[0].act[2].frame >= 6) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 63;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 81:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = true;
- if (_actor[0].act[2].frame >= 2 && !_kickBenProgress) {
- smlayer_setActorFacing(0, 2, 23, 180);
- _actor[0].act[2].state = 82;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 82:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- if (_actor[0].act[2].frame >= 3) {
- smlayer_setActorFacing(0, 2, 26, 180);
- _actor[0].act[2].state = 64;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 83:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 0;
- _actor[0].kicking = false;
- _actor[0].field_44 = true;
- if (_actor[0].act[2].frame >= 2 && !_kickBenProgress) {
- smlayer_setActorFacing(0, 2, 23, 180);
- _actor[0].act[2].state = 84;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 84:
- smlayer_setActorLayer(0, 2, 6);
- _actor[0].weaponClass = 0;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- if (_actor[0].act[2].frame >= 5) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 66;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 97:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = true;
- if (_actor[0].act[2].frame >= 5) {
- _actor[0].act[2].room = 1;
- _actor[0].act[1].room = 1;
- _actor[0].act[0].room = 1;
- smlayer_setActorFacing(0, 2, 21, 180);
- _actor[0].act[2].state = 13;
- _actor[0].x = _actor[1].x - 116;
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 104:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- smlayer_setActorFacing(0, 2, 28, 180);
- _actor[0].act[2].state = 105;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 105:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 5) {
- _actor[0].act[2].state = 1;
- _actor[0].inventory[INV_MACE] = 0;
- smlayer_startVoice(318);
- switchBenWeapon();
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 106:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- smlayer_setActorFacing(0, 2, 29, 180);
- _actor[0].act[2].state = 107;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 107:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 9) {
- _actor[0].act[2].state = 1;
- _actor[0].inventory[INV_MACE] = 0;
- smlayer_startVoice(318);
- switchBenWeapon();
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 108:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- smlayer_setActorFacing(0, 2, 28, 180);
- _actor[0].act[2].state = 109;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 109:
- smlayer_setActorLayer(0, 2, 5);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 5) {
- _actor[0].act[2].state = 1;
- _actor[0].inventory[INV_CHAIN] = 0; // Chain
- smlayer_startVoice(318);
- switchBenWeapon();
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 110:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- smlayer_setActorFacing(0, 2, 30, 180);
- _actor[0].act[2].state = 111;
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- case 111:
- smlayer_setActorLayer(0, 2, 4);
- _actor[0].weaponClass = 1;
- _actor[0].kicking = false;
- if (_actor[0].act[2].frame >= 7) {
- smlayer_setActorFacing(0, 2, 25, 180);
- _actor[0].act[2].state = 65;
- _actor[0].inventory[INV_CHAIN] = 1; // Chain
- }
- _actor[0].act[2].tilt = calcTilt(_actor[0].tilt);
- break;
- default:
- break;
- }
- tmp = _actor[0].x + _actor[0].act[2].tilt + 17 + _actor[0].x1;
- tmp2 = _actor[0].y + _actor[0].y1 - 98;
-
- if (_actor[0].act[2].room)
- smlayer_putActor(0, 2, tmp, tmp2, _smlayer_room2);
- else
- smlayer_putActor(0, 2, tmp, tmp2, _smlayer_room);
-}
-
-// Bike
-void Insane::actor00Reaction(int32 buttons) {
- int32 tmpx, tmpy;
-
- switch (_actor[0].tilt) {
- case -3:
- if (_actor[0].act[0].state != 41) {
- smlayer_setActorFacing(0, 0, 6, 180);
- _actor[0].act[0].state = 41;
- }
- break;
- case -2:
- if (_actor[0].act[0].state != 40) {
- smlayer_setActorFacing(0, 0, 7, 180);
- _actor[0].act[0].state = 40;
- }
- break;
- case -1:
- if (_actor[0].act[0].state != 39) {
- smlayer_setActorFacing(0, 0, 8, 180);
- _actor[0].act[0].state = 39;
- }
- break;
- case 0:
- if (_actor[0].act[0].state != 1) {
- smlayer_setActorFacing(0, 0, 9, 180);
- _actor[0].act[0].state = 1;
- }
- break;
- case 1:
- if (_actor[0].act[0].state != 55) {
- smlayer_setActorFacing(0, 0, 10, 180);
- _actor[0].act[0].state = 55;
- }
- break;
- case 2:
- if (_actor[0].act[0].state != 56) {
- smlayer_setActorFacing(0, 0, 11, 180);
- _actor[0].act[0].state = 56;
- }
- break;
- case 3:
- if (_actor[0].act[0].state != 57) {
- smlayer_setActorFacing(0, 0, 12, 180);
- _actor[0].act[0].state = 57;
- }
- break;
- default:
- break;
- }
- tmpx = _actor[0].x + _actor[0].x1;
- tmpy = _actor[0].y + _actor[0].y1;
-
- if (_actor[0].act[0].room)
- smlayer_putActor(0, 0, tmpx, tmpy, _smlayer_room2);
- else
- smlayer_putActor(0, 0, tmpx, tmpy, _smlayer_room);
-}
-
-// Bike top
-void Insane::actor01Reaction(int32 buttons) {
- int32 tmpx, tmpy;
-
- chooseBenWeaponAnim(buttons);
-
- switch (_actor[0].tilt) {
- case -3:
- if (_actor[0].act[1].state != 41 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 6);
- _actor[0].act[1].state = 41;
- }
-
- if (_actor[0].cursorX >= -100) {
- setBenAnimation(0, 7);
- _actor[0].act[1].state = 40;
- _actor[0].field_8 = 48;
- _actor[0].tilt = -2;
- }
- break;
- case -2:
- if (_actor[0].act[1].state != 40 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 7);
- _actor[0].act[1].state = 40;
- }
- if (_actor[0].field_8 == 48)
- _actor[0].tilt = -1;
- else
- _actor[0].tilt = -3;
- break;
- case -1:
- if (_actor[0].act[1].state != 39 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 8);
- _actor[0].act[1].state = 39;
- }
-
- if (_actor[0].field_8 == 48)
- _actor[0].tilt = 0;
- else
- _actor[0].tilt = -2;
- break;
- case 0:
- if (_actor[0].act[1].state != 1 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 9);
- _actor[0].act[1].state = 1;
- }
- _actor[0].field_8 = 1;
- if (_actor[0].cursorX < -100) {
- setBenAnimation(0, 8);
- _actor[0].act[1].state = 39;
- _actor[0].field_8 = 46;
- _actor[0].tilt = -1;
- } else {
- if (_actor[0].cursorX > 100) {
- setBenAnimation(0, 10);
- _actor[0].act[1].state = 55;
- _actor[0].field_8 = 49;
- _actor[0].tilt = 1;
- }
- }
- break;
- case 1:
- if (_actor[0].act[1].state != 55 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 10);
- _actor[0].act[1].state = 55;
- }
- if (_actor[0].field_8 == 51)
- _actor[0].tilt = 0;
- else
- _actor[0].tilt = 2;
- break;
- case 2:
- if (_actor[0].act[1].state != 56 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 11);
- _actor[0].act[1].state = 56;
- }
- if (_actor[0].field_8 == 51)
- _actor[0].tilt = 1;
- else
- _actor[0].tilt = 3;
- break;
- case 3:
- if (_actor[0].act[1].state != 57 || _actor[0].weaponClass != _actor[0].animWeaponClass) {
- setBenAnimation(0, 12);
- _actor[0].act[1].state = 57;
- }
-
- if (_actor[0].cursorX <= 100) {
- setBenAnimation(0, 11);
- _actor[0].act[1].state = 56;
- _actor[0].field_8 = 51;
- _actor[0].tilt = 2;
- }
- break;
- }
-
- if (_actor[0].curFacingFlag != _actor[0].newFacingFlag) {
- if (_actor[0].newFacingFlag == 2)
- smlayer_setActorFacing(0, 1, 28, 180);
- else
- smlayer_setActorFacing(0, 1, 27, 180);
- }
-
- tmpx = _actor[0].x + _actor[0].x1;
- tmpy = _actor[0].y + _actor[0].y1;
-
- if (_actor[0].act[1].room)
- smlayer_putActor(0, 1, tmpx, tmpy, _smlayer_room2);
- else
- smlayer_putActor(0, 1, tmpx, tmpy, _smlayer_room);
-
- _actor[0].animWeaponClass = _actor[0].weaponClass;
- _actor[0].curFacingFlag = _actor[0].newFacingFlag;
-}
-
-void Insane::actor03Reaction(int32 buttons) {
- int32 tmp;
-
- switch (_actor[0].act[3].state) {
- case 1:
- _actor[0].field_54 = 0;
- break;
- case 52:
- if (_actor[0].runningSound)
- smlayer_stopSound(_actor[0].runningSound);
-
- if (_currScenePropIdx)
- shutCurrentScene();
-
- _actor[0].runningSound = 0;
- _actor[0].defunct = 0;
- _actor[0].field_54 = 0;
- smlayer_setActorFacing(0, 3, 15, 180);
- _actor[0].act[3].state = 53;
- break;
- case 53:
- if (_actor[0].act[3].frame >= 2) {
- smlayer_setActorFacing(0, 3, 16, 180);
- _actor[0].act[3].state = 54;
- }
- break;
- case 54:
- break;
- case 69:
- if (_actor[0].act[3].frame >= 2)
- _actor[0].act[3].state = 70;
- break;
- case 70:
- if (_actor[0].scenePropSubIdx) {
- smlayer_setActorFacing(0, 3, 4, 180);
- tmp = _currScenePropIdx + _actor[0].scenePropSubIdx;
- if (!smlayer_startVoice(_sceneProp[tmp].sound))
- _actor[0].runningSound = 0;
- else
- _actor[0].runningSound = _sceneProp[tmp].sound;
- _actor[0].act[3].state = 72;
- } else {
- _actor[0].act[3].state = 118;
- }
- break;
- case 71:
- _actor[0].field_54 = 0;
- if (_actor[0].act[3].frame >= 2)
- _actor[0].act[3].state = 1;
- break;
- case 72:
- if (_actor[0].runningSound) {
- if (!smlayer_isSoundRunning(_actor[0].runningSound)) {
- smlayer_setActorFacing(0, 3, 5, 180);
- _actor[0].act[3].state = 70;
- _actor[0].scenePropSubIdx = 0;
- }
- } else {
- tmp = _currScenePropIdx + _actor[0].scenePropSubIdx;
- if (_sceneProp[tmp].counter >= _sceneProp[tmp].maxCounter) {
- smlayer_setActorFacing(0, 3, 5, 180);
- _actor[0].act[3].state = 70;
- _actor[0].scenePropSubIdx = 0;
- _actor[0].runningSound = 0;
- }
- }
- break;
- case 117:
- reinitActors();
- smlayer_setActorFacing(0, 3, 13, 180);
- _actor[0].act[3].state = 69;
- break;
- case 118:
- smlayer_setActorFacing(0, 3, 14, 180);
- _actor[0].act[3].state = 71;
- break;
- default:
- break;
- }
-}
-
-void Insane::chooseBenWeaponAnim(int buttons) {
- // kick
- if ((buttons & 1) && (_currEnemy != EN_TORQUE)) {
- if (!_kickBenProgress && actor0StateFlags2(_actor[0].act[2].state + _actor[0].weapon * 119)) {
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- _actor[0].act[2].state = 10;
- break;
- case INV_CHAINSAW:
- _actor[0].act[2].state = 14;
- break;
- case INV_MACE:
- _actor[0].act[2].state = 18;
- break;
- case INV_2X4:
- _actor[0].act[2].state = 22;
- break;
- case INV_WRENCH:
- _actor[0].act[2].state = 26;
- break;
- case INV_BOOT:
- _actor[0].act[2].state = 6;
- break;
- case INV_HAND:
- _actor[0].act[2].state = 2;
- break;
- case INV_DUST:
- _actor[0].act[2].state = 30;
- break;
- default:
- break;
- }
- _actor[0].kicking = true;
- _kickBenProgress = true;
- }
- } else {
- _kickBenProgress = false;
- }
-
- // switch weapon
- if ((buttons & 2) && (_currEnemy != EN_TORQUE)) {
- if (_weaponBenJustSwitched)
- return;
-
- if (!actor0StateFlags1(_actor[0].act[2].state))
- return;
-
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_WRENCH:
- _actor[0].act[2].state = 35;
- smlayer_setActorFacing(0, 2, 24, 180);
- break;
- case INV_BOOT:
- case INV_HAND:
- case INV_DUST:
- _actor[0].act[2].state = 0;
- switchBenWeapon();
- }
-
- _weaponBenJustSwitched = true;
- } else {
- _weaponBenJustSwitched = false;
- }
-}
-
-void Insane::switchBenWeapon(void) {
- do {
- _actor[0].weapon++;
- if (_actor[0].weapon > 7)
- _actor[0].weapon = INV_CHAIN;
-
- } while (!_actor[0].inventory[_actor[0].weapon]);
-
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- smlayer_setActorCostume(0, 2, readArray(20));
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 34;
- break;
- case INV_CHAINSAW:
- smlayer_setActorCostume(0, 2, readArray(24));
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 34;
- break;
- case INV_MACE:
- smlayer_setActorCostume(0, 2, readArray(23));
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 34;
- break;
- case INV_2X4:
- if (_currEnemy == EN_CAVEFISH)
- smlayer_setActorCostume(0, 2, readArray(38));
- else
- smlayer_setActorCostume(0, 2, readArray(19));
-
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 34;
- break;
- case INV_WRENCH:
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- smlayer_setActorCostume(0, 2, readArray(24));
- else
- smlayer_setActorCostume(0, 2, readArray(25));
- smlayer_setActorFacing(0, 2, 18, 180);
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 34;
- break;
- case INV_BOOT:
- case INV_HAND:
- case INV_DUST:
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- smlayer_setActorCostume(0, 2, readArray(11));
- else
- smlayer_setActorCostume(0, 2, readArray(12));
- _actor[0].weaponClass = 2;
- _actor[0].act[2].state = 1;
- break;
- default:
- break;
- }
-}
-
-int32 Insane::setBenState(void) {
- _actor[0].act[2].animTilt = -1000;
-
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 63;
- break;
- case INV_CHAINSAW:
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 64;
- break;
- case INV_MACE:
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 65;
- break;
- case INV_2X4:
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 66;
- break;
- case INV_WRENCH:
- _actor[0].weaponClass = 1;
- _actor[0].act[2].state = 62;
- break;
- case INV_BOOT:
- case INV_HAND:
- case INV_DUST:
- _actor[0].weaponClass = 2;
- _actor[0].act[2].state = 1;
- break;
- default:
- break;
- }
- return _actor[0].act[2].state;
-}
-
-void Insane::ouchSoundBen(void) {
- _actor[0].act[3].state = 52;
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- smlayer_startVoice(54);
- return;
- }
-
- switch (_vm->_rnd.getRandomNumber(3)) {
- case 0:
- smlayer_startVoice(315);
- break;
- case 1:
- smlayer_startVoice(316);
- break;
- case 2:
- smlayer_startVoice(317);
- break;
- case 3:
- smlayer_startVoice(98);
- break;
- }
-}
-
-}
diff --git a/scumm/insane/insane_enemy.cpp b/scumm/insane/insane_enemy.cpp
deleted file mode 100644
index d67fc7ae09..0000000000
--- a/scumm/insane/insane_enemy.cpp
+++ /dev/null
@@ -1,2813 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/engine.h"
-
-#include "scumm/insane/insane.h"
-
-namespace Scumm {
-
-int32 Insane::enemyInitializer(int num, int32 actor1, int32 actor2, int32 probability) {
- switch (num) {
- case EN_ROTT1:
- return enemy0initializer(actor1, actor2, probability);
- break;
- case EN_ROTT2:
- return enemy1initializer(actor1, actor2, probability);
- break;
- case EN_ROTT3:
- return enemy2initializer(actor1, actor2, probability);
- break;
- case EN_VULTF1:
- return enemy3initializer(actor1, actor2, probability);
- break;
- case EN_VULTM1:
- return enemy4initializer(actor1, actor2, probability);
- break;
- case EN_VULTF2:
- return enemy5initializer(actor1, actor2, probability);
- break;
- case EN_VULTM2:
- return enemy6initializer(actor1, actor2, probability);
- break;
- case EN_CAVEFISH:
- return enemy7initializer(actor1, actor2, probability);
- break;
- case EN_TORQUE:
- return enemy8initializer(actor1, actor2, probability);
- break;
- case -1:
- // nothing
- break;
- }
-
- return 0;
-}
-
-
-int32 Insane::enemyHandler(int num, int32 actor1, int32 actor2, int32 probability) {
- switch (num) {
- case EN_ROTT1:
- return enemy0handler(actor1, actor2, probability);
- break;
- case EN_ROTT2:
- return enemy1handler(actor1, actor2, probability);
- break;
- case EN_ROTT3:
- return enemy2handler(actor1, actor2, probability);
- break;
- case EN_VULTF1:
- return enemy3handler(actor1, actor2, probability);
- break;
- case EN_VULTM1:
- return enemy4handler(actor1, actor2, probability);
- break;
- case EN_VULTF2:
- return enemy5handler(actor1, actor2, probability);
- break;
- case EN_VULTM2:
- return enemy6handler(actor1, actor2, probability);
- break;
- case EN_CAVEFISH:
- return enemy7handler(actor1, actor2, probability);
- break;
- case EN_TORQUE:
- return enemy8handler(actor1, actor2, probability);
- break;
- case EN_BEN:
- return enemyBenHandler(actor1, actor2, probability);
- break;
- case -1:
- // nothing
- break;
- }
- return 0;
-}
-
-int32 Insane::enemy0handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act2damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act2damage = _actor[actor2].damage; // ebp
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // edi
-
- if (!_actor[actor1].defunct) {
- if (_enHdlVar[EN_ROTT1][1] > _enHdlVar[EN_ROTT1][2]) {
- if (act1damage - act2damage >= 30) {
- if (_vm->_rnd.getRandomNumber(probability - 1) != 1)
- _enHdlVar[EN_ROTT1][0] = 0;
- else
- _enHdlVar[EN_ROTT1][0] = 1;
- }
- _enHdlVar[EN_ROTT1][1] = 0;
- _enHdlVar[EN_ROTT1][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1);
- }
-
- dist = ABS(act1x - act2x);
-
- if (_enHdlVar[EN_ROTT1][3] > _enHdlVar[EN_ROTT1][4]) {
- if (_enHdlVar[EN_ROTT1][0] == 1) {
- if (weaponMaxRange(actor1) < dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- if (weaponMinRange(actor1) > dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- } else {
- if (weaponMaxRange(actor2) >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- _enHdlVar[EN_ROTT1][3] = 0;
- _enHdlVar[EN_ROTT1][4] = _vm->_rnd.getRandomNumber(probability - 1);
- }
-
- if (_enHdlVar[EN_ROTT1][5] > _enHdlVar[EN_ROTT1][6]) {
- if (weaponMaxRange(actor2) + 40 >= dist) {
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- }
- if (_actor[actor2].kicking) {
- if (weaponMaxRange(actor2) >= dist)
- if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1)
- retval = 1;
- }
- _enHdlVar[EN_ROTT1][5] = 0;
- _enHdlVar[EN_ROTT1][6] = _vm->_rnd.getRandomNumber(probability - 1) / 2;
- }
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- if ((_actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- if (_actor[actor1].act[3].state == 54) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 3:
- if (!_enemyState[EN_ROTT1][6]) {
- _enemyState[EN_ROTT1][6] = 1;
- prepareScenePropScene(54, 0, 0);
- }
- break;
- case 8:
- if (!_enemyState[EN_ROTT1][4]) {
- _enemyState[EN_ROTT1][4] = 1;
- prepareScenePropScene(52, 0, 0);
- }
- break;
- }
- } else {
- switch(_vm->_rnd.getRandomNumber(14)) {
- case 2:
- if (!_enemyState[EN_ROTT1][2]) {
- _enemyState[EN_ROTT1][2] = 1;
- prepareScenePropScene(50, 0, 0);
- }
- break;
- case 4:
- if (!_enemyState[EN_ROTT1][3]) {
- _enemyState[EN_ROTT1][3] = 1;
- prepareScenePropScene(51, 0, 0);
- }
- break;
- case 6:
- if (!_enemyState[EN_ROTT1][7]) {
- _enemyState[EN_ROTT1][7] = 1;
- if (_enemy[EN_ROTT1].occurences)
- prepareScenePropScene(55, 0, 0);
- }
- break;
- case 9:
- if (!_enemyState[EN_ROTT1][5]) {
- _enemyState[EN_ROTT1][5] = 1;
- prepareScenePropScene(53, 0, 0);
- }
- break;
- case 11:
- if (!_enemyState[EN_ROTT1][8]) {
- _enemyState[EN_ROTT1][8] = 1;
- prepareScenePropScene(56, 0, 0);
- }
- break;
- default:
- break;
- }
- }
- }
- _enHdlVar[EN_ROTT1][1]++;
- _enHdlVar[EN_ROTT1][3]++;
- _enHdlVar[EN_ROTT1][5]++;
- }
-
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- }
-
- return retval;
-}
-
-int32 Insane::enemy0initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 9; i++)
- _enemyState[EN_ROTT1][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_ROTT1][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy1handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act2damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act2damage = _actor[actor2].damage; // ebp
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // edi
-
- if (!_actor[actor1].defunct) {
- if (_enHdlVar[EN_ROTT2][1] > _enHdlVar[EN_ROTT2][2]) {
- if (act1damage - act2damage >= 30) {
- if (_vm->_rnd.getRandomNumber(probability - 1) != 1)
- _enHdlVar[EN_ROTT2][0] = 0;
- else
- _enHdlVar[EN_ROTT2][0] = 1;
- }
- _enHdlVar[EN_ROTT2][1] = 0;
- _enHdlVar[EN_ROTT2][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1);
- }
-
- dist = ABS(act1x - act2x);
-
- if (_enHdlVar[EN_ROTT2][3] > _enHdlVar[EN_ROTT2][4]) {
- if (_enHdlVar[EN_ROTT2][0] == 1) {
- if (weaponMaxRange(actor1) < dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- if (weaponMinRange(actor1) > dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- } else {
- if (weaponMaxRange(actor2) >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- _enHdlVar[EN_ROTT2][3] = 0;
- _enHdlVar[EN_ROTT2][4] = _vm->_rnd.getRandomNumber(probability - 1);
- }
-
- if (_enHdlVar[EN_ROTT2][5] > _enHdlVar[EN_ROTT2][6]) {
- if (weaponMaxRange(actor2) + 40 >= dist) {
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- }
- if (_actor[actor2].kicking) {
- if (weaponMaxRange(actor2) <= dist)
- if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1)
- retval = 1;
- }
- _enHdlVar[EN_ROTT1][5] = 0;
- _enHdlVar[EN_ROTT1][6] = _vm->_rnd.getRandomNumber(probability - 1) / 2;
- }
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- if ((_actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- if (_actor[actor1].act[3].state == 54) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 3:
- if (!_enemyState[EN_ROTT2][6]) {
- _enemyState[EN_ROTT2][6] = 1;
- prepareScenePropScene(38, 0, 0);
- }
- break;
- case 8:
- if (!_enemyState[EN_ROTT2][5]) {
- _enemyState[EN_ROTT2][5] = 1;
- prepareScenePropScene(37, 0, 0);
- }
- break;
- }
- } else {
- switch(_vm->_rnd.getRandomNumber(14)) {
- case 2:
- if (!_enemyState[EN_ROTT2][2]) {
- _enemyState[EN_ROTT2][2] = 1;
- prepareScenePropScene(34, 0, 0);
- }
- break;
- case 11:
- if (!_enemyState[EN_ROTT1][7]) {
- _enemyState[EN_ROTT1][7] = 1;
- prepareScenePropScene(39, 0, 0);
- }
- break;
- default:
- break;
- }
- }
- }
- _enHdlVar[EN_ROTT2][1]++;
- _enHdlVar[EN_ROTT2][3]++;
- _enHdlVar[EN_ROTT2][5]++;
- }
-
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- }
-
- return retval;
-}
-
-int32 Insane::enemy1initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 9; i++)
- _enemyState[EN_ROTT2][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_ROTT2][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy2handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act2damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act2damage = _actor[actor2].damage; // ebp
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // edi
-
- if (!_actor[actor1].defunct) {
- if (_enHdlVar[EN_ROTT3][1] > _enHdlVar[EN_ROTT3][2]) {
- if (act1damage - act2damage >= 30) {
- if (_vm->_rnd.getRandomNumber(probability - 1) != 1)
- _enHdlVar[EN_ROTT3][0] = 0;
- else
- _enHdlVar[EN_ROTT3][0] = 1;
- }
- _enHdlVar[EN_ROTT3][1] = 0;
- _enHdlVar[EN_ROTT3][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1);
- }
-
- dist = ABS(act1x - act2x);
-
- if (_enHdlVar[EN_ROTT3][3] > _enHdlVar[EN_ROTT3][4]) {
- if (_enHdlVar[EN_ROTT3][0] == 1) {
- if (weaponMaxRange(actor1) < dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- if (weaponMinRange(actor1) > dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- } else {
- if (weaponMaxRange(actor2) >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- _enHdlVar[EN_ROTT3][3] = 0;
- _enHdlVar[EN_ROTT3][4] = _vm->_rnd.getRandomNumber(probability - 1);
- }
- if (_enHdlVar[EN_ROTT3][5] > _enHdlVar[EN_ROTT3][6]) {
- if (weaponMaxRange(actor2) + 40 >= dist) {
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- }
- if (_actor[actor2].kicking) {
- if (weaponMaxRange(actor2) >= dist)
- if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1)
- retval = 1;
- }
- _enHdlVar[EN_ROTT3][5] = 0;
- _enHdlVar[EN_ROTT3][6] = _vm->_rnd.getRandomNumber(probability - 1) / 2;
- }
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- if ((_actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- if (_actor[actor1].act[3].state == 54) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 3:
- if (!_enemyState[EN_ROTT3][1]) {
- _enemyState[EN_ROTT3][1] = 1;
- prepareScenePropScene(26, 0, 0);
- }
- break;
- case 5:
- if (!_enemyState[EN_ROTT3][3]) {
- _enemyState[EN_ROTT3][3] = 1;
- prepareScenePropScene(28, 0, 0);
- }
- break;
- case 8:
- if (!_enemyState[EN_ROTT3][2]) {
- _enemyState[EN_ROTT3][2] = 1;
- prepareScenePropScene(27, 0, 0);
- }
- break;
- }
- } else {
- if (_actor[actor1].kicking) {
- if (_vm->_rnd.getRandomNumber(9) == 9) {
- if (!_enemyState[EN_ROTT3][6]) {
- _enemyState[EN_ROTT3][6] = 1;
- prepareScenePropScene(31, 0, 0);
- }
- }
- } else {
- if (_vm->_rnd.getRandomNumber(14) == 7) {
- if (!_enemyState[EN_ROTT3][5]) {
- _enemyState[EN_ROTT3][5] = 1;
- prepareScenePropScene(30, 0, 0);
- }
- }
- }
- }
- }
- _enHdlVar[EN_ROTT3][1]++;
- _enHdlVar[EN_ROTT3][3]++;
- _enHdlVar[EN_ROTT3][5]++;
- }
-
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- }
-
- return retval;
-}
-
-int32 Insane::enemy2initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 7; i++)
- _enemyState[EN_ROTT3][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_ROTT3][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy3handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act2damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act2damage = _actor[actor2].damage; // ebp
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // edi
-
- if (!_actor[actor1].defunct) {
- if (_enHdlVar[EN_VULTF1][1] > _enHdlVar[EN_VULTF1][2]) {
- if ((act1damage - act2damage >= 30) && (_vm->_rnd.getRandomNumber(probability - 1) != 1))
- _enHdlVar[EN_VULTF1][0] = 0;
- else
- _enHdlVar[EN_VULTF1][0] = 1;
-
- _enHdlVar[EN_VULTF1][1] = 0;
- _enHdlVar[EN_VULTF1][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1);
- }
-
- dist = ABS(act1x - act2x);
-
- if (_enHdlVar[EN_VULTF1][3] > _enHdlVar[EN_VULTF1][4]) {
- if (_enHdlVar[EN_VULTF1][0] == 1) {
- if (weaponMaxRange(actor1) < dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- if (weaponMinRange(actor1) > dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- } else {
- if (weaponMaxRange(actor2) >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- _enHdlVar[EN_VULTF1][3] = 0;
- _enHdlVar[EN_VULTF1][4] = _vm->_rnd.getRandomNumber(probability - 1);
- }
-
- if (_enHdlVar[EN_VULTF1][5] > _enHdlVar[EN_VULTF1][6]) {
- if (_enHdlVar[EN_VULTF1][0] == 1) {
- if (weaponMaxRange(actor2) + 40 >= dist)
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- } else {
- if (_actor[actor1].kicking)
- if (weaponMaxRange(actor2) >= dist)
- if (_vm->_rnd.getRandomNumber(probability - 1) <= 1)
- retval = 1;
- }
- _enHdlVar[EN_VULTF1][5] = 0;
- _enHdlVar[EN_VULTF1][6] = _vm->_rnd.getRandomNumber(probability - 1) / 2;
- }
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- if ((_actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- _enHdlVar[EN_VULTF1][8] = _vm->_rnd.getRandomNumber(25);
- if (_enHdlVar[EN_VULTF1][8] != _enHdlVar[EN_VULTF1][7]) {
- switch (_enHdlVar[EN_VULTF1][8]) {
- case 0:
- if (!_enemyState[EN_VULTF1][4]) {
- _enemyState[EN_VULTF1][4] = 1;
- prepareScenePropScene(3, 0, 0);
- }
- break;
- case 1:
- if (!_enemyState[EN_VULTF1][1]) {
- _enemyState[EN_VULTF1][1] = 1;
- prepareScenePropScene(4, 0, 0);
- }
- break;
- case 2:
- if (!_enemyState[EN_VULTF1][2]) {
- _enemyState[EN_VULTF1][2] = 1;
- prepareScenePropScene(5, 0, 0);
- }
- break;
- case 3:
- if (!_enemyState[EN_VULTF1][3]) {
- _enemyState[EN_VULTF1][3] = 1;
- prepareScenePropScene(6, 0, 0);
- }
- break;
- case 4:
- if (!_enemyState[EN_VULTF1][4]) {
- _enemyState[EN_VULTF1][4] = 1;
- prepareScenePropScene(7, 0, 0);
- }
- break;
- case 5:
- if (!_enemyState[EN_VULTF1][5]) {
- _enemyState[EN_VULTF1][5] = 1;
- prepareScenePropScene(8, 0, 0);
- }
- break;
- }
- _enHdlVar[EN_VULTF1][7] = _enHdlVar[EN_VULTF1][8];
- }
-
- }
- _enHdlVar[EN_VULTF1][1]++;
- _enHdlVar[EN_VULTF1][3]++;
- _enHdlVar[EN_VULTF1][5]++;
- } else {
- _actor[actor1].cursorX = 0;
- }
-
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- }
-
- return retval;
-}
-
-int32 Insane::enemy3initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 6; i++)
- _enemyState[EN_VULTF1][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_VULTF1][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy4handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act2damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act2damage = _actor[actor2].damage; // ebp
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // edi
-
- if (!_actor[actor1].defunct) {
- if (_enHdlVar[EN_VULTM1][1] > _enHdlVar[EN_VULTM1][2]) {
- if (act1damage - act2damage >= 30) {
- if (_vm->_rnd.getRandomNumber(probability - 1) != 1)
- _enHdlVar[EN_VULTM1][0] = 0;
- else
- _enHdlVar[EN_VULTM1][0] = 1;
- }
- _enHdlVar[EN_VULTM1][1] = 0;
- _enHdlVar[EN_VULTM1][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1);
- }
-
- dist = ABS(act1x - act2x);
-
- if (_enHdlVar[EN_VULTM1][3] > _enHdlVar[EN_VULTM1][4]) {
- if (_enHdlVar[EN_VULTM1][0] == 1) {
- if (weaponMaxRange(actor1) < dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- if (weaponMinRange(actor1) > dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- } else {
- if (weaponMaxRange(actor2) >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
- _enHdlVar[EN_VULTM1][3] = 0;
- _enHdlVar[EN_VULTM1][4] = _vm->_rnd.getRandomNumber(probability - 1);
- }
- if (_enHdlVar[EN_VULTM1][5] > _enHdlVar[EN_VULTM1][6]) {
- if (weaponMaxRange(actor2) + 40 >= dist) {
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- }
- if (_actor[actor2].kicking) {
- if (weaponMaxRange(actor2) >= dist) // that's weird but original is >=
- if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1)
- retval = 1;
- }
- _enHdlVar[EN_VULTM1][5] = 0;
- _enHdlVar[EN_VULTM1][6] = _vm->_rnd.getRandomNumber(probability - 1) / 2;
- }
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- if ((_actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- if (_actor[actor1].act[3].state == 54) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 4:
- if (!_enemyState[EN_VULTM1][7]) {
- _enemyState[EN_VULTM1][7] = 1;
- prepareScenePropScene(46, 0, 0);
- }
- break;
- case 8:
- if (!_enemyState[EN_VULTM1][8]) {
- _enemyState[EN_VULTM1][8] = 1;
- prepareScenePropScene(47, 0, 0);
- }
- break;
- }
- } else {
- if (_actor[actor1].kicking) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 3:
- prepareScenePropScene(44, 0, 0);
- break;
- case 9:
- prepareScenePropScene(45, 0, 0);
- break;
- }
- } else {
- if (weaponMaxRange(actor2) <= dist) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 3:
- if (!_enemyState[EN_VULTM1][3]) {
- _enemyState[EN_VULTM1][3] = 1;
- prepareScenePropScene(42, 0, 0);
- }
- break;
- case 9:
- if (!_enemyState[EN_VULTM1][4]) {
- _enemyState[EN_VULTM1][4] = 1;
- prepareScenePropScene(43, 0, 0);
- }
- break;
- }
- } else {
- switch (_vm->_rnd.getRandomNumber(14)) {
- case 7:
- if (!_enemyState[EN_VULTM1][9]) {
- _enemyState[EN_VULTM1][9] = 1;
- prepareScenePropScene(48, 0, 0);
- }
- break;
- case 11:
- if (!_enemyState[EN_VULTM1][1]) {
- _enemyState[EN_VULTM1][1] = 1;
- prepareScenePropScene(40, 0, 0);
- }
- break;
- }
- }
- }
- }
- }
- _enHdlVar[EN_VULTM1][1]++;
- _enHdlVar[EN_VULTM1][3]++;
- _enHdlVar[EN_VULTM1][5]++;
- }
-
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- }
-
- return retval;
-}
-
-int32 Insane::enemy4initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 10; i++)
- _enemyState[EN_VULTM1][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_VULTM1][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy5handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // ebp
-
- dist = ABS(act1x - act2x);
-
- if (weaponMaxRange(actor1) >= dist) {
- if (!_enHdlVar[EN_VULTF2][2])
- _enHdlVar[EN_VULTF2][3]++;
- _enHdlVar[EN_VULTF2][1] = 1;
- } else {
- _enHdlVar[EN_VULTF2][1] = 0;
- }
-
- if (!_actor[actor1].defunct) {
- if (_enHdlVar[EN_VULTF2][3] >= 2 || act1damage) {
- _actor[actor1].damage = 10;
-
- if (weaponMaxRange(actor1) <= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- _actor[actor1].cursorX = 0;
- }
-
- if (weaponMaxRange(actor1) + 20 >= dist)
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- } else {
- if (weaponMaxRange(actor2) >= dist && _actor[actor2].weapon == INV_CHAINSAW)
- if (!_actor[actor2].kicking) {
- if (_vm->_rnd.getRandomNumber(probability - 1) == 1)
- retval = 1;
- } else {
- retval = 1;
- }
- _actor[actor1].cursorX = 0;
- if (_enHdlVar[EN_VULTF2][0] >= 100)
- _enHdlVar[EN_VULTF2][3] = 3;
- }
-
- if ((_actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- if (_actor[actor1].act[3].state == 54)
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 4:
- if (!_enemyState[EN_VULTF2][6]) {
- _enemyState[EN_VULTF2][6] = 1;
- prepareScenePropScene(15, 0, 0);
- }
- break;
- case 8:
- if (!_enemyState[EN_VULTF2][3]) {
- _enemyState[EN_VULTF2][3] = 1;
- prepareScenePropScene(12, 0, 0);
- }
- break;
- }
- else {
- if (_actor[actor1].kicking) {
- switch (_vm->_rnd.getRandomNumber(9)) {
- case 2:
- if (!_enemyState[EN_VULTF2][8]) {
- _enemyState[EN_VULTF2][8] = 1;
- prepareScenePropScene(17, 0, 0);
- }
- break;
- case 5:
- prepareScenePropScene(11, 0, 0);
- _enemyState[EN_VULTF2][2] = 1;
- break;
- case 9:
- _enemyState[EN_VULTF2][1] = 1;
- prepareScenePropScene(10, 0, 0);
- break;
- }
- } else {
- switch (_vm->_rnd.getRandomNumber(14)) {
- case 3:
- if (!_enemyState[EN_VULTF2][4]) {
- _enemyState[EN_VULTF2][4] = 1;
- prepareScenePropScene(13, 0, 0);
- }
- break;
- case 11:
- if (!_enemyState[EN_VULTF2][5]) {
- _enemyState[EN_VULTF2][5] = 1;
- prepareScenePropScene(14, 0, 0);
- }
- break;
- }
- }
- }
- }
- }
-
- if (_actor[actor1].defunct)
- _actor[actor1].cursorX = 0;
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- _enHdlVar[EN_VULTF2][2] = _enHdlVar[EN_VULTF2][1];
- _enHdlVar[EN_VULTF2][0]++;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- _actor[1].act[2].state = 113;
- }
-
- return retval;
-}
-
-int32 Insane::enemy5initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 9; i++)
- _enemyState[EN_VULTF2][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_VULTF2][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy6handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act2damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx //ebx
- act2damage = _actor[actor2].damage; // ebp // edi
- act1x = _actor[actor1].x; // esi
- act2x = _actor[actor2].x; // edi
-
- if (_actor[actor2].weapon == INV_CHAINSAW)
- retval = 1;
-
- dist = ABS(act1x - act2x);
-
- if (_actor[actor1].defunct) {
- /* scenePropIdx[18] */
- if (_currScenePropIdx == 50 && _currScenePropSubIdx == 3)
- retval = 1;
- } else {
- if (act1damage > 0 || _enHdlVar[EN_VULTM2][0] > 20) {
- _actor[actor1].damage = 10;
- if (!_enHdlVar[EN_VULTM2][1] && !_actor[actor1].lost) {
- if (!_actor[actor1].field_54) {
- switch (_vm->_rnd.getRandomNumber(3)) {
- case 0:
- if (!_enemyState[EN_VULTM2][1]) {
- _enemyState[EN_VULTM2][1] = 1;
- prepareScenePropScene(19, 0, 0);
- }
- break;
- case 1:
- if (!_enemyState[EN_VULTM2][2]) {
- _enemyState[EN_VULTM2][2] = 1;
- prepareScenePropScene(20, 0, 0);
- }
- break;
- case 2:
- if (!_enemyState[EN_VULTM2][3]) {
- _enemyState[EN_VULTM2][3] = 1;
- prepareScenePropScene(21, 0, 0);
- }
- break;
- case 3:
- if (!_enemyState[EN_VULTM2][4]) {
- _enemyState[EN_VULTM2][4] = 1;
- prepareScenePropScene(22, 0, 0);
- }
- break;
- }
- _enHdlVar[EN_VULTM2][1] = 1;
- goto _label1;
- }
- } else {
- if (_actor[actor1].field_54 == 0 &&
- _actor[actor1].lost == 0) {
- retval = 1;
- _enHdlVar[EN_VULTM2][0] = 0;
- }
- }
- } else {
- if (weaponMaxRange(actor2) >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- }
-
- if ((_enHdlVar[EN_VULTM2][1] == 0) &&
- ( _actor[actor1].field_54 == 0) &&
- (_actor[actor2].lost == 0) &&
- (_actor[actor1].lost == 0)) {
- switch (_vm->_rnd.getRandomNumber(14)) {
- case 2:
- if (!_enemyState[EN_VULTM2][5]) {
- _enemyState[EN_VULTM2][5] = 1;
- prepareScenePropScene(23, 0, 0);
- }
- break;
- case 7:
- if (!_enemyState[EN_VULTF1][6]) {
- _enemyState[EN_VULTF1][6] = 1;
- prepareScenePropScene(24, 0, 0);
- }
- break;
- }
- }
- }
-
- _label1:
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 219)
- _actor[actor1].cursorX = 320;
- else if (act1x > 280)
- _actor[actor1].cursorX = -160;
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[0].act[2].state = 97;
- smlayer_setActorFacing(0, 2, 20, 180);
- _actor[0].act[2].room = 0;
- _actor[0].act[1].room = 0;
- _actor[0].act[0].room = 0;
- smlayer_setActorLayer(1, 2, 25);
- smlayer_setActorCostume(1, 2, readArray(45));
- smlayer_setActorFacing(1, 2, 6, 180);
- _actor[1].act[2].state = 97;
- _actor[1].act[2].room = 1;
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- }
-
- if (_actor[actor1].lost)
- retval = 0;
-
- return retval;
-}
-
-int32 Insane::enemy6initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 7; i++)
- _enemyState[EN_VULTM2][i] = 0;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_VULTM2][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy7handler(int32 actor1, int32 actor2, int32 probability) {
- int32 act1damage, act1x, act2x, retval;
- int32 dist;
-
- retval = 0;
- act1damage = _actor[actor1].damage; // ebx
- act1x = _actor[actor1].x; // ebp, esi
- act2x = _actor[actor2].x; // edi
-
- dist = ABS(act1x - act2x);
-
- if (_enHdlVar[EN_CAVEFISH][1] >= 600) {
- _enHdlVar[EN_CAVEFISH][2] = 1;
- _enHdlVar[EN_CAVEFISH][1] = 0;
- } else {
- if (!_enHdlVar[EN_CAVEFISH][2]) {
- if (weaponMaxRange(actor2) + 30 >= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = 101;
- else
- _actor[actor1].cursorX = -101;
- } else {
- _actor[actor1].cursorX = 0;
- }
- goto _labelA;
- }
- }
-
- if (weaponMaxRange(actor1) <= dist) {
- if (act2x < act1x)
- _actor[actor1].cursorX = -101;
- else
- _actor[actor1].cursorX = 101;
- } else {
- _actor[actor1].cursorX = 0;
- }
-
- _labelA:
- if (act1x > 310)
- _actor[actor1].cursorX = -320;
- else if (act1x < 10)
- _actor[actor1].cursorX = 320;
-
- if (dist <= 95)
- retval = 1;
-
- if (_actor[actor1].weapon == -1)
- retval = 2;
-
- _enHdlVar[EN_CAVEFISH][1]++;
- _enHdlVar[EN_CAVEFISH][0] = act1damage;
-
- // Shift+V cheat to win the battle
- if (_vm->getKeyState(0x56) && !_beenCheated &&
- !_actor[0].lost && !_actor[1].lost) {
- _beenCheated = 1;
- _actor[1].damage = _actor[1].maxdamage + 10;
- _actor[1].act[2].state = 102;
- }
-
- return retval;
-}
-
-int32 Insane::enemy7initializer(int32 actor1, int32 actor2, int32 probability) {
- int i;
-
- for (i = 0; i < 9; i++)
- _enHdlVar[EN_CAVEFISH][i] = 0;
-
- _beenCheated = 0;
-
- return 1;
-}
-
-int32 Insane::enemy8handler(int32 actor1, int32 actor2, int32 probability) {
- _actor[actor1].cursorX = 0;
- return 0;
-}
-
-int32 Insane::enemy8initializer(int32 actor1, int32 actor2, int32 probability) {
- return 1;
-}
-
-
-void Insane::ouchSoundEnemy(void) {
- int32 tmp;
-
- _actor[1].act[3].state = 52;
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- smlayer_startVoice(55);
- return;
- }
-
- switch (_currEnemy) {
- case EN_VULTF1:
- if (_actor[0].weapon == INV_DUST) {
- smlayer_startVoice(287);
- } else {
- if (_vm->_rnd.getRandomNumber(1)) {
- smlayer_startVoice(279);
- } else {
- smlayer_startVoice(280);
- }
- }
- break;
- case EN_VULTF2:
- smlayer_startVoice(271);
- break;
- case EN_VULTM1:
- smlayer_startVoice(162);
- break;
- case EN_ROTT1:
- tmp = _vm->_rnd.getRandomNumber(2);
-
- if (!tmp) {
- smlayer_startVoice(216);
- } else if (tmp == 1) {
- smlayer_startVoice(217);
- } else {
- smlayer_startVoice(218);
- }
- break;
- case EN_ROTT2:
- tmp = _vm->_rnd.getRandomNumber(2);
-
- if (!tmp) {
- smlayer_startVoice(243);
- } else if (tmp == 1) {
- smlayer_startVoice(244);
- } else {
- smlayer_startVoice(245);
- }
- break;
- case EN_VULTM2:
- smlayer_startVoice(180);
- break;
- default:
- smlayer_startVoice(99);
- break;
- }
-}
-
-bool Insane::loadScenePropSounds(int32 scenePropNum) {
- int32 num = 0;
- int32 res = 1;
-
- if (_sceneProp[scenePropNum + num].index != 1) {
- while (num < 12) {
- res &= smlayer_loadSound(_sceneProp[scenePropNum + num].sound, 0, 2);
- num = _sceneProp[scenePropNum + num].index;
-
- if (!num)
- break;
- }
- }
-
- return res != 0;
-}
-
-void Insane::turnEnemy(bool battle) {
- int buttons;
-
- if (_actor[1].damage < _actor[1].maxdamage) {
- _actor[1].lost = false;
- } else {
- if (!_actor[1].lost && !_actor[1].lost) {
- _actor[1].lost = true;
- _actor[1].act[2].state = 36;
- _actor[1].act[1].state = 36;
- _actor[1].act[0].state = 36;
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- }
- }
-
- buttons = 0;
-
- if (_actor[1].lost == 0)
- if (battle)
- buttons = actionEnemy();
-
- debug(5, "11:%d 12:%d 13:%d 10:%d", _actor[1].act[1].state,
- _actor[1].act[2].state, _actor[1].act[3].state, _actor[1].act[0].state);
- actor11Reaction(buttons);
- actor12Reaction(buttons);
- actor13Reaction(buttons);
- actor10Reaction(buttons);
-}
-
-void Insane::actor11Reaction(int32 buttons) {
- int32 tmpx, tmpy;
-
- chooseEnemyWeaponAnim(buttons);
-
- switch(_actor[1].tilt) {
- case -3:
- if (_actor[1].act[1].state != 41 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 6);
- _actor[1].act[1].state = 41;
- }
-
- if (_actor[1].cursorX >= -100) {
- setEnemyAnimation(1, 7);
- _actor[1].act[1].state = 40;
- _actor[1].field_8 = 48;
- _actor[1].tilt = -2;
- }
-
- _actor[1].x += _actor[1].cursorX / 32;
- break;
- case -2:
- if (_actor[1].act[1].state != 40 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 7);
- _actor[1].act[1].state = 40;
- }
- if (_actor[1].field_8 == 48)
- _actor[1].tilt = -1;
- else
- _actor[1].tilt = -3;
-
- _actor[1].x += _actor[1].cursorX / 32;
- break;
- case -1:
- if (_actor[1].act[1].state != 39 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 8);
- _actor[1].act[1].state = 39;
- }
-
- if (_actor[1].field_8 == 48)
- _actor[1].tilt = 0;
- else
- _actor[1].tilt = -2;
-
- _actor[1].x += _actor[1].cursorX / 32;
- break;
- case 0:
- if (_actor[1].act[1].state != 1 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 9);
- _actor[1].act[1].state = 1;
- }
- _actor[1].field_8 = 1;
- if (_actor[1].cursorX < -100) {
- setEnemyAnimation(1, 8);
- _actor[1].act[1].state = 39;
- _actor[1].field_8 = 46;
- _actor[1].tilt = -1;
- } else {
- if (_actor[1].cursorX > 100) {
- setEnemyAnimation(1, 10);
- _actor[1].act[1].state = 55;
- _actor[1].field_8 = 49;
- _actor[1].tilt = 1;
- }
- }
- break;
- case 1:
- if (_actor[1].act[1].state != 55 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 10);
- _actor[1].act[1].state = 55;
- }
- if (_actor[1].field_8 == 51)
- _actor[1].tilt = 0;
- else
- _actor[1].tilt = 2;
-
- _actor[1].x += _actor[1].cursorX / 32;
- break;
- case 2:
- if (_actor[1].act[1].state != 56 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 11);
- _actor[1].act[1].state = 56;
- }
- if (_actor[1].field_8 == 51)
- _actor[1].tilt = 1;
- else
- _actor[1].tilt = 3;
-
- _actor[1].x += _actor[1].cursorX / 32;
- break;
- case 3:
- if (_actor[1].act[1].state != 57 || _actor[1].weaponClass != _actor[1].animWeaponClass) {
- setEnemyAnimation(1, 12);
- _actor[1].act[1].state = 57;
- }
-
- if (_actor[1].cursorX <= 100) {
- setEnemyAnimation(1, 11);
- _actor[1].act[1].state = 56;
- _actor[1].field_8 = 51;
- _actor[1].tilt = 2;
- }
-
- _actor[1].x += _actor[1].cursorX / 32;
- break;
- }
-
- tmpx = _actor[1].x;
- tmpy = _actor[1].y + _actor[1].y1;
-
- if (_actor[1].act[1].room)
- smlayer_putActor(1, 1, tmpx, tmpy, _smlayer_room2);
- else
- smlayer_putActor(1, 1, tmpx, tmpy, _smlayer_room);
-
- _actor[1].animWeaponClass = _actor[1].weaponClass;
-}
-
-void Insane::chooseEnemyWeaponAnim(int32 buttons) {
- // kick
- if ((buttons & 1) && (!_actor[0].lost)) {
- if (!_kickEnemyProgress && actor0StateFlags2(_actor[1].act[2].state + _actor[1].weapon * 119)) {
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- _actor[1].act[2].state = 10;
- break;
- case INV_CHAINSAW:
- _actor[1].act[2].state = 14;
- break;
- case INV_MACE:
- _actor[1].act[2].state = 18;
- break;
- case INV_2X4:
- _actor[1].act[2].state = 22;
- break;
- case INV_WRENCH:
- _actor[1].act[2].state = 26;
- break;
- case INV_BOOT:
- _actor[1].act[2].state = 93;
- break;
- case INV_HAND:
- _actor[1].act[2].state = 2;
- break;
- case INV_DUST:
- _actor[1].act[2].state = 89;
- break;
- default:
- break;
- }
- _kickEnemyProgress = true;
- }
- } else {
- _kickEnemyProgress = false;
- }
-
- // switch weapon
- if ((buttons & 2) && (_currEnemy != EN_TORQUE)) {
- if (_weaponEnemyJustSwitched || _actor[1].act[2].state == 35 ||
- _actor[1].act[2].state == 34)
- return;
-
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_WRENCH:
- _actor[1].act[2].state = 35;
- smlayer_setActorFacing(1, 2, 24, 180);
- break;
- case INV_BOOT:
- case INV_HAND:
- case INV_DUST:
- _actor[1].act[2].state = 0;
- switchEnemyWeapon();
- default:
- switchEnemyWeapon();
- }
-
- _weaponEnemyJustSwitched = true;
- } else {
- _weaponEnemyJustSwitched = false;
- }
-}
-
-void Insane::switchEnemyWeapon(void) {
- do {
- _actor[1].weapon++;
- if (_actor[1].weapon > 7)
- _actor[1].weapon = INV_CHAIN;
- } while (!_actor[1].inventory[_actor[1].weapon]);
-
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_WRENCH:
- smlayer_setActorCostume(1, 2, readArray(_enemy[_currEnemy].costume4));
- smlayer_setActorFacing(1, 2, 18, 180);
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 34;
- break;
- case INV_BOOT:
- _actor[1].weaponClass = 2;
- _actor[1].act[2].state = 1;
- break;
- case INV_HAND:
- smlayer_setActorCostume(1, 2, readArray(_enemy[_currEnemy].costume4));
- _actor[1].weaponClass = 2;
- _actor[1].act[2].state = 1;
- break;
- case INV_DUST:
- setEnemyState();
- break;
- default:
- break;
- }
-}
-
-void Insane::setEnemyState(void) {
- if (_actor[1].lost)
- return;
-
- _actor[1].act[2].animTilt = -1000;
-
- if (_currEnemy == EN_CAVEFISH) {
- _actor[1].weaponClass = 2;
- if (!_roadBumps)
- _actor[1].act[2].state = 98;
- else
- _actor[1].act[2].state = 99;
-
- return;
- }
-
- switch (_actor[1].weapon) {
- case INV_CHAIN:
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 63;
- break;
- case INV_CHAINSAW:
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 64;
- break;
- case INV_MACE:
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 65;
- break;
- case INV_2X4:
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 66;
- break;
- case INV_WRENCH:
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 62;
- break;
- case INV_BOOT:
- case INV_HAND:
- case INV_DUST:
- _actor[1].weaponClass = 2;
- _actor[1].act[2].state = 1;
- }
-}
-
-void Insane::actor12Reaction(int32 buttons) {
- int32 tmp, tmp2;
-
- switch(_actor[1].act[2].state) {
- case 1:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 2;
- _actor[1].kicking = false;
-
- switch (_actor[1].tilt) {
- case -3:
- if (_actor[1].act[2].animTilt != -3) {
- smlayer_setActorFacing(1, 2, 6, 180);
- _actor[1].act[2].animTilt = -3;
- }
- break;
- case -2:
- if (_actor[1].field_8 == 48)
- smlayer_setActorFacing(1, 2, 7, 180);
- _actor[1].act[2].animTilt = -2;
- break;
- case -1:
- if (_actor[1].field_8 == 46)
- smlayer_setActorFacing(1, 2, 8, 180);
- _actor[1].act[2].animTilt = -1;
- break;
- case 0:
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 9, 180);
- _actor[1].act[2].animTilt = 0;
- }
- break;
- case 1:
- if (_actor[1].field_8 == 49)
- smlayer_setActorFacing(1, 2, 10, 180);
- _actor[1].act[2].animTilt = 1;
- break;
- case 2:
- if (_actor[1].field_8 == 51)
- smlayer_setActorFacing(1, 2, 11, 180);
- _actor[1].act[2].animTilt = 2;
- break;
- case 3:
- if (_actor[1].act[2].animTilt != 3) {
- smlayer_setActorFacing(1, 2, 12, 180);
- _actor[1].act[2].animTilt = 3;
- }
- break;
- default:
- break;
- }
- _actor[1].act[2].tilt = 0;
- break;
- case 2:
- smlayer_setActorLayer(1, 2, 4);
- smlayer_setActorFacing(1, 2, 17, 180);
- _actor[1].kicking = true;
- _actor[1].weaponClass = 1;
- _actor[1].act[2].state = 3;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- smlayer_startSfx(63);
- break;
- case 3:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- if (_actor[1].act[2].frame >= 6) {
- tmp = calcBenDamage(1, 1);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- if (tmp == 1)
- smlayer_startSfx(50);
- } else if (tmp == 1)
- smlayer_startSfx(60);
- else if (tmp == 1000)
- smlayer_startSfx(62);
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 4;
- }
- _actor[1].kicking = true;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 4:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 2) {
- smlayer_setActorFacing(1, 2, 9, 180);
- _actor[1].act[2].state = 1;
- _actor[1].act[2].animTilt = -1000;
- _actor[1].weaponClass = 2;
- _actor[1].kicking = false;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 5:
- smlayer_setActorLayer(1, 2, 5);
- break;
- case 10:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- smlayer_setActorFacing(1, 2, 19, 180);
- _actor[1].act[2].state = 11;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- smlayer_startSfx(75);
- break;
- case 11:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 2) {
- if (weaponEnemyIsEffective()) {
- smlayer_setActorFacing(1, 2, 22, 180);
- _actor[1].act[2].state = 79;
- } else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 12;
- }
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 12:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 1) {
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_DUST:
- case INV_WRENCH:
- case INV_BOOT:
- tmp = calcBenDamage(1, 1);
- if (tmp == 1)
- smlayer_startSfx(73);
- if (tmp == 1000)
- smlayer_startSfx(74);
- break;
- case INV_HAND:
- if (calcBenDamage(1, 0))
- smlayer_startSfx(73);
- break;
- }
- smlayer_setActorFacing(1, 2, 21, 180);
- _actor[1].act[2].state = 13;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 13:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 3) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 63;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 14:
- smlayer_setActorLayer(1, 2, 8);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- smlayer_setActorFacing(1, 2, 19, 180);
- _actor[1].act[2].state = 15;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- smlayer_startSfx(78);
- break;
- case 15:
- smlayer_setActorLayer(1, 2, 8);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 5) {
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_WRENCH:
- if (weaponEnemyIsEffective()) {
- smlayer_setActorFacing(1, 2, 22, 180);
- _actor[1].act[2].state = 81;
- } else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 16;
- }
- break;
- default:
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 16;
- break;
- }
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 16:
- smlayer_setActorLayer(1, 2, 8);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 3) {
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_WRENCH:
- tmp = calcBenDamage(1, 1);
- if (tmp == 1)
- smlayer_startSfx(76);
- if (tmp == 1000)
- smlayer_startSfx(77);
- break;
- default:
- calcBenDamage(1, 0);
- break;
- }
- smlayer_setActorFacing(1, 2, 21,180);
- _actor[1].act[2].state = 17;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 17:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 1) {
- smlayer_setActorFacing(1, 2, 26, 180);
- _actor[1].act[2].state = 64;
- smlayer_stopSound(76);
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 18:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- smlayer_setActorFacing(1, 2, 19, 180);
- _actor[1].act[2].state = 19;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
- smlayer_startSfx(69);
- if (!_actor[1].field_54) {
- tmp = _vm->_rnd.getRandomNumber(4);
- if (tmp == 1)
- smlayer_startSfx(213);
- else if (tmp == 3)
- smlayer_startSfx(215);
- }
- } else {
- smlayer_startSfx(53);
- }
- break;
- case 19:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- if (_actor[1].act[2].frame >= 3) {
- switch (_actor[0].weapon) {
- case INV_CHAIN:
- if (_actor[0].kicking) {
- _actor[0].act[2].state = 108;
- _actor[1].act[2].state = 110;
- } else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 20;
- }
- break;
- case INV_CHAINSAW:
- if (_actor[0].kicking || _actor[0].field_44)
- _actor[1].act[2].state = 106;
- else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 20;
- }
- break;
- case INV_BOOT:
- case INV_DUST:
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 20;
- break;
- default:
- if (weaponEnemyIsEffective()) {
- smlayer_setActorFacing(1, 2, 22, 180);
- _actor[1].act[2].state = 77;
- } else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 20;
- }
- break;
- }
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 20:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 1) {
- switch (_actor[1].weapon) {
- case INV_CHAINSAW:
- case INV_MACE:
- case INV_2X4:
- case INV_BOOT:
- tmp = calcBenDamage(1, 1);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- if (tmp == 1)
- smlayer_startSfx(52);
- else if (tmp == 1000)
- smlayer_startSfx(56);
- } else {
- if (tmp == 1)
- smlayer_startSfx(67);
- else if (tmp == 1000)
- smlayer_startSfx(68);
- }
- break;
- default:
- calcBenDamage(1, 0);
- break;
- }
- smlayer_setActorFacing(1, 2, 21, 180);
- _actor[1].act[2].state = 21;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 21:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 5) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 65;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 22:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 0;
- _actor[1].kicking = true;
- smlayer_setActorFacing(1, 2, 19, 180);
- _actor[1].act[2].state = 23;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- smlayer_startSfx(81);
- break;
- case 23:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 0;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 3) {
- if (weaponEnemyIsEffective()) {
- smlayer_setActorFacing(1, 2, 22, 180);
- _actor[1].act[2].state = 83;
- } else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 24;
-
- if (!_actor[1].field_54)
- smlayer_startSfx(246);
- }
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 24:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 0;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 1) {
- tmp = calcBenDamage(1, 1);
-
- if (tmp == 1)
- smlayer_startSfx(79);
-
- if (tmp == 1000)
- smlayer_startSfx(80);
-
- smlayer_setActorFacing(1, 2, 21, 180);
- _actor[1].act[2].state = 25;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 25:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 0;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 3) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 66;
- _actor[1].weaponClass = 1;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 26:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- smlayer_setActorFacing(1, 2, 19, 180);
- _actor[1].act[2].state = 27;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- smlayer_startSfx(72);
- break;
- case 27:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 1) {
- if (weaponEnemyIsEffective()) {
- smlayer_setActorFacing(1, 2, 22, 180);
- _actor[1].act[2].state = 75;
- } else {
- smlayer_setActorFacing(1, 2, 20, 180);
- _actor[1].act[2].state = 28;
- break;
- }
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 28:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = true;
- if (_actor[1].act[2].frame >= 3) {
- tmp = calcBenDamage(1, 1);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- if (tmp == 1)
- smlayer_startSfx(57);
- } else if (tmp == 1)
- smlayer_startSfx(70);
- else if (tmp == 1000)
- smlayer_startSfx(71);
-
- smlayer_setActorFacing(1, 2, 21, 180);
- _actor[1].act[2].state = 29;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 29:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 6) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 62;
- _actor[1].kicking = false;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 34:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].kicking = false;
-
- if (!smlayer_actorNeedRedraw(1, 2)) {
- setEnemyState();
- _actor[1].act[2].tilt = 0;
- // for some reason there is no break at this
- // place, so tilt gets overriden on next line
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 35:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].kicking = false;
-
- if (!smlayer_actorNeedRedraw(1, 2)) {
- switchEnemyWeapon();
- _actor[1].act[2].tilt = 0;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 36:
- _actor[1].lost = true;
- _actor[1].field_54 = 1;
- _actor[1].cursorX = 0;
- _actor[1].kicking = false;
- smlayer_setActorCostume(1, 2, readArray(_enemy[_currEnemy].costumevar));
- smlayer_setActorFacing(1, 2, 6, 180);
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].act[2].state = 37;
-
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
- smlayer_startSfx(96);
- switch (_currEnemy) {
- case EN_ROTT1:
- smlayer_startVoice(212);
- break;
- case EN_ROTT2:
- smlayer_startVoice(259);
- break;
- case EN_ROTT3:
- smlayer_startVoice(232);
- break;
- case EN_VULTF1:
- smlayer_startVoice(281);
- break;
- case EN_VULTF2:
- smlayer_startVoice(276);
- break;
- }
- }
- break;
- case 37:
- _actor[1].cursorX = 0;
- _actor[1].kicking = false;
-
- if (_actor[1].act[2].frame < _enemy[_currEnemy].maxframe) {
- if (_actor[1].x >= 50 && _actor[1].x <= 270)
- break;
-
- if (_actor[1].act[2].frame < _enemy[_currEnemy].maxframe / 2)
- break;
- }
- if (_currSceneId == 21) {
- queueSceneSwitch(22, 0, "rottflip.san", 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- } else {
- queueSceneSwitch(11, 0, _enemy[_currEnemy].filename, 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- }
- break;
- case 38:
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].kicking = false;
-
- if (_actor[1].act[2].frame < _enemy[_currEnemy].maxframe + 20)
- break;
-
- _actor[1].act[2].frame = 0;
-
- if (_currSceneId == 21) {
- queueSceneSwitch(22, 0, "rottflip.san", 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- } else {
- queueSceneSwitch(11, 0, _enemy[_currEnemy].filename, 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- }
- break;
- case 63:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].animTilt = 0;
- }
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 64:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 26, 180);
- _actor[1].act[2].animTilt = 0;
- }
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 65:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].animTilt = 0;
- }
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 66:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].animTilt = 0;
- }
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 73:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = true;
- if (_actor[1].act[2].frame >= 2 && !_kickEnemyProgress) {
- smlayer_setActorFacing(1, 2, 19, 180);
- _actor[1].act[2].state = 74;
- }
-
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 74:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- if (_actor[1].act[2].frame >= 2) {
- smlayer_setActorFacing(1, 2, 9, 180);
- _actor[1].act[2].state = 1;
- _actor[1].weaponClass = 2;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 75:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = true;
- if (_actor[1].act[2].frame >= 4 && !_kickEnemyProgress) {
- smlayer_setActorFacing(1, 2, 23, 180);
- _actor[1].act[2].state = 76;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 76:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- if (_actor[1].act[2].frame >= 4) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 62;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 77:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = true;
- if (_actor[1].act[2].frame >= 1 && !_kickEnemyProgress) {
- smlayer_setActorFacing(1, 2, 23, 180);
- _actor[1].act[2].state = 78;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 78:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- if (_actor[1].act[2].frame >= 5) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 65;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 79:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = true;
- if (_actor[1].act[2].frame >= 1 && !_kickEnemyProgress) {
- smlayer_setActorFacing(1, 2, 23, 180);
- _actor[1].act[2].state = 80;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 80:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- if (_actor[1].act[2].frame >= 6) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 63;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 81:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = true;
- if (_actor[1].act[2].frame >= 2 && !_kickEnemyProgress) {
- smlayer_setActorFacing(1, 2, 23, 180);
- _actor[1].act[2].state = 82;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 82:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- if (_actor[1].act[2].frame >= 3) {
- smlayer_setActorFacing(1, 2, 26, 180);
- _actor[1].act[2].state = 64;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 83:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 0;
- _actor[1].kicking = false;
- _actor[1].field_44 = true;
- if (_actor[1].act[2].frame >= 2 && !_kickEnemyProgress) {
- smlayer_setActorFacing(1, 2, 23, 180);
- _actor[1].act[2].state = 84;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 84:
- smlayer_setActorLayer(1, 2, 6);
- _actor[1].weaponClass = 0;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- if (_actor[1].act[2].frame >= 5) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 66;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 89:
- smlayer_setActorLayer(1, 2, 26);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_roadBumps)
- smlayer_setActorFacing(1, 2, 13, 180);
- else
- smlayer_setActorFacing(1, 2, 12, 180);
-
- smlayer_startSfx(100);
- _actor[1].act[2].state = 90;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 90:
- smlayer_setActorLayer(1, 2, 26);
- _actor[1].weaponClass = 2;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 5)
- if (_actor[1].x - _actor[0].x <= 125)
- _actor[0].damage += 90;
-
- if (_actor[1].act[2].frame >= 12) {
- _actor[1].kicking = false;
- setEnemyState();
- smlayer_setActorLayer(1, 2, 5);
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 91:
- smlayer_setActorLayer(1, 2, 26);
- _actor[1].kicking = false;
- break;
- case 92:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].kicking = false;
- break;
- case 93:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- smlayer_setActorFacing(1, 2, 18, 180);
- _actor[1].act[2].state = 94;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 94:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 15) {
- smlayer_setActorCostume(1, 2, readArray(44));
- smlayer_setActorFacing(1, 2, 6, 180);
- _actor[1].act[2].state = 95;
- _actor[1].act[0].room = 0;
- _actor[1].act[1].room = 0;
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 95:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 19) {
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame1, 1300);
- _actor[1].act[2].state = 96;
- }
- break;
- case 97:
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].lost = true;
- if (_actor[1].act[2].frame >= 18) {
- writeArray(7, 1);
- _enemy[EN_VULTM2].isEmpty = 1;
- queueSceneSwitch(12, 0, "getnitro.san", 0, 0, 0, 0);
- }
- break;
- case 98:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 6, 180);
- _actor[1].act[2].animTilt = 0;
- }
- if (_roadBumps) {
- smlayer_setActorFacing(1, 2, 7, 180);
- _actor[1].act[2].state = 100;
- }
- _actor[1].kicking = false;
- break;
- case 99:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].animTilt) {
- smlayer_setActorFacing(1, 2, 9, 180);
- _actor[1].act[2].animTilt = 0;
- }
- if (!_roadBumps) {
- smlayer_setActorFacing(1, 2, 8, 180);
- _actor[1].act[2].state = 101;
- }
- _actor[1].kicking = false;
- break;
- case 100:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].frame >= 4) {
- smlayer_setActorFacing(1, 2, 9, 180);
- _actor[1].act[2].state = 99;
- }
- _actor[1].kicking = false;
- break;
- case 101:
- smlayer_setActorLayer(1, 2, 5);
- if (_actor[1].act[2].frame >= 4) {
- smlayer_setActorFacing(1, 2, 6, 180);
- _actor[1].act[2].state = 98;
- }
- _actor[1].kicking = false;
- break;
- case 102:
- _actor[1].lost = true;
- _actor[1].cursorX = 0;
- _actor[1].kicking = false;
- smlayer_setActorCostume(1, 2, readArray(40));
- smlayer_setActorFacing(1, 2, 6, 180);
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].act[2].state = 103;
- case 103:
- _actor[1].kicking = false;
-
- if (_actor[1].act[2].frame >= 18 || ((_actor[1].x < 50 || _actor[1].x > 270) &&
- _actor[1].act[2].frame >= 9)) {
- _enemy[EN_CAVEFISH].isEmpty = 1;
- queueSceneSwitch(20, 0, "wr2_cvko.san", 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- }
- break;
- case 106:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- smlayer_setActorFacing(1, 2, 29, 180);
- _actor[1].act[2].state = 107;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 107:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 8)
- _actor[1].damage = _actor[1].maxdamage + 10;
-
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 108:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- smlayer_setActorFacing(1, 2, 28, 180);
- _actor[1].act[2].state = 109;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 109:
- smlayer_setActorLayer(1, 2, 5);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 6)
- _actor[1].damage = _actor[1].maxdamage + 10;
-
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 110:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- smlayer_setActorFacing(1, 2, 30, 180);
- _actor[1].act[2].state = 111;
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 111:
- smlayer_setActorLayer(1, 2, 4);
- _actor[1].weaponClass = 1;
- _actor[1].kicking = false;
- if (_actor[1].act[2].frame >= 7) {
- smlayer_setActorFacing(1, 2, 25, 180);
- _actor[1].act[2].state = 65;
- smlayer_setActorLayer(1, 2, 5);
- }
- _actor[1].act[2].tilt = calcTilt(_actor[1].tilt);
- break;
- case 113:
- _actor[1].lost = true;
- _actor[1].kicking = false;
- smlayer_setActorCostume(1, 2, readArray(46));
- smlayer_setActorFacing(1, 2, 6, 180);
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- _actor[1].cursorX = 0;
- _actor[1].act[2].state = 114;
- _enemy[EN_VULTF2].isEmpty = 1;
- smlayer_startVoice(275);
- break;
- case 114:
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].kicking = false;
-
- if (_actor[1].act[2].frame >= 16 || ((_actor[1].x < 50 || _actor[1].x > 270)
- && (_actor[1].act[2].frame >= 8))) {
- queueSceneSwitch(11, 0, _enemy[_currEnemy].filename, 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- }
- break;
- case 115:
- _actor[1].lost = true;
- _actor[1].kicking = false;
- smlayer_setActorCostume(1, 2, readArray(47));
- smlayer_setActorFacing(1, 2, 6, 180);
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- _actor[1].cursorX = 0;
- _actor[1].act[2].state = 116;
- smlayer_startVoice(232);
- break;
- case 116:
- smlayer_setActorLayer(1, 2, 25);
- _actor[1].kicking = false;
-
- if (_actor[1].act[2].frame >= 17 || ((_actor[1].x < 50 || _actor[1].x > 270)
- && _actor[1].act[2].frame >= 8)) {
- queueSceneSwitch(11, 0, _enemy[_currEnemy].filename, 64, 0, 0, 0);
- _actor[1].act[2].state = 38;
- }
- break;
- default:
- break;
- }
- tmp = _actor[1].x + _actor[1].act[2].tilt - 17;
- tmp2 = _actor[1].y + _actor[1].y1 - 98;
-
- if (_actor[1].act[2].room)
- smlayer_putActor(1, 2, tmp, tmp2, _smlayer_room2);
- else
- smlayer_putActor(1, 2, tmp, tmp2, _smlayer_room);
-}
-
-int32 Insane::calcEnemyDamage(bool arg_0, bool arg_4) {
- if ((_actor[1].x - _actor[0].x > weaponMaxRange(0)) ||
- (_actor[1].x - _actor[0].x < weaponMinRange(0)))
- return 0;
-
- if (_actor[1].field_44 && arg_4)
- return 1000;
-
- if (!actor1StateFlags(_actor[1].act[2].state))
- return 0;
-
- if (arg_0) {
- ouchSoundEnemy();
- _actor[1].damage += weaponDamage(0);
- }
-
- return 1;
-}
-
-bool Insane::weaponEnemyIsEffective(void) {
- if ((_actor[1].x - _actor[0].x > weaponMaxRange(1)) ||
- (_actor[1].x - _actor[0].x < weaponMinRange(1)) ||
- !_actor[0].kicking)
- return false;
-
- return true;
-}
-
-void Insane::actor13Reaction(int32 buttons) {
- int32 tmp;
-
- switch (_actor[1].act[3].state) {
- case 1:
- case 54:
- _actor[1].field_54 = 0;
- break;
- case 52:
- if (_actor[1].runningSound)
- smlayer_stopSound(_actor[1].runningSound);
-
- if (_currScenePropIdx)
- shutCurrentScene();
-
- _actor[1].runningSound = 0;
- _actor[1].defunct = 0;
- _actor[1].field_54 = 0;
- smlayer_setActorFacing(1, 3, 15, 180);
- _actor[1].act[3].state = 53;
- break;
- case 53:
- _actor[1].field_54 = 0;
- if (_actor[1].act[3].frame >= 2) {
- smlayer_setActorFacing(1, 3, 16, 180);
- _actor[1].act[3].state = 54;
- }
- break;
- case 69:
- if (_actor[1].act[3].frame >= 2)
- _actor[1].act[3].state = 70;
- break;
- case 70:
- if (_actor[1].scenePropSubIdx) {
- smlayer_setActorFacing(1, 3, 4, 180);
- tmp = _currScenePropIdx + _actor[1].scenePropSubIdx;
- if (!smlayer_startVoice(_sceneProp[tmp].sound))
- _actor[1].runningSound = 0;
- else
- _actor[1].runningSound = _sceneProp[tmp].sound;
- _actor[1].act[3].state = 72;
- } else {
- _actor[1].act[3].state = 118;
- }
- break;
- case 71:
- _actor[1].field_54 = 0;
- if (_actor[1].act[3].frame >= 2)
- _actor[1].act[3].state = 1;
- break;
- case 72:
- if (_actor[1].runningSound) {
- if (!smlayer_isSoundRunning(_actor[1].runningSound)) {
- smlayer_setActorFacing(1, 3, 5, 180);
- _actor[1].act[3].state = 70;
- _actor[1].scenePropSubIdx = 0;
- }
- } else {
- tmp = _currScenePropIdx + _actor[1].scenePropSubIdx;
- if (_sceneProp[tmp].counter >= _sceneProp[tmp].maxCounter) {
- smlayer_setActorFacing(1, 3, 5, 180);
- _actor[1].act[3].state = 70;
- _actor[1].scenePropSubIdx = 0;
- _actor[1].runningSound = 0;
- }
- }
- break;
- case 117:
- smlayer_setActorFacing(1, 3, 13, 180);
- _actor[1].field_54 = 1;
- _actor[1].act[3].state = 69;
- break;
- case 118:
- smlayer_setActorFacing(1, 3, 14, 180);
- _actor[1].act[3].state = 71;
- break;
- default:
- break;
- }
-}
-
-
-// FIXME: this is exact actor00Reaction. Combine
-void Insane::actor10Reaction(int32 buttons) {
- int32 tmpx, tmpy;
-
- switch (_actor[1].tilt) {
- case -3:
- if (_actor[1].act[0].state != 41) {
- smlayer_setActorFacing(1, 0, 6, 180);
- _actor[1].act[0].state = 41;
- }
- break;
- case -2:
- if (_actor[1].act[0].state != 40) {
- smlayer_setActorFacing(1, 0, 7, 180);
- _actor[1].act[0].state = 40;
- }
- break;
- case -1:
- if (_actor[1].act[0].state != 39) {
- smlayer_setActorFacing(1, 0, 8, 180);
- _actor[1].act[0].state = 39;
- }
- break;
- case 0:
- if (_actor[1].act[0].state != 1) {
- smlayer_setActorFacing(1, 0, 9, 180);
- _actor[1].act[0].state = 1;
- }
- break;
- case 1:
- if (_actor[1].act[0].state != 55) {
- smlayer_setActorFacing(1, 0, 10, 180);
- _actor[1].act[0].state = 55;
- }
- break;
- case 2:
- if (_actor[1].act[0].state != 56) {
- smlayer_setActorFacing(1, 0, 11, 180);
- _actor[1].act[0].state = 56;
- }
- break;
- case 3:
- if (_actor[1].act[0].state != 57) {
- smlayer_setActorFacing(1, 0, 12, 180);
- _actor[1].act[0].state = 57;
- }
- break;
- default:
- break;
- }
- tmpx = _actor[1].x + _actor[1].x1;
- tmpy = _actor[1].y + _actor[1].y1;
-
- if (_actor[1].act[0].room)
- smlayer_putActor(1, 0, tmpx, tmpy, _smlayer_room2);
- else
- smlayer_putActor(1, 0, tmpx, tmpy, _smlayer_room);
-}
-
-int32 Insane::actionEnemy(void) {
- int32 buttons;
-
- if (_actor[1].enemyHandler != -1)
- buttons = enemyHandler(_actor[1].enemyHandler, 1, 0, _actor[1].probability);
- else
- buttons = enemyHandler(EN_TORQUE, 1, 0, _actor[1].probability);
-
- if (_actor[1].tilt) {
- _actor[1].speed += _actor[1].cursorX / 40;
- } else {
- if (_actor[1].speed < 0)
- _actor[1].speed++;
- else
- _actor[1].speed--;
- }
-
- if (_actor[1].speed > 8)
- _actor[1].speed = 8;
-
- if (_actor[1].speed < -8)
- _actor[1].speed = -8;
-
- _actor[1].x += _actor[0].speed;
-
- if (_actor[1].x > 250)
- _actor[1].x--;
- else if (_actor[1].x < 250)
- _actor[1].x++;
-
- if (_actor[1].x > 320) {
- _actor[1].x = 320;
- _actor[1].damage++;
- _actor[1].x1 = -_actor[1].x1;
- _actor[1].damage++;
-
- return buttons;
- }
-
- if (!_actor[1].lost) {
- if (_actor[0].x + 90 > _actor[1].x)
- _actor[1].x = _actor[0].x + 90;
- }
-
- if (_actor[1].x < 0) {
- _actor[1].x = 0;
- _actor[1].x1 = -_actor[1].x1;
- _actor[1].damage++;
- } else if (_actor[1].x > 310) {
- _actor[1].x1 = -_actor[1].x1;
- _actor[1].damage++;
- }
-
- return buttons;
-}
-
-}
-
diff --git a/scumm/insane/insane_iact.cpp b/scumm/insane/insane_iact.cpp
deleted file mode 100644
index c706c7d191..0000000000
--- a/scumm/insane/insane_iact.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/engine.h"
-
-#include "scumm/scumm.h"
-
-#include "scumm/smush/smush_player.h"
-#include "scumm/smush/chunk_type.h"
-#include "scumm/smush/chunk.h"
-
-#include "scumm/insane/insane.h"
-
-namespace Scumm {
-
-void Insane::procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- if (_keyboardDisable)
- return;
-
- switch (_currSceneId) {
- case 1:
- iactScene1(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
- break;
- case 3:
- case 13:
- iactScene3(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
- break;
- case 4:
- case 5:
- iactScene4(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
- break;
- case 6:
- iactScene6(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
- break;
- case 17:
- iactScene17(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
- break;
- case 21:
- iactScene21(renderBitmap, codecparam, setupsan12, setupsan13, b, size, flags);
- break;
- }
-}
-
-void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- _player->checkBlock(b, TYPE_IACT, 8);
-
- int16 par1, par2, par3, par4, par5, par6, par7, par9, par11, par13, tmp;
-
- par1 = b.getWord(); // cx
- par2 = b.getWord(); // dx
- par3 = b.getWord(); // si
- par4 = b.getWord(); // bx
-
- switch (par1) {
- case 2: // PATCH
- if (par3 != 1)
- break;
-
- par5 = b.getWord(); // si
- if (_actor[0].field_8 == 112) {
- setBit(par5);
- break;
- }
-
- if (_approachAnim == -1) {
- chooseEnemy(); //PATCH
- _approachAnim = _enemy[_currEnemy].apprAnim;
- }
-
- if (_approachAnim == par4)
- clearBit(par5);
- else
- setBit(par5);
- break;
- case 3:
- if (par3 == 1) {
- setBit(b.getWord());
- _approachAnim = -1;
- }
- break;
- case 4:
- if (par3 == 1 && (_approachAnim < 0 || _approachAnim > 4))
- setBit(b.getWord());
- break;
- case 5:
- if (par2 != 13)
- break;
-
- tmp = b.getWord(); // +8
- tmp = b.getWord(); // +10
- par7 = b.getWord(); // +12 dx
- tmp = b.getWord(); // +14
- par9 = b.getWord(); // +16 bx
- tmp = b.getWord(); // +18
- par11 = b.getWord(); // +20 cx
- tmp = b.getWord(); // +22
- par13 = b.getWord(); // +24 ax
-
- if (par13 > _actor[0].x || par11 < _actor[0].x) {
- _tiresRustle = true;
- _actor[0].x1 = -_actor[0].x1;
- _actor[0].damage++; // PATCH
- }
-
- if (par9 < _actor[0].x || par7 > _actor[0].x) {
- _tiresRustle = true;
- _actor[0].damage += 4; // PATCH
- }
- break;
- case 6:
- switch (par2) {
- case 38:
- smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
- _smush_iconsNut, 7, 0, 0);
- _roadBranch = true;
- _iactSceneId = par4;
- break;
- case 25:
- _roadBumps = true;
- _actor[0].y1 = -_actor[0].y1;
- break;
- case 11:
- if (_approachAnim >= 1 && _approachAnim <= 4 && !_needSceneSwitch)
- queueSceneSwitch(13, _smush_minefiteFlu, "minefite.san", 64, 0,
- _continueFrame1, 1300);
- break;
- case 9:
- par5 = b.getWord(); // si
- par6 = b.getWord(); // bx
- smlayer_setFluPalette(_smush_roadrsh3Rip, 0);
- if (par5 == par6 - 1)
- smlayer_setFluPalette(_smush_roadrashRip, 0);
- }
- break;
- case 7:
- switch (par4) {
- case 1:
- _actor[0].x -= (b.getWord() - 160) / 10;
- break;
- case 2:
- par5 = b.getWord();
-
- if (par5 - 8 > _actor[0].x || par5 + 8 < _actor[0].x) {
- if (smlayer_isSoundRunning(86))
- smlayer_stopSound(86);
- } else {
- if (!smlayer_isSoundRunning(86))
- smlayer_startSfx(86);
- }
- break;
- }
- break;
- }
-
- if (_approachAnim < 0 || _approachAnim > 4)
- if (readArray(8)) {
- smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-18, 3,
- _smush_iconsNut, 20, 0, 0);
- _benHasGoggles = true;
- }
-}
-
-void Insane::chooseEnemy(void) {
- if (readArray(58) != 0)
- _enemy[EN_TORQUE].isEmpty = 1;
-
- if (_enemy[EN_TORQUE].occurences == 0) {
- _currEnemy = EN_TORQUE;
- _metEnemiesListTail++;
- _metEnemiesList[_metEnemiesListTail] = EN_TORQUE;
- return;
- }
-
- removeEmptyEnemies();
-
- int32 count, i, j, en, en2;
- bool notfound;
-
- en = 0;
- for (i = 0; i < 9; i++)
- if (_enemy[i].isEmpty == 0)
- ++en;
-
- en -= 4;
- assert(en >= 0);
-
- count = 0;
- while (1) {
- count++;
- if (count < 14) {
- en2 = _vm->_rnd.getRandomNumber(10);
- if (en2 == 9)
- en2 = 6;
- else if (en2 > 9)
- en2 = 7;
-
- notfound = true;
-
- if (_enemy[en2].isEmpty != 0)
- continue;
-
- if (0 < _metEnemiesListTail) {
- i = 0;
- do {
- if (en2 == _metEnemiesList[i + 1])
- notfound = false;
- i++;
- } while (i < _metEnemiesListTail && notfound);
- }
- if (!notfound) {
- continue;
- }
- } else {
- j = 0;
- do {
- notfound = true;
- en2 = j;
- if (0 < _metEnemiesListTail) {
- i = 0;
- do {
- if (en2 == _metEnemiesList[i + 1])
- notfound = false;
- i++;
- } while (i < _metEnemiesListTail && notfound);
- }
- j++;
- } while (j < 9 && !notfound);
- if (!notfound) {
- _metEnemiesListTail = 0;
- count = 0;
- continue;
- }
- }
-
- ++_metEnemiesListTail;
- assert(_metEnemiesListTail < ARRAYSIZE(_metEnemiesList));
- _metEnemiesList[_metEnemiesListTail] = en2;
-
- if (_metEnemiesListTail >= en) {
- removeEnemyFromMetList(0);
- }
-
- if (notfound)
- break;
- }
-
- _currEnemy = en2;
-}
-
-void Insane::removeEmptyEnemies(void) {
- if (_metEnemiesListTail > 0) {
- for (int i = 0; i < _metEnemiesListTail; i++)
- if (_enemy[i].isEmpty == 1)
- removeEnemyFromMetList(i);
- }
-}
-
-void Insane::removeEnemyFromMetList(int32 enemy1) {
- if (enemy1 >= _metEnemiesListTail)
- return;
-
- int en = enemy1;
- do {
- ++en;
- assert(en + 1 < ARRAYSIZE(_metEnemiesList));
- _metEnemiesList[en] = _metEnemiesList[en + 1];
- } while (en < _metEnemiesListTail);
- _metEnemiesListTail--;
-}
-
-void Insane::iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- _player->checkBlock(b, TYPE_IACT, 8);
-
- int command, par1, par2, par3, tmp;
- command = b.getWord();
- par1 = b.getWord();
- if (command == 6) {
- if (par1 == 9) {
- tmp = b.getWord(); // ptr + 4
- tmp = b.getWord(); // ptr + 6
- par2 = b.getWord(); // ptr + 8
- par3 = b.getWord(); // ptr + 10
-
- if (!par2)
- smlayer_setFluPalette(_smush_roadrsh3Rip, 0);
- else {
- if (par2 == par3 - 1)
- smlayer_setFluPalette(_smush_roadrashRip, 0);
- }
- } else if (par1 == 25) {
- _roadBumps = true;
- _actor[0].y1 = -_actor[0].y1;
- _actor[1].y1 = -_actor[1].y1;
- }
- }
-}
-
-void Insane::iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- _player->checkBlock(b, TYPE_IACT, 8);
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- return;
-
- int16 par1, par2, par3, par4, par5;
-
- par1 = b.getWord(); // edx
- par2 = b.getWord(); // bx
- par3 = b.getWord();
- par4 = b.getWord(); // cx
-
- switch (par1) {
- case 2:
- case 4:
- par5 = b.getWord(); // si
- switch (par3) {
- case 1:
- if (par4 == 1) {
- if (readArray(6))
- setBit(par5);
- else
- clearBit(par5);
- } else {
- if (readArray(6))
- clearBit(par5);
- else
- setBit(par5);
- }
- break;
- case 2:
- if (readArray(5))
- clearBit(par5);
- else
- setBit(par5);
- break;
- }
- break;
- case 6:
- switch (par2) {
- case 38:
-
- smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-13, 3,
- _smush_icons2Nut, 10, 0, 0);
- _roadBranch = true;
- _iactSceneId = par4;
- break;
- case 7:
- if (readArray(4) != 0)
- return;
-
- smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, // QW
- _smush_icons2Nut, 8, 0, 0);
- _roadStop = true;
- break;
- case 8:
- if (readArray(4) == 0 || readArray(6) == 0)
- return;
-
- writeArray(1, _posBrokenTruck);
- writeArray(3, _val57d);
- smush_setToFinish();
-
- break;
- case 25:
- if (readArray(5) == 0)
- return;
-
- _carIsBroken = true;
- smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, // QW
- _smush_icons2Nut, 8, 0, 0);
- break;
- case 11:
- smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
- _smush_icons2Nut, 9, 0, 0);
- _roadBranch = true;
- _iactSceneId = par4;
- break;
- }
- break;
- }
-}
-
-void Insane::iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- _player->checkBlock(b, TYPE_IACT, 8);
-
- int16 par1, par2, par3, par4, par5;
-
- par1 = b.getWord();
- par2 = b.getWord(); // bx
- par3 = b.getWord();
- par4 = b.getWord();
-
- switch (par1) {
- case 7:
- par5 = b.getWord();
- if (par4 != 3)
- break;
-
- if (par5 >= _actor[0].x)
- break;
-
- _actor[0].x = par5;
- break;
- case 2:
- case 4:
- par5 = b.getWord();
- switch (par3) {
- case 1:
- if (par4 == 1) {
- if (readArray(6))
- setBit(par5);
- else
- clearBit(par5);
- } else {
- if (readArray(6))
- clearBit(par5);
- else
- setBit(par5);
- }
- break;
- case 2:
- if (readArray(5))
- clearBit(par5);
- else
- setBit(par5);
- break;
- }
- break;
- case 6:
- switch (par2) {
- case 38:
- smlayer_drawSomething(renderBitmap, codecparam, 270-19, 20-13, 3,
- _smush_icons2Nut, 10, 0, 0);
- _roadBranch = true;
- _iactSceneId = par4;
- break;
- case 7:
- if (readArray(4) != 0)
- return;
-
- _roadStop = true;
- smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, //QW
- _smush_icons2Nut, 8, 0, 0);
- break;
- case 8:
- if (readArray(4) == 0 || readArray(6) == 0)
- return;
-
- writeArray(1, _posBrokenTruck);
- writeArray(3, _posVista);
- smush_setToFinish();
-
- break;
- case 25:
- if (readArray(5) == 0)
- return;
-
- _carIsBroken = true;
- smlayer_drawSomething(renderBitmap, codecparam, 160-13, 20-10, 3, //QW
- _smush_icons2Nut, 8, 0, 0);
- break;
- case 11:
- smlayer_drawSomething(renderBitmap, codecparam, 50-19, 20-13, 3,
- _smush_icons2Nut, 9, 0, 0);
- _roadBranch = true;
- _iactSceneId = par4;
- break;
- }
- break;
- }
-}
-
-void Insane::iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- _player->checkBlock(b, TYPE_IACT, 8);
- int16 par1, par2, par3, par4;
-
- par1 = b.getWord(); // dx
- par2 = b.getWord(); // cx
- par3 = b.getWord(); // di
- par4 = b.getWord();
-
- switch (par1) {
- case 2:
- case 3:
- case 4:
- if (par3 == 1) {
- setBit(b.getWord());
- _approachAnim = -1;
- }
- break;
- case 6:
- switch (par2) {
- case 38:
- smlayer_drawSomething(renderBitmap, codecparam, 28, 48, 1,
- _smush_iconsNut, 6, 0, 0);
- _roadBranch = true;
- _iactSceneId = par4;
- if (_counter1 <= 4) {
- if (_counter1 == 4)
- smlayer_startSfx(94);
-
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 24, 167, 1,
- 2, 0, "%s", handleTrsTag(5000));
- }
- _objectDetected = true;
- break;
- case 10:
- smlayer_drawSomething(renderBitmap, codecparam, 28, 48, 1,
- _smush_iconsNut, 6, 0, 0);
- if (_counter1 <= 4) {
- if (_counter1 == 4)
- smlayer_startSfx(94);
-
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 24, 167, 1,
- 2, 0, "%s", handleTrsTag(5001));
- }
- _objectDetected = true;
- _mineCaveIsNear = true;
- break;
- }
- break;
- }
-}
-
-void Insane::iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags) {
- // void implementation
-}
-
-}
-
diff --git a/scumm/insane/insane_scenes.cpp b/scumm/insane/insane_scenes.cpp
deleted file mode 100644
index 7cc01fc2cf..0000000000
--- a/scumm/insane/insane_scenes.cpp
+++ /dev/null
@@ -1,1499 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/engine.h"
-
-#include "common/config-manager.h"
-
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-
-#include "scumm/insane/insane.h"
-
-namespace Scumm {
-
-void Insane::runScene(int arraynum) {
- _insaneIsRunning = true;
- _player = new SmushPlayer(_vm, _speed);
- _player->insanity(true);
-
- _numberArray = arraynum;
-
- // zeroValues1()
- _objArray2Idx = 0;
- _objArray2Idx2 = 0;
- // zeroValues2()
- _objArray1Idx = 0;
- _objArray1Idx2 = 0;
- // zeroValues3()
- _currScenePropIdx = 0;
- _currScenePropSubIdx = 0;
- _currTrsMsg = 0;
-
- smush_warpMouse(160, 100, -1);
- putActors();
- readState();
-
- debugC(DEBUG_INSANE, "INSANE Arg: %d", readArray(0));
-
- switch (readArray(0)) {
- case 1:
- initScene(1);
- setupValues();
- smlayer_setActorCostume(0, 2, readArray(10));
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1 + 190, _smlayer_room2);
- startVideo("minedriv.san", 1, 32, 12, 0);
- break;
- case 2:
- setupValues();
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- smlayer_setActorCostume(0, 2, readArray(10));
- else
- smlayer_setActorCostume(0, 2, readArray(11));
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1 + 190, _smlayer_room2);
-
- _mainRoadPos = readArray(2);
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- initScene(5);
- startVideo("tovista.san", 1, 32, 12, 0);
- } else if (_mainRoadPos == _posBrokenTruck) {
- initScene(5);
- startVideo("tovista2.san", 1, 32, 12, 0);
- } else if (_mainRoadPos == _posBrokenCar) {
- initScene(5);
- startVideo("tovista2.san", 1, 32, 12, 0, _smush_tovista2Flu, 60);
- } else {
- initScene(4);
- startVideo("tovista1.san", 1, 32, 12, 0);
- }
- break;
- case 3:
- setupValues();
- smlayer_setActorCostume(0, 2, readArray(11));
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1 + 190, _smlayer_room2);
- _mainRoadPos = readArray(2);
- if (_mainRoadPos == _posBrokenTruck) {
- initScene(6);
- startVideo("toranch.san", 1, 32, 12, 0, _smush_toranchFlu, 300);
- } else if (_mainRoadPos == _posBrokenCar) {
- initScene(6);
- startVideo("toranch.san", 1, 32, 12, 0, _smush_toranchFlu, 240);
- } else {
- initScene(6);
- startVideo("toranch.san", 1, 32, 12, 0);
- }
- break;
- case 4:
- _firstBattle = true;
- _currEnemy = EN_ROTT1;
- initScene(13);
- startVideo("minefite.san", 1, 32, 12, 0);
- break;
- case 5:
- writeArray(1, _val54d);
- initScene(24);
- startVideo("rottopen.san", 1, 32, 12, 0);
- break;
- case 6:
- initScene(1);
- setupValues();
- smlayer_setFluPalette(_smush_roadrashRip, 1);
- smlayer_setActorCostume(0, 2, readArray(10));
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1 + 190, _smlayer_room2);
- startVideo("minedriv.san", 1, 32, 12, 0, _smush_minedrivFlu, 420);
- break;
- case 7:
- case 8:
- case 9:
- break;
- case 10:
- initScene(26);
- writeArray(1, _val54d);
- startVideo("credits.san", 1, 32, 12, 0);
- break;
- default:
- error("Unknown FT_INSANE mode %d", readArray(0));
- }
-
- putActors();
- _enemy[EN_ROTT3].maxdamage = 120;
-
- _insaneIsRunning = false;
-
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
- writeArray(50, _actor[0].inventory[INV_CHAIN]);
- writeArray(51, _actor[0].inventory[INV_CHAINSAW]);
- writeArray(52, _actor[0].inventory[INV_MACE]);
- writeArray(53, _actor[0].inventory[INV_2X4]);
- writeArray(54, _actor[0].inventory[INV_WRENCH]);
- writeArray(55, _actor[0].inventory[INV_DUST]);
- writeArray(56, _enemy[EN_CAVEFISH].isEmpty);
- writeArray(337, _enemy[EN_TORQUE].occurences);
- writeArray(329, _enemy[EN_ROTT1].occurences);
- writeArray(330, _enemy[EN_ROTT2].occurences);
- writeArray(331, _enemy[EN_ROTT3].occurences);
- writeArray(332, _enemy[EN_VULTF1].occurences);
- writeArray(333, _enemy[EN_VULTM1].occurences);
- writeArray(334, _enemy[EN_VULTF2].occurences);
- writeArray(335, _enemy[EN_VULTM2].occurences);
- writeArray(336, _enemy[EN_CAVEFISH].occurences);
- writeArray(339, _enemy[EN_VULTF2].isEmpty);
- writeArray(340, _enemy[EN_VULTM2].isEmpty);
- }
- // insane_unlock(); // FIXME
- _vm->_sound->stopAllSounds(); // IMUSE_StopAllSounds();
-
- delete _player;
-}
-
-int Insane::initScene(int sceneId) {
- debugC(DEBUG_INSANE, "initScene(%d)", sceneId);
-
- if (_needSceneSwitch)
- return 1;
-
- stopSceneSounds(_currSceneId); // do it for previous scene
- loadSceneData(sceneId, 0, 1);
- if (loadSceneData(sceneId, 0, 2)) {
- setSceneCostumes(sceneId);
- _sceneData2Loaded = 0;
- _sceneData1Loaded = 0;
- } else
- _sceneData2Loaded = 1;
-
- _currSceneId = sceneId;
-
- return 1;
-}
-
-void Insane::stopSceneSounds(int sceneId) {
- int flag = 0;
-
- debugC(DEBUG_INSANE, "stopSceneSounds(%d)", sceneId);
-
- switch (sceneId) {
- case 1:
- smlayer_stopSound(88);
- smlayer_stopSound(86);
- smlayer_stopSound(87);
- flag = 1;
- break;
- case 18:
- case 19:
- smlayer_stopSound(88);
- flag = 1;
- break;
- case 17:
- smlayer_stopSound(88);
- smlayer_stopSound(94);
- flag = 1;
- break;
- case 2:
- case 7:
- case 8:
- flag = 1;
- break;
- case 3:
- case 21:
- flag = 1;
- // break is omittted intentionally
- case 13:
- if (_actor[0].runningSound != 0)
- smlayer_stopSound(_actor[0].runningSound);
- _actor[0].runningSound = 0;
-
- if (_actor[1].runningSound != 0)
- smlayer_stopSound(_actor[1].runningSound);
- _actor[1].runningSound = 0;
-
- if (_currScenePropIdx != 0)
- shutCurrentScene();
-
- _currScenePropSubIdx = 0;
- _currTrsMsg = 0;
- _actor[0].defunct = 0;
- _actor[0].scenePropSubIdx = 0;
- _actor[0].field_54 = 0;
- _actor[1].defunct = 0;
- _actor[1].scenePropSubIdx = 0;
- _actor[1].field_54 = 0;
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- smlayer_stopSound(59);
- smlayer_stopSound(63);
- } else {
- smlayer_stopSound(89);
- smlayer_stopSound(90);
- smlayer_stopSound(91);
- smlayer_stopSound(92);
- smlayer_stopSound(93);
- smlayer_stopSound(95);
- smlayer_stopSound(87);
- }
- break;
- case 4:
- case 5:
- case 6:
- smlayer_stopSound(88);
- smlayer_stopSound(86);
- flag = 1;
- break;
- case 24:
- smlayer_stopSound(90);
- break;
- case 9:
- case 10:
- case 11:
- case 12:
- case 14:
- case 15:
- case 16:
- case 20:
- case 22:
- case 23:
- break;
- }
- if (!flag)
- return;
-
- smlayer_setActorCostume(0, 2, 0);
- smlayer_setActorCostume(0, 0, 0);
- smlayer_setActorCostume(0, 1, 0);
- smlayer_setActorCostume(1, 2, 0);
- smlayer_setActorCostume(1, 0, 0);
- smlayer_setActorCostume(1, 1, 0);
-
- return;
-}
-
-void Insane::shutCurrentScene(void) {
- debugC(DEBUG_INSANE, "shutCurrentScene()");
-
- _currScenePropIdx = 0;
- _currTrsMsg = 0;
- _currScenePropSubIdx = 0;
- _actor[1].scenePropSubIdx = 0;
- _actor[1].defunct = 0;
-
- if (_actor[1].runningSound != 0) {
- smlayer_stopSound(_actor[1].runningSound);
- _actor[1].runningSound = 0;
- }
-
- _actor[0].scenePropSubIdx = 0;
- _actor[0].defunct = 0;
-
- if (_actor[0].runningSound != 0) {
- smlayer_stopSound(_actor[0].runningSound);
- _actor[0].runningSound = 0;
- }
-
- _battleScene = true;
-}
-
-
-// insane_loadSceneData1 & insane_loadSceneData2
-int Insane::loadSceneData(int scene, int flag, int phase) {
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- return 1;
-
- int retvalue = 1;
-
- debugC(DEBUG_INSANE, "Insane::loadSceneData(%d, %d, %d)", scene, flag, phase);
- //if (phase == 1) /// FIXME
- // insane_unlock();
- switch (scene) {
- case 1:
- smlayer_loadSound(88, flag, phase);
- smlayer_loadSound(86, flag, phase);
- smlayer_loadSound(87, flag, phase);
- smlayer_loadCostume(10, phase);
- break;
- case 4:
- case 5:
- case 6:
- smlayer_loadSound(88, flag, phase);
- smlayer_loadCostume(11, phase);
- break;
- case 3:
- case 13:
- switch(_currEnemy) {
- case EN_TORQUE:
- smlayer_loadSound(59, flag, phase);
- smlayer_loadSound(93, flag, phase);
- smlayer_loadCostume(57, phase);
- smlayer_loadCostume(37, phase);
- break;
- case EN_ROTT1:
- smlayer_loadSound(201, flag, phase);
- smlayer_loadSound(194, flag, phase);
- smlayer_loadSound(195, flag, phase);
- smlayer_loadSound(199, flag, phase);
- smlayer_loadSound(205, flag, phase);
- smlayer_loadSound(212, flag, phase);
- smlayer_loadSound(198, flag, phase);
- smlayer_loadSound(203, flag, phase);
- smlayer_loadSound(213, flag, phase);
- smlayer_loadSound(215, flag, phase);
- smlayer_loadSound(216, flag, phase);
- smlayer_loadSound(217, flag, phase);
- smlayer_loadSound(218, flag, phase);
- smlayer_loadSound(90, flag, phase);
- smlayer_loadCostume(26, phase);
- smlayer_loadCostume(16, phase);
- smlayer_loadCostume(17, phase);
- smlayer_loadCostume(27, phase);
- break;
- case EN_ROTT2:
- smlayer_loadSound(242, flag, phase);
- smlayer_loadSound(244, flag, phase);
- smlayer_loadSound(236, flag, phase);
- smlayer_loadSound(238, flag, phase);
- smlayer_loadSound(239, flag, phase);
- smlayer_loadSound(240, flag, phase);
- smlayer_loadSound(258, flag, phase);
- smlayer_loadSound(259, flag, phase);
- smlayer_loadSound(260, flag, phase);
- smlayer_loadSound(243, flag, phase);
- smlayer_loadSound(244, flag, phase);
- smlayer_loadSound(245, flag, phase);
- smlayer_loadSound(246, flag, phase);
- smlayer_loadSound(233, flag, phase);
- smlayer_loadSound(234, flag, phase);
- smlayer_loadSound(241, flag, phase);
- smlayer_loadSound(242, flag, phase);
- smlayer_loadSound(90, flag, phase);
- smlayer_loadCostume(28, phase);
- smlayer_loadCostume(16, phase);
- smlayer_loadCostume(17, phase);
- smlayer_loadCostume(42, phase);
- break;
- case EN_ROTT3:
- smlayer_loadSound(223, flag, phase);
- smlayer_loadSound(224, flag, phase);
- smlayer_loadSound(225, flag, phase);
- smlayer_loadSound(226, flag, phase);
- smlayer_loadSound(228, flag, phase);
- smlayer_loadSound(229, flag, phase);
- smlayer_loadSound(230, flag, phase);
- smlayer_loadSound(232, flag, phase);
- smlayer_loadSound(220, flag, phase);
- smlayer_loadSound(221, flag, phase);
- smlayer_loadSound(222, flag, phase);
- smlayer_loadSound(90, flag, phase);
- smlayer_loadCostume(15, phase);
- smlayer_loadCostume(16, phase);
- smlayer_loadCostume(17, phase);
- smlayer_loadCostume(43, phase);
- smlayer_loadCostume(47, phase);
- break;
- case EN_VULTF1:
- smlayer_loadSound(282, flag, phase);
- smlayer_loadSound(283, flag, phase);
- smlayer_loadSound(284, flag, phase);
- smlayer_loadSound(285, flag, phase);
- smlayer_loadSound(286, flag, phase);
- smlayer_loadSound(287, flag, phase);
- smlayer_loadSound(279, flag, phase);
- smlayer_loadSound(280, flag, phase);
- smlayer_loadSound(281, flag, phase);
- smlayer_loadSound(277, flag, phase);
- smlayer_loadSound(288, flag, phase);
- smlayer_loadSound(278, flag, phase);
- smlayer_loadSound(91, flag, phase);
- smlayer_loadCostume(29, phase);
- smlayer_loadCostume(33, phase);
- smlayer_loadCostume(32, phase);
- smlayer_loadCostume(37, phase);
- break;
- case EN_VULTM1:
- smlayer_loadSound(160, flag, phase);
- smlayer_loadSound(161, flag, phase);
- smlayer_loadSound(174, flag, phase);
- smlayer_loadSound(167, flag, phase);
- smlayer_loadSound(163, flag, phase);
- smlayer_loadSound(164, flag, phase);
- smlayer_loadSound(170, flag, phase);
- smlayer_loadSound(166, flag, phase);
- smlayer_loadSound(175, flag, phase);
- smlayer_loadSound(162, flag, phase);
- smlayer_loadSound(91, flag, phase);
- smlayer_loadCostume(30, phase);
- smlayer_loadCostume(33, phase);
- smlayer_loadCostume(32, phase);
- smlayer_loadCostume(36, phase);
- break;
- case EN_VULTF2:
- smlayer_loadSound(263, flag, phase);
- smlayer_loadSound(264, flag, phase);
- smlayer_loadSound(265, flag, phase);
- smlayer_loadSound(266, flag, phase);
- smlayer_loadSound(267, flag, phase);
- smlayer_loadSound(268, flag, phase);
- smlayer_loadSound(270, flag, phase);
- smlayer_loadSound(271, flag, phase);
- smlayer_loadSound(275, flag, phase);
- smlayer_loadSound(276, flag, phase);
- smlayer_loadSound(261, flag, phase);
- smlayer_loadSound(262, flag, phase);
- smlayer_loadSound(263, flag, phase);
- smlayer_loadSound(274, flag, phase);
- smlayer_loadSound(91, flag, phase);
- smlayer_loadCostume(31, phase);
- smlayer_loadCostume(33, phase);
- smlayer_loadCostume(32, phase);
- smlayer_loadCostume(35, phase);
- smlayer_loadCostume(46, phase);
- break;
- case EN_VULTM2:
- smlayer_loadSound(179, flag, phase);
- smlayer_loadSound(183, flag, phase);
- smlayer_loadSound(184, flag, phase);
- smlayer_loadSound(186, flag, phase);
- smlayer_loadSound(191, flag, phase);
- smlayer_loadSound(192, flag, phase);
- smlayer_loadSound(180, flag, phase);
- smlayer_loadSound(101, flag, phase);
- smlayer_loadSound(289, flag, phase);
- smlayer_loadSound(177, flag, phase);
- smlayer_loadSound(178, flag, phase);
- smlayer_loadSound(290, flag, phase);
- smlayer_loadSound(102, flag, phase);
- smlayer_loadSound(91, flag, phase);
- smlayer_loadCostume(34, phase);
- smlayer_loadCostume(33, phase);
- smlayer_loadCostume(32, phase);
- smlayer_loadCostume(44, phase);
- smlayer_loadCostume(45, phase);
- break;
- case EN_CAVEFISH:
- smlayer_loadSound(291, flag, phase);
- smlayer_loadSound(100, flag, phase);
- smlayer_loadSound(92, flag, phase);
- smlayer_loadCostume(39, phase);
- smlayer_loadCostume(40, phase);
- smlayer_loadCostume(41, phase);
- break;
- default:
- retvalue = 0;
- break;
- }
- smlayer_loadSound(64, flag, phase);
- smlayer_loadSound(65, flag, phase);
- smlayer_loadSound(66, flag, phase);
- smlayer_loadSound(67, flag, phase);
- smlayer_loadSound(68, flag, phase);
- smlayer_loadSound(69, flag, phase);
- smlayer_loadSound(70, flag, phase);
- smlayer_loadSound(71, flag, phase);
- smlayer_loadSound(72, flag, phase);
- smlayer_loadSound(73, flag, phase);
- smlayer_loadSound(74, flag, phase);
- smlayer_loadSound(75, flag, phase);
- smlayer_loadSound(76, flag, phase);
- smlayer_loadSound(77, flag, phase);
- smlayer_loadSound(78, flag, phase);
- smlayer_loadSound(79, flag, phase);
- smlayer_loadSound(80, flag, phase);
- smlayer_loadSound(81, flag, phase);
- smlayer_loadSound(82, flag, phase);
- smlayer_loadSound(83, flag, phase);
- smlayer_loadSound(84, flag, phase);
- smlayer_loadSound(85, flag, phase);
- smlayer_loadSound(86, flag, phase);
- smlayer_loadSound(87, flag, phase);
- smlayer_loadSound(62, flag, phase);
- smlayer_loadSound(63, flag, phase);
- smlayer_loadSound(60, flag, phase);
- smlayer_loadSound(61, flag, phase);
- smlayer_loadSound(315, flag, phase);
- smlayer_loadSound(316, flag, phase);
- smlayer_loadSound(317, flag, phase);
- smlayer_loadSound(98, flag, phase);
- smlayer_loadSound(318, flag, phase);
- smlayer_loadSound(96, flag, phase);
- smlayer_loadSound(97, flag, phase);
- smlayer_loadSound(95, flag, phase);
- smlayer_loadSound(89, flag, phase);
- smlayer_loadCostume(12, phase);
- smlayer_loadCostume(13, phase);
- smlayer_loadCostume(14, phase);
- smlayer_loadCostume(18, phase);
- smlayer_loadCostume(22, phase);
- smlayer_loadCostume(19, phase);
- smlayer_loadCostume(38, phase);
- smlayer_loadCostume(20, phase);
- smlayer_loadCostume(21, phase);
- smlayer_loadCostume(23, phase);
- smlayer_loadCostume(24, phase);
- smlayer_loadCostume(25, phase);
- break;
- case 21:
- case 24:
- case 25:
- smlayer_loadSound(223, flag, phase);
- smlayer_loadSound(224, flag, phase);
- smlayer_loadSound(225, flag, phase);
- smlayer_loadSound(226, flag, phase);
- smlayer_loadSound(228, flag, phase);
- smlayer_loadSound(229, flag, phase);
- smlayer_loadSound(230, flag, phase);
- smlayer_loadSound(232, flag, phase);
- smlayer_loadSound(90, flag, phase);
- smlayer_loadCostume(15, phase);
- smlayer_loadCostume(16, phase);
- smlayer_loadCostume(17, phase);
- smlayer_loadCostume(43, phase);
- smlayer_loadSound(62, flag, phase);
- smlayer_loadSound(63, flag, phase);
- smlayer_loadSound(60, flag, phase);
- smlayer_loadSound(61, flag, phase);
- smlayer_loadSound(315, flag, phase);
- smlayer_loadSound(316, flag, phase);
- smlayer_loadSound(317, flag, phase);
- smlayer_loadSound(98, flag, phase);
- smlayer_loadSound(318, flag, phase);
- smlayer_loadSound(96, flag, phase);
- smlayer_loadSound(97, flag, phase);
- smlayer_loadSound(95, flag, phase);
- smlayer_loadSound(89, flag, phase);
- smlayer_loadCostume(12, phase);
- smlayer_loadCostume(13, phase);
- smlayer_loadCostume(14, phase);
- smlayer_loadCostume(18, phase);
- smlayer_loadCostume(22, phase);
- break;
- case 17:
- smlayer_loadSound(88, flag, phase);
- smlayer_loadSound(94, flag, phase);
- break;
- case 2:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 14:
- case 15:
- case 16:
- case 18:
- case 19:
- case 20:
- case 22:
- case 23:
- break;
- default:
- retvalue = 0;
- }
- if (phase == 1) {
- _sceneData1Loaded = 1;
- }
- return retvalue;
-}
-
-void Insane::setSceneCostumes(int sceneId) {
- debugC(DEBUG_INSANE, "Insane::setSceneCostumes(%d)", sceneId);
-
- switch (sceneId) {
- case 1:
- smlayer_setActorCostume(0, 2, readArray(10));
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1 + 190, _smlayer_room2);
- smlayer_setFluPalette(_smush_roadrashRip, 0);
- setupValues();
- return;
- break;
- case 17:
- smlayer_setFluPalette(_smush_goglpaltRip, 0);
- setupValues();
- return;
- break;
- case 2:
- smlayer_setActorCostume(0, 2, readArray(10));
- setupValues();
- return;
- break;
- case 13:
- setEnemyCostumes();
- smlayer_setFluPalette(_smush_roadrashRip, 0);
- return;
- break;
- case 21:
- _currEnemy = EN_ROTT3; //PATCH
- setEnemyCostumes();
- _actor[1].y = 200;
- smlayer_setFluPalette(_smush_roadrashRip, 0);
- return;
- break;
- case 4:
- case 5:
- case 6:
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- smlayer_setActorCostume(0, 2, readArray(10));
- else
- smlayer_setActorCostume(0, 2, readArray(11));
- smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1+190, _smlayer_room2);
- setupValues();
- return;
- break;
- case 7:
- case 8:
- writeArray(4, 0);
- return;
- }
-}
-
-void Insane::setEnemyCostumes(void) {
- int i;
-
- debugC(DEBUG_INSANE, "setEnemyCostumes(%d)", _currEnemy);
-
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)) {
- smlayer_setActorCostume(0, 2, readArray(11));
- smlayer_setActorCostume(0, 0, readArray(13));
- smlayer_setActorCostume(0, 1, readArray(12));
- } else {
- smlayer_setActorCostume(0, 2, readArray(12));
- smlayer_setActorCostume(0, 0, readArray(14));
- smlayer_setActorCostume(0, 1, readArray(13));
- }
- smlayer_setActorLayer(0, 1, 1);
- smlayer_setActorLayer(0, 2, 5);
- smlayer_setActorLayer(0, 0, 10);
- smlayer_putActor(0, 2, _actor[0].x+11, _actor[0].y1+102, _smlayer_room2);
- smlayer_putActor(0, 1, _actor[0].x, _actor[0].y1+200, _smlayer_room2);
- smlayer_putActor(0, 0, _actor[0].x, _actor[0].y1+200, _smlayer_room2);
-
- if (_currEnemy == EN_CAVEFISH) {
- smlayer_setActorCostume(1, 2, readArray(_enemy[_currEnemy].costume4));
- _actor[1].act[2].room = 1;
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- _actor[1].act[2].animTilt = 1;
- _actor[1].field_8 = 98;
- _actor[1].act[2].state = 98;
- _actor[1].act[0].state = 98;
- _actor[1].act[1].state = 98;
-
- smlayer_putActor(1, 2, _actor[1].x + _actor[1].act[2].tilt - 17,
- _actor[1].y + _actor[1].y1 - 98, _smlayer_room2);
- } else if (_currEnemy == EN_TORQUE) {
- smlayer_setActorCostume(1, 2, readArray(_enemy[_currEnemy].costume4));
- _actor[1].act[2].room = 1;
- _actor[1].act[1].room = 0;
- _actor[1].act[0].room = 0;
- _actor[1].field_8 = 1;
- _actor[1].act[2].state = 1;
- _actor[1].act[0].state = 1;
- _actor[1].act[1].state = 1;
- smlayer_putActor(1, 2, _actor[1].x + _actor[1].act[2].tilt - 17,
- _actor[1].y + _actor[1].y1 - 98, _smlayer_room2);
- } else {
- _actor[1].act[2].room = 1;
- _actor[1].act[1].room = 1;
- _actor[1].act[0].room = 1;
-
- if (_enemy[_currEnemy].costume4)
- smlayer_setActorCostume(1, 2, readArray(_enemy[_currEnemy].costume4));
-
- if (_enemy[_currEnemy].costume5)
- smlayer_setActorCostume(1, 0, readArray(_enemy[_currEnemy].costume5));
-
- if (_enemy[_currEnemy].costume6)
- smlayer_setActorCostume(1, 1, readArray(_enemy[_currEnemy].costume6));
-
- _actor[1].field_8 = 1;
- _actor[1].act[2].state = 1;
- _actor[1].act[0].state = 1;
- _actor[1].act[1].state = 1;
-
- if (_actor[1].act[2].room != 0)
- smlayer_putActor(1, 2, _actor[1].x + _actor[1].act[2].tilt - 17,
- _actor[1].y + _actor[1].y1 - 98,
- _smlayer_room2);
- }
-
- if (_actor[1].act[1].room != 0)
- smlayer_putActor(1, 1, _actor[1].x, _actor[1].y + _actor[1].y1,
- _smlayer_room2);
-
- if (_actor[1].act[0].room != 0)
- smlayer_putActor(1, 0, _actor[1].x, _actor[1].y + _actor[1].y1,
- _smlayer_room2);
-
- smlayer_setActorLayer(1, 1, 1);
- smlayer_setActorLayer(1, 2, 5);
- smlayer_setActorLayer(1, 0, 10);
-
- _actor[1].damage = 0;
- _actor[1].x = 250;
- _actor[1].y = 300;
- _actor[1].cursorX = 0;
- _actor[1].tilt = 0;
- _actor[1].weapon = -1;
- _actor[1].weaponClass = 2;
- _enemy[_currEnemy].occurences++;
- _actor[1].maxdamage = _enemy[_currEnemy].maxdamage;
- _actor[1].enemyHandler = _enemy[_currEnemy].handler;
- _actor[1].animWeaponClass = 0;
- for (i = 0; i < 8; i++)
- _actor[1].inventory[i] = 0;
- _actor[0].damage = 0;
- _actor[0].x = 100;
- _actor[0].y = 200;
- _actor[0].weapon = INV_HAND;
- _actor[0].weaponClass = 2;
- _actor[0].animWeaponClass = 0;
- _actor[0].newFacingFlag = 2;
- _actor[0].curFacingFlag = 0;
- _actor[0].tilt = 0;
- _actor[0].field_8 = 1;
- _actor[0].act[2].state = 1;
- _actor[0].act[2].animTilt = 1;
- _actor[0].act[0].state = 0;
- _actor[0].act[1].state = 1;
- _actor[0].act[2].room = 1;
- _actor[0].act[1].room = 1;
- _actor[0].act[0].room = 1;
- _actor[0].cursorX = 0;
- _actor[0].defunct = 0;
- _actor[0].scenePropSubIdx = 0;
- _actor[0].field_54 = 0;
- _actor[0].runningSound = 0;
- _actor[0].lost = false;
- _actor[0].kicking = false;
- _actor[0].field_44 = false;
- _actor[1].inventory[_enemy[_currEnemy].weapon] = 1;
- _actor[0].field_48 = false;
- _actor[1].defunct = 0;
- _actor[1].scenePropSubIdx = 0;
- _actor[1].field_54 = 0;
- _actor[1].runningSound = 0;
- _actor[1].lost = false;
- _actor[1].kicking = false;
- _actor[1].field_44 = false;
- _actor[1].field_48 = false;
- if (_enemy[_currEnemy].initializer != -1)
- enemyInitializer(_enemy[_currEnemy].initializer, _actor[1].damage,
- _actor[0].damage, _actor[1].probability);
-
- smush_warpMouse(160, 100, -1);
-}
-
-void Insane::procPreRendering(void) {
- _smush_isSanFileSetup = 0; // FIXME: This shouldn't be here
-
- switchSceneIfNeeded();
-
- if (_sceneData1Loaded) {
- _val115_ = true;
- if (!_keyboardDisable) {
- smush_changeState(1);
- _keyboardDisable = 1;
- }
- } else {
- _val115_ = false;
- if (_keyboardDisable) {
- smush_changeState(0);
- _keyboardDisable = 0;
- }
- }
-
- _lastKey = getLastKey(1);
-}
-
-void Insane::procPostRendering(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- int32 tmpSnd;
- bool needMore = false;
-
- if (!_keyboardDisable) {
- switch (_currSceneId) {
- case 12:
- postCase11(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 1:
- postCase0(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- if (!smlayer_isSoundRunning(88))
- smlayer_startSfx(88);
- smlayer_soundSetPan(88, ((_actor[0].x+160)>>2)+64);
- if (_tiresRustle) {
- if (!smlayer_isSoundRunning(87))
- smlayer_startSfx(87);
- } else {
- smlayer_stopSound(87);
- }
- break;
- case 18:
- case 19:
- postCase17(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- smlayer_stopSound(95);
- smlayer_stopSound(87);
- smlayer_stopSound(88);
- if (!smlayer_isSoundRunning(88))
- smlayer_startSfx(88);
- break;
- case 17:
- postCase16(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- if (!smlayer_isSoundRunning(88))
- smlayer_startSfx(88);
- break;
- case 2:
- postCase1(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 3:
- postCase2(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- needMore = true;
- if (!smlayer_isSoundRunning(89)) {
- smlayer_startSfx(89);
- smlayer_soundSetPriority(89, 100);
- }
- tmpSnd = _enemy[_currEnemy].sound;
- if (!smlayer_isSoundRunning(tmpSnd)) {
- smlayer_startSfx(tmpSnd);
- smlayer_soundSetPriority(tmpSnd, 100);
- }
- smlayer_soundSetPan(89, ((_actor[0].x+160)>>2)+64);
- smlayer_soundSetPan(tmpSnd, ((_actor[1].x+160)>>2)+64);
- if (!_tiresRustle) {
- smlayer_stopSound(87);
- } else {
- if (!smlayer_isSoundRunning(87))
- smlayer_startSfx(87);
- }
- break;
- case 21:
- postCase20(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- needMore = true;
- if (!smlayer_isSoundRunning(89)) {
- smlayer_startSfx(89);
- smlayer_soundSetPriority(89, 100);
- }
- tmpSnd = _enemy[_currEnemy].sound;
- if (!smlayer_isSoundRunning(tmpSnd)) {
- smlayer_startSfx(tmpSnd);
- smlayer_soundSetPriority(tmpSnd, 100);
- }
- smlayer_soundSetPan(89, ((_actor[0].x+160)>>2)+64);
- smlayer_soundSetPan(tmpSnd, ((_actor[1].x+160)>>2)+64);
- break;
- case 4:
- case 5:
- postCase3(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- if (!smlayer_isSoundRunning(88))
- smlayer_startSfx(88);
- smlayer_soundSetPan(88, ((_actor[0].x+160)>>2)+64);
- break;
- case 6:
- postCase5(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- if (!smlayer_isSoundRunning(88))
- smlayer_startSfx(88);
- smlayer_soundSetPan(88, ((_actor[0].x+160)>>2)+64);
- break;
- case 7:
- case 8:
- postCase6(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 9:
- case 23:
- postCase8(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 10:
- postCase9(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 11:
- case 20:
- case 22:
- postCase10(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 14:
- postCase23(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 13:
- postCase12(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- needMore = true;
- if (!smlayer_isSoundRunning(89)) {
- smlayer_startSfx(89);
- smlayer_soundSetPriority(89, 100);
- }
- tmpSnd = _enemy[_currEnemy].sound;
- if (!smlayer_isSoundRunning(tmpSnd)) {
- smlayer_startSfx(tmpSnd);
- smlayer_soundSetPriority(tmpSnd, 100);
- }
- smlayer_soundSetPan(89, ((_actor[0].x+160)>>2)+64);
- smlayer_soundSetPan(tmpSnd, ((_actor[1].x+160)>>2)+64);
- break;
- case 24:
- if (!smlayer_isSoundRunning(90)) {
- smlayer_startSfx(90);
- smlayer_soundSetPriority(90, 100);
- }
- postCase23(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 15:
- case 16:
- postCase14(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
- break;
- case 25:
- case 26:
- break;
- }
-
- if (_currScenePropIdx)
- postCaseAll(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
-
- _actor[0].frame++;
- _actor[0].act[3].frame++;
- _actor[0].act[2].frame++;
- _actor[0].act[1].frame++;
- _actor[0].act[0].frame++;
- _actor[1].act[3].frame++;
- _actor[1].frame++;
- _actor[1].act[2].frame++;
- _actor[1].act[1].frame++;
- _actor[1].act[0].frame++;
- }
-
- if (!_val115_) {
- smlayer_overrideDrawActorAt(&renderBitmap[0], renderBitmap[2], renderBitmap[3]);
- _isBenCut = 0;
- }
-
- if (_isBenCut)
- smlayer_drawSomething(renderBitmap, codecparam, 89, 56, 1, _smush_bencutNut, 0, 0, 0);
-
- if (!_keyboardDisable)
- _vm->processActors();
-
- if (needMore)
- postCaseMore(renderBitmap, codecparam, setupsan12, setupsan13, curFrame, maxFrame);
-
- _lastKey = 0;
- _tiresRustle = false;
-}
-
-void Insane::postCase11(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame && !_needSceneSwitch) {
- if (_firstBattle) {
- smush_setToFinish();
- } else {
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame, 1300);
- }
- }
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase0(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- turnBen(true);
-
- if (!curFrame || curFrame == 420)
- smlayer_setFluPalette(_smush_roadrashRip, 0);
-
- if (curFrame >= maxFrame)
- smush_rewindCurrentSan(1088, -1, -1);
-
- _roadBumps = false;
- _roadBranch = false;
- _roadStop = false;
- _benHasGoggles = false;
- _mineCaveIsNear = false;
- _continueFrame1 = curFrame;
-}
-
-void Insane::postCase17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame && !_needSceneSwitch) {
- if (_currSceneId == 18) {
- queueSceneSwitch(17, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame1, 1300);
- writeArray(9, 1);
- } else {
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame1, 1300);
- writeArray(9, 0);
- }
- }
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase16(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- char buf[12];
- int32 tmp;
-
- turnBen(true);
- sprintf(buf, "^f01%02o", curFrame & 0x3f);
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 180, 168, 1, 2, 0, "%s", buf);
- tmp = 400-curFrame;
-
- if (tmp < 0)
- tmp += 1300;
-
- sprintf(buf, "^f01%04d", tmp);
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 202, 168, 1, 2, 0, "%s", buf);
-
- sprintf(buf, "^f01%02o", curFrame & 0xff);
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 240, 168, 1, 2, 0, "%s", buf);
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 170, 43, 1, 2, 0, "%s", buf);
-
- smlayer_drawSomething(renderBitmap, codecparam, 0, 0, 1, _smush_bensgoggNut, 0, 0, 0);
-
- if (!_objectDetected)
- smlayer_drawSomething(renderBitmap, codecparam, 24, 170, 1,
- _smush_iconsNut, 23, 0, 0);
-
- if (!curFrame)
- smlayer_setFluPalette(_smush_goglpaltRip, 0);
-
- if (curFrame >= maxFrame) {
- smush_rewindCurrentSan(1088, -1, -1);
- smlayer_setFluPalette(_smush_goglpaltRip, 0);
- }
- _roadBumps = false;
- _mineCaveIsNear = false;
- _roadBranch = false;
- _roadStop = false;
- _objectDetected = false;
- _counter1++;
- _continueFrame1 = curFrame;
- if (_counter1 >= 10)
- _counter1 = 0;
-}
-
-void Insane::postCase1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- struct fluConf *flu;
-
- if ((curFrame >= maxFrame) && !_needSceneSwitch) {
- flu = &_fluConf[14 + _iactSceneId2];
- queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
- flu->startFrame, flu->numFrames);
- }
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase2(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- turnBen(_battleScene != 0);
- turnEnemy(true);
-
- if (!curFrame)
- smlayer_setFluPalette(_smush_roadrashRip, 0);
-
- if (curFrame >= maxFrame)
- smush_rewindCurrentSan(1088, -1, -1);
-
- _roadBumps = false;
- _roadBranch = false;
- _roadStop = false;
- _continueFrame = curFrame;
-}
-
-void Insane::postCase20(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- turnBen(true);
- turnEnemy(true);
-
- if (curFrame >= maxFrame)
- smush_rewindCurrentSan(1088, -1, -1);
-
- _roadBumps = false;
- _roadBranch = false;
- _roadStop = false;
- _continueFrame = curFrame;
-}
-
-void Insane::postCase3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if ((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))
- turnBen(false);
- else
- turnBen(true);
-
- if (_actor[0].x >= 158 && _actor[0].x <= 168) {
- if (!smlayer_isSoundRunning(86))
- smlayer_startSfx(86);
- } else {
- if (smlayer_isSoundRunning(86))
- smlayer_stopSound(86);
- }
-
- if (curFrame >= maxFrame) {
- if (_currSceneId == 4) {
- if (!_needSceneSwitch) {
- if (readArray(6)) {
- if (readArray(4))
- queueSceneSwitch(14, 0, "hitdust2.san", 64, 0, 0, 0);
- else
- queueSceneSwitch(14, 0, "hitdust4.san", 64, 0, 0, 0);
- } else {
- if (readArray(4))
- queueSceneSwitch(14, 0, "hitdust1.san", 64, 0, 0, 0);
- else
- queueSceneSwitch(14, 0, "hitdust3.san", 64, 0, 0, 0);
- }
- }
- } else {
- if (readArray(4)) {
- if (!_needSceneSwitch)
- queueSceneSwitch(15, 0, "vistthru.san", 64, 0, 0, 0);
- } else {
- writeArray(1, _posVista);
- smush_setToFinish();
- }
- }
- }
-
- _carIsBroken = false;
- _roadStop = false;
- _roadBranch = false;
- _iactSceneId = 0;
-}
-
-void Insane::postCase5(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- turnBen(true);
-
- if (_actor[0].x >= 158 && _actor[0].x <= 168) {
- if (!smlayer_isSoundRunning(86))
- smlayer_startSfx(86);
- } else {
- if (smlayer_isSoundRunning(86))
- smlayer_stopSound(86);
- }
-
- if (curFrame >= maxFrame) {
- if (readArray(4)) {
- if (!_needSceneSwitch)
- queueSceneSwitch(15, 0, "chasthru.san", 64, 0, 0, 0);
- } else {
- if (readArray(5)) {
- writeArray(1, _val57d);
- smush_setToFinish();
- } else {
- writeArray(4, 1);
- queueSceneSwitch(15, 0, "chasout.san", 64, 0, 0, 0);
- }
- }
- }
-
- _carIsBroken = false;
- _roadStop = false;
- _roadBranch = false;
- _iactSceneId = 0;
-}
-
-void Insane::postCase6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- struct fluConf *flu;
-
- if ((curFrame >= maxFrame) && !_needSceneSwitch) {
- if (_currSceneId == 8)
- flu = &_fluConf[7 + _iactSceneId2];
- else
- flu = &_fluConf[0 + _iactSceneId2];
-
- queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0,
- flu->startFrame, flu->numFrames);
- }
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase8(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame && !_needSceneSwitch) {
- _actor[0].damage = 0;
-
- if (_firstBattle) {
- queueSceneSwitch(13, _smush_minefiteFlu, "minefite.san", 64, 0,
- _continueFrame, 1300);
- } else {
- if (_currSceneId == 23) {
- queueSceneSwitch(21, 0, "rottfite.san", 64, 0, 0, 0);
- } else {
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame, 1300);
- }
- }
- }
-
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase9(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame && !_needSceneSwitch) {
- _actor[0].damage = 0;
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame1, 1300);
- }
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase10(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame && !_needSceneSwitch) {
- _actor[0].damage = 0;
-
- switch (_currSceneId) {
- case 20:
- writeArray(8, 1);
- queueSceneSwitch(12, 0, "liftgog.san", 0, 0, 0, 0);
- break;
- case 22:
- writeArray(1, _val54d);
- smush_setToFinish();
- break;
- default:
- if (_actor[0].inventory[_enemy[_currEnemy].weapon]) {
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame, 1300);
- break;
- }
-
- switch (_enemy[_currEnemy].weapon) {
- case INV_CHAIN:
- _actor[0].inventory[INV_CHAIN] = 1;
- queueSceneSwitch(12, 0, "liftchay.san", 0, 0, 0, 0);
- break;
- case INV_CHAINSAW:
- _actor[0].inventory[INV_CHAINSAW] = 1;
- queueSceneSwitch(12, 0, "liftsaw.san", 0, 0, 0, 0);
- break;
- case INV_MACE:
- _actor[0].inventory[INV_MACE] = 1;
- queueSceneSwitch(12, 0, "liftmace.san", 0, 0, 0, 0);
- break;
- case INV_2X4:
- _actor[0].inventory[INV_2X4] = 1;
- queueSceneSwitch(12, 0, "liftbord.san", 0, 0, 0, 0);
- break;
- default:
- queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0,
- _continueFrame, 1300);
- break;
- }
- }
- }
-
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase12(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (_actor[1].y <= 200) {
- initScene(3);
- _actor[1].y = 200;
-
- switch (_currEnemy) {
- case EN_ROTT2:
- turnBen(true);
-
- if (_enemy[EN_ROTT2].occurences <= 1)
- prepareScenePropScene(32, 0, 1);
- else
- prepareScenePropScene(33, 0, 1);
- break;
- case EN_ROTT3:
- turnBen(true);
-
- if (_enemy[EN_ROTT3].occurences <= 1)
- prepareScenePropScene(25, 0, 1);
- break;
- case EN_VULTF1:
- turnBen(true);
-
- if (_enemy[EN_VULTF1].occurences <= 1)
- prepareScenePropScene(2, 0, 1);
- break;
- case EN_VULTF2:
- turnBen(true);
-
- if (_enemy[EN_VULTF2].occurences <= 1)
- prepareScenePropScene(9, 0, 1);
- else
- prepareScenePropScene(16, 0, 1);
- break;
- case EN_VULTM2:
- if (_enemy[EN_VULTM2].occurences <= 1) {
- turnBen(false);
- prepareScenePropScene(18, 0, 1);
- _battleScene = false;
- } else
- turnBen(true);
- break;
- case EN_TORQUE:
- turnBen(false);
- writeArray(1, _posFatherTorque);
- smush_setToFinish();
- break;
- case EN_ROTT1:
- case EN_VULTM1:
- case EN_CAVEFISH:
- default:
- turnBen(true);
- break;
- }
- } else {
- switch (_currEnemy) {
- case EN_VULTM2:
- if (_enemy[EN_VULTM2].occurences <= 1)
- turnBen(false);
- else
- turnBen(true);
- break;
- case EN_TORQUE:
- turnBen(false);
- if (_actor[1].y != 300)
- prepareScenePropScene(57, 1, 0);
- break;
- default:
- turnBen(true);
- }
- _actor[1].y -= (_actor[1].y - 200) / 20 + 1;
- }
-
- turnEnemy(false);
-
- if (curFrame == 0)
- smlayer_setFluPalette(_smush_roadrashRip, 0);
-
- if (curFrame >= maxFrame)
- smush_rewindCurrentSan(1088, -1, -1);
-
- _roadBranch = false;
- _roadStop = false;
- _continueFrame = curFrame;
-}
-
-void Insane::postCase23(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame) {
- if (_currSceneId == 24) {
- queueSceneSwitch(21, 0, "rottfite.san", 64, 0, 0, 0);
- } else {
- if (readArray(6) && readArray(4))
- queueSceneSwitch(16, 0, "limocrsh.san", 64, 0, 0, 0);
- else
- queueSceneSwitch(5, 0, "tovista2.san", 64, 0, 0, 290);
- }
- }
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCase14(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (curFrame >= maxFrame) {
- if (_currSceneId == 16) {
- writeArray(4, 0);
- writeArray(5, 1);
- writeArray(1, _posBrokenCar);
- writeArray(3, _posBrokenTruck);
- smush_setToFinish();
- } else {
- switch (_tempSceneId) {
- case 5:
- queueSceneSwitch(6, 0, "toranch.san", 64, 0, 0, 530);
- break;
- case 6:
- queueSceneSwitch(4, 0, "tovista1.san", 64, 0, 0, 230);
- break;
- }
- }
- }
-
- _roadBranch = false;
- _roadStop = false;
-}
-
-void Insane::postCaseAll(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- struct sceneProp *tsceneProp;
-
- tsceneProp = &_sceneProp[_currScenePropIdx + _currScenePropSubIdx];
- if (tsceneProp->actor != -1) {
- if (_actor[tsceneProp->actor].field_54) {
- tsceneProp->counter++;
- if (!_actor[tsceneProp->actor].runningSound || ConfMan.getBool("subtitles")) {
- if (_actor[tsceneProp->actor].act[3].state == 72 &&
- _currTrsMsg) {
- _player->setPaletteValue(0, tsceneProp->r, tsceneProp->g, tsceneProp->b);
- _player->setPaletteValue(1, tsceneProp->r, tsceneProp->g, tsceneProp->b);
- _player->setPaletteValue(0, 0, 0, 0);
- smlayer_showStatusMsg(-1, renderBitmap, codecparam, 160, 20, 1, 2, 5,
- "^f00%s", _currTrsMsg);
- }
- }
- } else {
- _currScenePropSubIdx = tsceneProp->index;
- if (_currScenePropSubIdx && _currScenePropIdx) {
- tsceneProp = &_sceneProp[_currScenePropIdx + _currScenePropSubIdx];
- tsceneProp->counter = 0;
- if (tsceneProp->trsId)
- _currTrsMsg = handleTrsTag(tsceneProp->trsId);
- else
- _currTrsMsg = 0;
-
- if (tsceneProp->actor != -1) {
- _actor[tsceneProp->actor].field_54 = 1;
- _actor[tsceneProp->actor].act[3].state = 117;
- _actor[tsceneProp->actor].scenePropSubIdx = _currScenePropSubIdx;
- }
- } else {
- _currScenePropIdx = 0;
- _currTrsMsg = 0;
- _currScenePropSubIdx = 0;
- _actor[0].defunct = 0;
- _actor[1].defunct = 0;
- _battleScene = true;
- }
- }
- }
- _roadBranch = false;
- _roadStop = false;
- _continueFrame = curFrame;
-}
-
-void Insane::postCaseMore(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, int32 curFrame, int32 maxFrame) {
- if (_actor[0].weapon <= 7) {
- smlayer_drawSomething(renderBitmap, codecparam, 5, 160, 1, _smush_iconsNut,
- _actor[0].weapon + 11, 0, 0);
- }
-}
-
-}
-
diff --git a/scumm/instrument.cpp b/scumm/instrument.cpp
deleted file mode 100644
index 6e688d89e5..0000000000
--- a/scumm/instrument.cpp
+++ /dev/null
@@ -1,462 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/saveload.h"
-#include "scumm/instrument.h"
-#include "sound/mididrv.h"
-
-namespace Scumm {
-
-static bool _native_mt32 = false;
-
-static struct {
- const char *name;
- byte program;
-}
-
-roland_to_gm_map [] = {
- // Monkey Island 2 instruments
- // TODO: Complete
- { "badspit ", 62 },
- { "Big Drum ", 116 },
- { "burp ", 58 },
-// { "dinkfall ", ??? },
-// { "Fire Pit ", ??? },
- { "foghorn ", 60 },
- { "glop ", 39 },
-// { "jacob's la", ??? },
- { "LeshBass ", 33 },
-// { "lowsnort ", ??? },
- { "ML explosn", 127 },
- { "ReggaeBass", 32 },
-// { "rope fall ", ??? },
- { "rumble ", 89 },
- { "SdTrk Bend", 97 },
-// { "snort ", ??? },
- { "spitting ", 62 },
- { "Swell 1 ", 95 },
- { "Swell 2 ", 95 },
- { "thnderclap", 127 }
-
- // Fate of Atlantis instruments
- // TODO: Build
-// { "*aah! ", ??? },
-// { "*ooh! ", ??? },
-// { "*ShotFar4 ", ??? },
-// { "*splash3 ", ??? },
-// { "*torpedo5 ", ??? },
-// { "*whip3 ", ??? },
-// { "*woodknock", ??? },
-// { "35 lavabub", ??? },
-// { "49 bzzt! ", ??? },
-// { "applause ", ??? },
-// { "Arabongo ", ??? },
-// { "Big Drum ", ??? }, // DUPLICATE (todo: confirm)
-// { "bodythud1 ", ??? },
-// { "boneKLOK2 ", ??? },
-// { "boom10 ", ??? },
-// { "boom11 ", ??? },
-// { "boom15 ", ??? },
-// { "boxclik1a ", ??? },
-// { "brassbonk3", ??? },
-// { "carstart ", ??? },
-// { "cb tpt 2 ", ??? },
-// { "cell door ", ??? },
-// { "chains ", ??? },
-// { "crash ", ??? },
-// { "crsrt/idl3", ??? },
-// { "Fire Pit ", ??? }, // DUPLICATE (todo: confirm)
-// { "Fzooom ", ??? },
-// { "Fzooom 2 ", ??? },
-// { "ghostwhosh", ??? },
-// { "glasssmash", ??? },
-// { "gloop2 ", ??? },
-// { "gunShotNea", ??? },
-// { "idoorclse ", ??? },
-// { "knife ", ??? },
-// { "lavacmbl4 ", ??? },
-// { "Mellow Str", ??? },
-// { "mtlheater1", ??? },
-// { "pachinko5 ", ??? },
-// { "Ping1 ", ??? },
-// { "rockcrunch", ??? },
-// { "rumble ", ??? }, // DUPLICATE (todo: confirm)
-// { "runngwatr ", ??? },
-// { "scrape2 ", ??? },
-// { "snakeHiss ", ??? },
-// { "snort ", ??? }, // DUPLICATE (todo: confirm)
-// { "spindle4 ", ??? },
-// { "splash2 ", ??? },
-// { "squirel ", ??? },
-// { "steam3 ", ??? },
-// { "stonwheel6", ??? },
-// { "street ", ??? },
-// { "trickle4 ", ??? }
-};
-
-const byte Instrument::_gmRhythmMap[35] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 39, 40, 41, 66, 47,
- 65, 48, 56};
- // This emulates the percussion bank setup LEC used with the MT-32,
- // where notes 24 - 34 were assigned instruments without reverb.
- // It also fixes problems on GS devices that map sounds to these
- // notes by default.
-
-class Instrument_Program : public InstrumentInternal {
-private:
- byte _program;
- bool _mt32;
-
-public:
- Instrument_Program (byte program, bool mt32);
- Instrument_Program (Serializer *s);
- void saveOrLoad (Serializer *s);
- void send (MidiChannel *mc);
- void copy_to (Instrument *dest) { dest->program (_program, _mt32); }
- bool is_valid() {
- return (_program < 128) &&
- ((_native_mt32 == _mt32) || _native_mt32
- ? (MidiDriver::_gmToMt32[_program] < 128)
- : (MidiDriver::_mt32ToGm[_program] < 128)); }
-};
-
-class Instrument_Adlib : public InstrumentInternal {
-private:
- struct {
- byte flags_1;
- byte oplvl_1;
- byte atdec_1;
- byte sustrel_1;
- byte waveform_1;
- byte flags_2;
- byte oplvl_2;
- byte atdec_2;
- byte sustrel_2;
- byte waveform_2;
- byte feedback;
- byte flags_a;
- struct { byte a,b,c,d,e,f,g,h; } extra_a;
- byte flags_b;
- struct { byte a,b,c,d,e,f,g,h; } extra_b;
- byte duration;
- } _instrument;
-
-public:
- Instrument_Adlib (byte *data);
- Instrument_Adlib (Serializer *s);
- void saveOrLoad (Serializer *s);
- void send (MidiChannel *mc);
- void copy_to (Instrument *dest) { dest->adlib ((byte *) &_instrument); }
- bool is_valid() { return true; }
-};
-
-class Instrument_Roland : public InstrumentInternal {
-private:
- struct RolandInstrument {
- byte roland_id;
- byte device_id;
- byte model_id;
- byte command;
- byte address[3];
- struct {
- byte name[10];
- byte partial_struct12;
- byte partial_struct34;
- byte partial_mute;
- byte env_mode;
- } common;
- struct {
- byte wg_pitch_coarse;
- byte wg_pitch_fine;
- byte wg_pitch_keyfollow;
- byte wg_pitch_bender_sw;
- byte wg_waveform_pcm_bank;
- byte wg_pcm_wave_num;
- byte wg_pulse_width;
- byte wg_pw_velo_sens;
- byte p_env_depth;
- byte p_evn_velo_sens;
- byte p_env_time_keyf;
- byte p_env_time[4];
- byte p_env_level[3];
- byte p_env_sustain_level;
- byte end_level;
- byte p_lfo_rate;
- byte p_lfo_depth;
- byte p_lfo_mod_sens;
- byte tvf_cutoff_freq;
- byte tvf_resonance;
- byte tvf_keyfollow;
- byte tvf_bias_point_dir;
- byte tvf_bias_level;
- byte tvf_env_depth;
- byte tvf_env_velo_sens;
- byte tvf_env_depth_keyf;
- byte tvf_env_time_keyf;
- byte tvf_env_time[5];
- byte tvf_env_level[3];
- byte tvf_env_sustain_level;
- byte tva_level;
- byte tva_velo_sens;
- byte tva_bias_point_1;
- byte tva_bias_level_1;
- byte tva_bias_point_2;
- byte tva_bias_level_2;
- byte tva_env_time_keyf;
- byte tva_env_time_v_follow;
- byte tva_env_time[5];
- byte tva_env_level[3];
- byte tva_env_sustain_level;
- } partial[4];
- byte checksum;
- } GNUPACK;
- RolandInstrument _instrument;
-
- char _instrument_name [11];
-
- uint8 getEquivalentGM();
-
-public:
- Instrument_Roland (byte *data);
- Instrument_Roland (Serializer *s);
- void saveOrLoad (Serializer *s);
- void send (MidiChannel *mc);
- void copy_to (Instrument *dest) { dest->roland ((byte *) &_instrument); }
- bool is_valid() { return (_native_mt32 ? true : (_instrument_name[0] != '\0')); }
-};
-
-////////////////////////////////////////
-//
-// Instrument class members
-//
-////////////////////////////////////////
-
-void Instrument::nativeMT32 (bool native) {
- _native_mt32 = native;
-}
-
-void Instrument::clear() {
- if (_instrument)
- delete _instrument;
- _instrument = NULL;
- _type = itNone;
-}
-
-void Instrument::program (byte prog, bool mt32) {
- clear();
- if (prog > 127)
- return;
- _type = itProgram;
- _instrument = new Instrument_Program (prog, mt32);
-}
-
-void Instrument::adlib (byte *instrument) {
- clear();
- if (!instrument)
- return;
- _type = itAdlib;
- _instrument = new Instrument_Adlib (instrument);
-}
-
-void Instrument::roland (byte *instrument) {
- clear();
- if (!instrument)
- return;
- _type = itRoland;
- _instrument = new Instrument_Roland (instrument);
-}
-
-void Instrument::saveOrLoad (Serializer *s) {
- if (s->isSaving()) {
- s->saveByte (_type);
- if (_instrument)
- _instrument->saveOrLoad (s);
- } else {
- clear();
- _type = s->loadByte();
- switch (_type) {
- case itNone:
- break;
- case itProgram:
- _instrument = new Instrument_Program (s);
- break;
- case itAdlib:
- _instrument = new Instrument_Adlib (s);
- break;
- case itRoland:
- _instrument = new Instrument_Roland (s);
- break;
- default:
- warning ("No known instrument classification #%d", (int) _type);
- _type = itNone;
- }
- }
-}
-
-////////////////////////////////////////
-//
-// Instrument_Program class members
-//
-////////////////////////////////////////
-
-Instrument_Program::Instrument_Program (byte program, bool mt32) :
-_program (program),
-_mt32 (mt32) {
- if (program > 127)
- _program = 255;
-}
-
-Instrument_Program::Instrument_Program (Serializer *s) {
- _program = 255;
- if (!s->isSaving())
- saveOrLoad (s);
-}
-
-void Instrument_Program::saveOrLoad (Serializer *s) {
- if (s->isSaving()) {
- s->saveByte (_program);
- s->saveByte (_mt32 ? 1 : 0);
- } else {
- _program = s->loadByte();
- _mt32 = (s->loadByte() > 0);
- }
-}
-
-void Instrument_Program::send (MidiChannel *mc) {
- if (_program > 127)
- return;
-
- byte program = _program;
- if (_native_mt32 != _mt32)
- program = _native_mt32 ? MidiDriver::_gmToMt32 [program] : MidiDriver::_mt32ToGm [program];
- if (program < 128)
- mc->programChange (program);
-}
-
-////////////////////////////////////////
-//
-// Instrument_Adlib class members
-//
-////////////////////////////////////////
-
-Instrument_Adlib::Instrument_Adlib (byte *data) {
- memcpy (&_instrument, data, sizeof (_instrument));
-}
-
-Instrument_Adlib::Instrument_Adlib (Serializer *s) {
- if (!s->isSaving())
- saveOrLoad (s);
- else
- memset (&_instrument, 0, sizeof (_instrument));
-}
-
-void Instrument_Adlib::saveOrLoad (Serializer *s) {
- if (s->isSaving())
- s->saveBytes (&_instrument, sizeof (_instrument));
- else
- s->loadBytes (&_instrument, sizeof (_instrument));
-}
-
-void Instrument_Adlib::send (MidiChannel *mc) {
- mc->sysEx_customInstrument ('ADL ', (byte *) &_instrument);
-}
-
-////////////////////////////////////////
-//
-// Instrument_Roland class members
-//
-////////////////////////////////////////
-
-Instrument_Roland::Instrument_Roland (byte *data) {
- memcpy (&_instrument, data, sizeof (_instrument));
- memcpy (&_instrument_name, &_instrument.common.name, sizeof (_instrument.common.name));
- _instrument_name[10] = '\0';
- if (!_native_mt32 && getEquivalentGM() >= 128) {
- debug (0, "MT-32 instrument \"%s\" not supported yet", _instrument_name);
- _instrument_name[0] = '\0';
- }
-}
-
-Instrument_Roland::Instrument_Roland (Serializer *s) {
- _instrument_name[0] = '\0';
- if (!s->isSaving())
- saveOrLoad (s);
- else
- memset (&_instrument, 0, sizeof (_instrument));
-}
-
-void Instrument_Roland::saveOrLoad (Serializer *s) {
- if (s->isSaving()) {
- s->saveBytes (&_instrument, sizeof (_instrument));
- } else {
- s->loadBytes (&_instrument, sizeof (_instrument));
- memcpy (&_instrument_name, &_instrument.common.name, sizeof (_instrument.common.name));
- _instrument_name[10] = '\0';
- if (!_native_mt32 && getEquivalentGM() >= 128) {
- debug (2, "MT-32 custom instrument \"%s\" not supported", _instrument_name);
- _instrument_name[0] = '\0';
- }
- } // end if
-}
-
-void Instrument_Roland::send (MidiChannel *mc) {
- if (_native_mt32) {
- if (mc->getNumber() > 8)
- return;
- _instrument.device_id = mc->getNumber();
-
- // Remap instrument to appropriate address space.
- int address = 0x008000;
- _instrument.address[0] = (address >> 14) & 0x7F;
- _instrument.address[1] = (address >> 7) & 0x7F;
- _instrument.address[2] = (address ) & 0x7F;
-
- // Recompute the checksum.
- byte checksum = 0;
- byte *ptr = (byte *) &_instrument + 4;
- int i;
- for (i = 4; i < (int)sizeof (_instrument) - 1; ++i)
- checksum -= *ptr++;
- _instrument.checksum = checksum & 0x7F;
-
- mc->device()->sysEx ((byte *) &_instrument, sizeof (_instrument));
- } else {
- // Convert to a GM program change.
- byte program = getEquivalentGM();
- if (program < 128)
- mc->programChange (program);
- }
-}
-
-uint8 Instrument_Roland::getEquivalentGM() {
- byte i;
- for (i = 0; i != ARRAYSIZE(roland_to_gm_map); ++i) {
- if (!memcmp (roland_to_gm_map[i].name, _instrument.common.name, 10))
- return roland_to_gm_map[i].program;
- }
- return 255;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/instrument.h b/scumm/instrument.h
deleted file mode 100644
index eb1a30a1d1..0000000000
--- a/scumm/instrument.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef INSTRUMENT_H
-#define INSTRUMENT_H
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-
-class MidiChannel;
-
-namespace Scumm {
-
-class Serializer;
-class Instrument;
-
-class InstrumentInternal {
-public:
- virtual ~InstrumentInternal() {}
- virtual void saveOrLoad (Serializer *s) = 0;
- virtual void send (MidiChannel *mc) = 0;
- virtual void copy_to (Instrument *dest) = 0;
- virtual bool is_valid() = 0;
- virtual operator int() { return 255; }
-};
-
-class Instrument {
-private:
- byte _type;
- InstrumentInternal *_instrument;
-
-public:
- enum {
- itNone = 0,
- itProgram = 1,
- itAdlib = 2,
- itRoland = 3
- };
-
- Instrument() : _type (0), _instrument (0) { }
- ~Instrument() { delete _instrument; }
- static void nativeMT32 (bool native);
- static const byte _gmRhythmMap[35];
-
- void clear();
- void copy_to (Instrument *dest) { if (_instrument) _instrument->copy_to (dest); else dest->clear(); }
-
- void program (byte program, bool mt32);
- void adlib (byte *instrument);
- void roland (byte *instrument);
-
- byte getType() { return _type; }
- bool isValid() { return (_instrument ? _instrument->is_valid() : false); }
- void saveOrLoad (Serializer *s);
- void send (MidiChannel *mc) { if (_instrument) _instrument->send (mc); }
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/intern.h b/scumm/intern.h
deleted file mode 100644
index fae915a037..0000000000
--- a/scumm/intern.h
+++ /dev/null
@@ -1,912 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCUMM_INTERN_H
-#define SCUMM_INTERN_H
-
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-// This is to help devices with small memory (PDA, smartphones, ...)
-// to save abit of memory used by opcode names in the Scumm engine.
-#ifndef REDUCE_MEMORY_USAGE
-# define _OPCODE(ver, x) { &ver::x, #x }
-#else
-# define _OPCODE(ver, x) { &ver::x, "" }
-#endif
-
-class ScummEngine_v5 : public ScummEngine {
-protected:
- typedef void (ScummEngine_v5::*OpcodeProcV5)();
- struct OpcodeEntryV5 {
- OpcodeProcV5 proc;
- const char *desc;
- };
-
- const OpcodeEntryV5 *_opcodesV5;
-
- uint16 _cursorImages[4][17];
- byte _cursorHotspots[2 * 4];
-
-public:
- ScummEngine_v5(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void initScummVars();
- virtual void decodeParseString();
-
- virtual void saveOrLoad(Serializer *s);
-
- virtual void readMAXS(int blockSize);
-
- int getWordVararg(int *ptr);
- void saveVars();
- void loadVars();
-
- virtual int getVar();
- virtual int getVarOrDirectByte(byte mask);
- virtual int getVarOrDirectWord(byte mask);
-
- virtual void animateCursor();
-
- void setBuiltinCursor(int index);
- void redefineBuiltinCursorFromChar(int index, int chr);
- void redefineBuiltinCursorHotspot(int index, int x, int y);
-
- /* Version 5 script opcodes */
- void o5_actorFollowCamera();
- void o5_actorFromPos();
- void o5_actorOps();
- void o5_add();
- void o5_and();
- void o5_animateActor();
- void o5_breakHere();
- void o5_chainScript();
- void o5_cursorCommand();
- void o5_cutscene();
- void o5_debug();
- void o5_decrement();
- void o5_delay();
- void o5_delayVariable();
- void o5_divide();
- void o5_doSentence();
- void o5_drawBox();
- void o5_drawObject();
- void o5_endCutscene();
- void o5_equalZero();
- void o5_expression();
- void o5_faceActor();
- void o5_findInventory();
- void o5_findObject();
- void o5_freezeScripts();
- void o5_getActorCostume();
- void o5_getActorElevation();
- void o5_getActorFacing();
- void o5_getActorMoving();
- void o5_getActorRoom();
- void o5_getActorScale();
- void o5_getActorWalkBox();
- void o5_getActorWidth();
- void o5_getActorX();
- void o5_getActorY();
- void o5_getAnimCounter();
- void o5_getClosestObjActor();
- void o5_getDist();
- void o5_getInventoryCount();
- void o5_getObjectOwner();
- void o5_getObjectState();
- void o5_getRandomNr();
- void o5_getStringWidth();
- void o5_getVerbEntrypoint();
- void o5_ifClassOfIs();
- void o5_ifNotState();
- void o5_ifState();
- void o5_increment();
- void o5_isActorInBox();
- void o5_isEqual();
- void o5_isGreater();
- void o5_isGreaterEqual();
- void o5_isLess();
- void o5_isNotEqual();
- void o5_isScriptRunning();
- void o5_isSoundRunning();
- void o5_jumpRelative();
- void o5_lessOrEqual();
- void o5_lights();
- void o5_loadRoom();
- void o5_loadRoomWithEgo();
- void o5_matrixOps();
- void o5_move();
- void o5_multiply();
- void o5_notEqualZero();
- void o5_oldRoomEffect();
- void o5_or();
- void o5_beginOverride();
- void o5_panCameraTo();
- void o5_pickupObject();
- void o5_pickupObjectOld();
- void o5_print();
- void o5_printEgo();
- void o5_pseudoRoom();
- void o5_putActor();
- void o5_putActorAtObject();
- void o5_putActorInRoom();
- void o5_systemOps();
- void o5_resourceRoutines();
- void o5_roomOps();
- void o5_saveLoadGame();
- void o5_saveLoadVars();
- void o5_saveRestoreVerbs();
- void o5_setCameraAt();
- void o5_setClass();
- void o5_setObjectName();
- void o5_setOwnerOf();
- void o5_setState();
- void o5_setVarRange();
- void o5_soundKludge();
- void o5_startMusic();
- void o5_startObject();
- void o5_startScript();
- void o5_startSound();
- void o5_stopMusic();
- void o5_stopObjectCode();
- void o5_stopObjectScript();
- void o5_stopScript();
- void o5_stopSound();
- void o5_stringOps();
- void o5_subtract();
- void o5_verbOps();
- void o5_wait();
- void o5_walkActorTo();
- void o5_walkActorToActor();
- void o5_walkActorToObject();
-};
-
-/**
- * Engine for version 4 SCUMM games; GF_SMALL_HEADER is always set for these.
- */
-class ScummEngine_v4 : public ScummEngine_v5 {
-public:
- ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
-protected:
- virtual void readIndexFile();
- virtual void loadCharset(int no);
- virtual void loadRoomObjects();
- virtual void readMAXS(int blockSize);
- virtual void readGlobalObjects();
-
- virtual void setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
-};
-
-/**
- * Engine for version 3 SCUMM games; GF_SMALL_NAMES is always set for these.
- */
-class ScummEngine_v3 : public ScummEngine_v4 {
-public:
- ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
-protected:
- virtual void readRoomsOffsets();
- virtual void loadCharset(int no);
-};
-
-/**
- * Engine for old format version 3 SCUMM games; GF_OLD_BUNDLE is always set for these.
- */
-class ScummEngine_v3old : public ScummEngine_v3 {
-public:
- ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
-protected:
- virtual void readResTypeList(int id, uint32 tag, const char *name);
- virtual void readIndexFile();
- virtual void loadRoomSubBlocks();
- virtual void initRoomSubBlocks();
- virtual void loadRoomObjects();
-};
-
-/**
- * Engine for version 2 SCUMM games.
- */
-class ScummEngine_v2 : public ScummEngine_v3old {
-protected:
- typedef void (ScummEngine_v2::*OpcodeProcV2)();
- struct OpcodeEntryV2 {
- OpcodeProcV2 proc;
- const char *desc;
- };
-
- const OpcodeEntryV2 *_opcodesV2;
-
- struct V2MouseoverBox {
- Common::Rect rect;
- byte color;
- byte hicolor;
- };
-
- V2MouseoverBox _mouseOverBoxesV2[7];
- int8 _mouseOverBoxV2;
-
-public:
- ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
- virtual void scummInit();
-
- void checkV2MouseOver(Common::Point pos);
- void checkV2Inventory(int x, int y);
- void redrawV2Inventory();
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void initScummVars();
- virtual void decodeParseString();
-
- virtual void readIndexFile();
- void readClassicIndexFile(); // V1
- void readEnhancedIndexFile(); // V2
- virtual void readGlobalObjects();
- virtual void loadCharset(int no);
-
- virtual void runInventoryScript(int i);
-
- virtual int getVar();
-
- void getResultPosIndirect();
- virtual void getResultPos();
- virtual int readVar(uint var);
- virtual void writeVar(uint var, int value);
-
- virtual void ifStateCommon(byte type);
- virtual void ifNotStateCommon(byte type);
- virtual void setStateCommon(byte type);
- virtual void clearStateCommon(byte type);
-
- void resetSentence();
- void setUserState(byte state);
-
- virtual void handleMouseOver(bool updateInventory);
- void initV2MouseOver();
- void initNESMouseOver();
-
- /* Version 2 script opcodes */
- void o2_actorFromPos();
- void o2_actorOps();
- void o2_add();
- void o2_addIndirect();
- void o2_animateActor();
- void o2_assignVarByte();
- void o2_assignVarWordIndirect();
- void o2_beginOverride();
- void o2_chainScript();
- void o2_clearState01();
- void o2_clearState02();
- void o2_clearState04();
- void o2_clearState08();
- void o2_cursorCommand();
- void o2_cutscene();
- void o2_delay();
- void o2_doSentence();
- void o2_drawObject();
- void o2_drawSentence();
- void o2_dummy();
- void o2_endCutscene();
- void o2_findObject();
- void o2_getActorWalkBox();
- void o2_getActorX();
- void o2_getActorY();
- void o2_getBitVar();
- void o2_getObjPreposition();
- void o2_ifClassOfIs();
- void o2_ifNotState01();
- void o2_ifNotState02();
- void o2_ifNotState04();
- void o2_ifNotState08();
- void o2_ifState01();
- void o2_ifState02();
- void o2_ifState04();
- void o2_ifState08();
- void o2_isGreater();
- void o2_isGreaterEqual();
- void o2_isLess();
- void o2_isLessEqual();
- void o2_lights();
- void o2_loadRoomWithEgo();
- void o2_setBoxFlags();
- void o2_panCameraTo();
- void o2_pickupObject();
- void o2_putActor();
- void o2_putActorAtObject();
- void o2_resourceRoutines();
- void o2_restart();
- void o2_roomOps();
- void o2_getActorElevation();
- void o2_setActorElevation();
- void o2_setBitVar();
- void o2_setCameraAt();
- void o2_setObjPreposition();
- void o2_setOwnerOf();
- void o2_setState01();
- void o2_setState02();
- void o2_setState04();
- void o2_setState08();
- void o2_startScript();
- void o2_stopScript();
- void o2_subtract();
- void o2_subIndirect();
- void o2_switchCostumeSet();
- void o2_verbOps();
- void o2_waitForActor();
- void o2_waitForMessage();
- void o2_waitForSentence();
- void o2_walkActorTo();
- void o2_walkActorToObject();
-
- byte VAR_SENTENCE_VERB;
- byte VAR_SENTENCE_OBJECT1;
- byte VAR_SENTENCE_OBJECT2;
- byte VAR_SENTENCE_PREPOSITION;
- byte VAR_BACKUP_VERB;
-};
-
-/**
- * Engine for Commodore 64 version of Maniac Mansion
- */
-class ScummEngine_c64 : public ScummEngine_v2 {
-protected:
- typedef void (ScummEngine_c64::*OpcodeProcC64)();
- struct OpcodeEntryC64 {
- OpcodeProcC64 proc;
- const char *desc;
- };
-
- const OpcodeEntryC64 *_opcodesC64;
-
- int _currentAction;
- int _currentMode;
-public:
- ScummEngine_c64(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
- virtual void scummInit();
-
-protected:
- virtual void setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
-
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void decodeParseString();
-
- void initC64Verbs();
- virtual void checkExecVerbs();
-
- virtual int getVarOrDirectWord(byte mask);
- virtual uint fetchScriptWord();
-
- virtual void ifStateCommon(byte type);
- virtual void ifNotStateCommon(byte type);
- virtual void setStateCommon(byte type);
- virtual void clearStateCommon(byte type);
-
- int getObjectFlag();
-
- /* Version C64 script opcodes */
- void o_setState08();
- void o_clearState08();
- void o_stopCurrentScript();
- void o_loadSound();
- void o_getActorMoving();
- void o_animateActor();
- void o_putActorAtObject();
- void o_lockSound();
- void o_lockActor();
- void o_loadActor();
- void o_loadRoom();
- void o_loadRoomWithEgo();
- void o_lockScript();
- void o_loadScript();
- void o_lockRoom();
- void o_cursorCommand();
- void o_lights();
- void o_pickupObject();
- void o_unlockActor();
- void o_unlockScript();
- void o_decrement();
- void o_badOpcode();
- void o_nop();
- void o_getActorBitVar();
- void o_setActorBitVar();
- void o_doSentence();
- void o_unknown2();
- void o_unknown3();
- void o_getClosestObjActor();
- void o_printEgo_c64();
- void o_print_c64();
- void o_unlockRoom();
- void o_unlockSound();
- void o_beginOverride();
- void o_isEqual();
- void o_isGreater();
- void o_isGreaterEqual();
- void o_isLess();
- void o_isLessEqual();
- void o_isNotEqual();
- void o_notEqualZero();
- void o_equalZero();
- void o_jumpRelative();
-};
-
-class ScummEngine_v6 : public ScummEngine {
- friend class Insane;
-
-protected:
- typedef void (ScummEngine_v6::*OpcodeProcV6)();
- struct OpcodeEntryV6 {
- OpcodeProcV6 proc;
- const char *desc;
- };
-
- enum ArrayType {
- kBitArray = 1,
- kNibbleArray = 2,
- kByteArray = 3,
- kStringArray = 4,
- kIntArray = 5,
- kDwordArray = 6
- };
-
- #if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
- #endif
-
- struct ArrayHeader {
- int16 dim1;
- int16 type;
- int16 dim2;
- byte data[1];
- } GCC_PACK;
-
- #if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
- #endif
-
- const OpcodeEntryV6 *_opcodesV6;
-
- int _smushFrameRate;
-
- struct TextObject {
- int16 xpos, ypos;
- byte color;
- byte charset;
- byte text[256];
- };
-
- /** BlastObjects to draw */
- struct BlastObject {
- uint16 number;
- Common::Rect rect;
- uint16 scaleX, scaleY;
- uint16 image;
- uint16 mode;
- };
-
- int _blastObjectQueuePos;
- BlastObject _blastObjectQueue[200];
-
- struct BlastText : TextObject {
- Common::Rect rect;
- bool center;
- };
-
- int _blastTextQueuePos;
- BlastText _blastTextQueue[50];
-
-
-public:
- ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
- virtual void scummInit();
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void decodeParseString(int a, int b);
- virtual void readArrayFromIndexFile();
-
- virtual byte *getStringAddress(int i);
- virtual void readMAXS(int blockSize);
-
- virtual void palManipulateInit(int resID, int start, int end, int time);
- virtual void drawDirtyScreenParts();
-
- int getStackList(int *args, uint maxnum);
- int popRoomAndObj(int *room);
-
- ArrayHeader *getArray(int array);
- ArrayHeader *defineArray(int array, int type, int dim2, int dim1);
- int findFreeArrayId();
- void nukeArray(int array);
- virtual int readArray(int array, int index, int base);
- virtual void writeArray(int array, int index, int base, int value);
- void shuffleArray(int num, int minIdx, int maxIdx);
-
- void setDefaultCursor();
- void setCursorTransparency(int a);
- void setCursorHotspot(int x, int y);
-
- virtual void setCursorFromImg(uint img, uint room, uint imgindex);
- void useIm01Cursor(const byte *im, int w, int h);
- void useBompCursor(const byte *im, int w, int h);
- void grabCursor(int x, int y, int w, int h);
-
- void enqueueText(const byte *text, int x, int y, byte color, byte charset, bool center);
- void drawBlastTexts();
- void removeBlastTexts();
-
- void enqueueObject(int objectNumber, int objectX, int objectY, int objectWidth,
- int objectHeight, int scaleX, int scaleY, int image, int mode);
- void drawBlastObjects();
- void drawBlastObject(BlastObject *eo);
- void removeBlastObjects();
- void removeBlastObject(BlastObject *eo);
-
- virtual void clearDrawQueues();
-
-
- /* Version 6 script opcodes */
- void o6_setBlastObjectWindow();
- void o6_pushByte();
- void o6_pushWord();
- void o6_pushByteVar();
- void o6_pushWordVar();
- void o6_invalid();
- void o6_byteArrayRead();
- void o6_wordArrayRead();
- void o6_byteArrayIndexedRead();
- void o6_wordArrayIndexedRead();
- void o6_dup();
- void o6_pop();
- void o6_not();
- void o6_eq();
- void o6_neq();
- void o6_gt();
- void o6_lt();
- void o6_le();
- void o6_ge();
- void o6_add();
- void o6_sub();
- void o6_mul();
- void o6_div();
- void o6_land();
- void o6_lor();
- void o6_writeByteVar();
- void o6_writeWordVar();
- void o6_byteArrayWrite();
- void o6_wordArrayWrite();
- void o6_byteArrayIndexedWrite();
- void o6_wordArrayIndexedWrite();
- void o6_byteVarInc();
- void o6_wordVarInc();
- void o6_byteArrayInc();
- void o6_wordArrayInc();
- void o6_byteVarDec();
- void o6_wordVarDec();
- void o6_byteArrayDec();
- void o6_wordArrayDec();
- void o6_if();
- void o6_ifNot();
- void o6_jump();
- void o6_startScript();
- void o6_startScriptQuick();
- void o6_startObject();
- void o6_drawObject();
- void o6_drawObjectAt();
- void o6_stopObjectCode();
- void o6_endCutscene();
- void o6_cutscene();
- void o6_stopMusic();
- void o6_freezeUnfreeze();
- void o6_cursorCommand();
- void o6_breakHere();
- void o6_ifClassOfIs();
- void o6_setClass();
- void o6_getState();
- void o6_setState();
- void o6_setOwner();
- void o6_getOwner();
- void o6_startSound();
- void o6_stopSound();
- void o6_startMusic();
- void o6_stopObjectScript();
- void o6_panCameraTo();
- void o6_actorFollowCamera();
- void o6_setCameraAt();
- void o6_loadRoom();
- void o6_stopScript();
- void o6_walkActorToObj();
- void o6_walkActorTo();
- void o6_putActorAtXY();
- void o6_putActorAtObject();
- void o6_faceActor();
- void o6_animateActor();
- void o6_doSentence();
- void o6_pickupObject();
- void o6_loadRoomWithEgo();
- void o6_getRandomNumber();
- void o6_getRandomNumberRange();
- void o6_getActorMoving();
- void o6_isScriptRunning();
- void o6_getActorRoom();
- void o6_getObjectX();
- void o6_getObjectY();
- void o6_getObjectOldDir();
- void o6_getObjectNewDir();
- void o6_getActorWalkBox();
- void o6_getActorCostume();
- void o6_findInventory();
- void o6_getInventoryCount();
- void o6_getVerbFromXY();
- void o6_beginOverride();
- void o6_endOverride();
- void o6_setObjectName();
- void o6_isSoundRunning();
- void o6_setBoxFlags();
- void o6_createBoxMatrix();
- void o6_resourceRoutines();
- void o6_roomOps();
- void o6_actorOps();
- void o6_verbOps();
- void o6_getActorFromXY();
- void o6_findObject();
- void o6_pseudoRoom();
- void o6_getActorElevation();
- void o6_getVerbEntrypoint();
- void o6_arrayOps();
- void o6_saveRestoreVerbs();
- void o6_drawBox();
- void o6_getActorWidth();
- void o6_wait();
- void o6_getActorScaleX();
- void o6_getActorAnimCounter1();
- void o6_soundKludge();
- void o6_isAnyOf();
- void o6_systemOps();
- void o6_isActorInBox();
- void o6_delay();
- void o6_delaySeconds();
- void o6_delayMinutes();
- void o6_stopSentence();
- void o6_printLine();
- void o6_printText();
- void o6_printDebug();
- void o6_printSystem();
- void o6_printActor();
- void o6_printEgo();
- void o6_talkActor();
- void o6_talkEgo();
- void o6_dimArray();
- void o6_dummy();
- void o6_startObjectQuick();
- void o6_startScriptQuick2();
- void o6_dim2dimArray();
- void o6_abs();
- void o6_distObjectObject();
- void o6_distObjectPt();
- void o6_distPtPt();
- void o6_kernelSetFunctions();
- void o6_delayFrames();
- void o6_pickOneOf();
- void o6_pickOneOfDefault();
- void o6_jumpToScript();
- void o6_isRoomScriptRunning();
- void o6_kernelGetFunctions();
- void o6_getAnimateVariable();
- void o6_drawBlastObject();
- void o6_getActorLayer();
- void o6_stampObject();
- void o6_bor();
- void o6_band();
- void o6_stopTalking();
- void o6_findAllObjects();
- void o6_pickVarRandom();
- void o6_getDateTime();
- void o6_getPixel();
- void o6_setBoxSet();
- void o6_shuffle();
-
- byte VAR_VIDEONAME;
- byte VAR_RANDOM_NR;
- byte VAR_STRING2DRAW;
-
- byte VAR_TIMEDATE_YEAR;
- byte VAR_TIMEDATE_MONTH;
- byte VAR_TIMEDATE_DAY;
- byte VAR_TIMEDATE_HOUR;
- byte VAR_TIMEDATE_MINUTE;
- byte VAR_TIMEDATE_SECOND;
-};
-
-#ifndef DISABLE_SCUMM_7_8
-class ScummEngine_v7 : public ScummEngine_v6 {
-public:
- ScummEngine_v7(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
- ~ScummEngine_v7();
-
- struct LangIndexNode {
- char tag[12+1];
- int32 offset;
- };
-
- bool _existLanguageFile;
- char *_languageBuffer;
- LangIndexNode *_languageIndex;
- int _languageIndexSize;
- char _lastStringTag[12+1];
-
-#if defined(__SYMBIAN32__) || defined (_WIN32_WCE) // for some reason VC6 cannot find the base class TextObject
- struct SubtitleText {
- int16 xpos, ypos;
- byte color;
- byte charset;
- byte text[256];
- bool actorSpeechMsg;
- };
-#else
- struct SubtitleText : TextObject {
- bool actorSpeechMsg;
- };
-#endif
-
- int _subtitleQueuePos;
- SubtitleText _subtitleQueue[20];
-
- void processSubtitleQueue();
- void addSubtitleToQueue(const byte *text, const Common::Point &pos, byte color, byte charset);
- void clearSubtitleQueue();
-
-protected:
- virtual void setupScummVars();
- virtual void initScummVars();
-
- virtual void akos_processQueue();
-
- virtual void saveOrLoad(Serializer *s);
-
- virtual void readMAXS(int blockSize);
- virtual void readGlobalObjects();
- virtual void readIndexBlock(uint32 blocktype, uint32 itemsize);
-
- virtual void setCameraAt(int pos_x, int pos_y);
- virtual void setCameraFollows(Actor *a);
- virtual void moveCamera();
- virtual void panCameraTo(int x, int y);
-
- virtual int getObjectIdFromOBIM(const byte *obim);
-
- virtual void actorTalk(const byte *msg);
- virtual void translateText(const byte *text, byte *trans_buff);
- virtual void loadLanguageBundle();
- void playSpeech(const byte *ptr);
-
- virtual void drawVerb(int verb, int mode);
-};
-
-class ScummEngine_v8 : public ScummEngine_v7 {
-protected:
- typedef void (ScummEngine_v8::*OpcodeProcV8)();
- struct OpcodeEntryV8 {
- OpcodeProcV8 proc;
- const char *desc;
- };
-
- const OpcodeEntryV8 *_opcodesV8;
-
- struct ObjectNameId {
- char name[40];
- int id;
- };
- int _objectIDMapSize;
- ObjectNameId *_objectIDMap;
-
-public:
- ScummEngine_v8(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
- ~ScummEngine_v8();
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void decodeParseString(int m, int n);
- virtual void readArrayFromIndexFile();
-
- virtual void readMAXS(int blockSize);
- virtual void readGlobalObjects();
-
- virtual uint fetchScriptWord();
- virtual int fetchScriptWordSigned();
-
- virtual int readVar(uint var);
- virtual void writeVar(uint var, int value);
-
- virtual int getObjectIdFromOBIM(const byte *obim);
-
-
- void desaturatePalette(int hueScale, int satScale, int lightScale, int startColor, int endColor);
-
-
- /* Version 8 script opcodes */
- void o8_mod();
- void o8_wait();
-
- void o8_dimArray();
- void o8_dim2dimArray();
- void o8_arrayOps();
- void o8_blastText();
-
- void o8_cursorCommand();
- void o8_resourceRoutines();
- void o8_roomOps();
- void o8_actorOps();
- void o8_cameraOps();
- void o8_verbOps();
-
- void o8_systemOps();
- void o8_startVideo();
- void o8_kernelSetFunctions();
- void o8_kernelGetFunctions();
-
- void o8_getActorChore();
- void o8_getActorZPlane();
-
- void o8_drawObject();
- void o8_getObjectImageX();
- void o8_getObjectImageY();
- void o8_getObjectImageWidth();
- void o8_getObjectImageHeight();
-
- void o8_getStringWidth();
-
-};
-
-#endif
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/intern_he.h b/scumm/intern_he.h
deleted file mode 100644
index 26a9e0a40f..0000000000
--- a/scumm/intern_he.h
+++ /dev/null
@@ -1,606 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCUMM_INTERN_HE_H
-#define SCUMM_INTERN_HE_H
-
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/floodfill_he.h"
-#include "scumm/wiz_he.h"
-#endif
-
-namespace Scumm {
-
-#ifndef DISABLE_HE
-class ResExtractor;
-class LogicHE;
-class Sprite;
-#endif
-
-class ScummEngine_v60he : public ScummEngine_v6 {
-protected:
- typedef void (ScummEngine_v60he::*OpcodeProcv60he)();
- struct OpcodeEntryv60he {
- OpcodeProcv60he proc;
- const char *desc;
- };
-
- const OpcodeEntryv60he *_opcodesv60he;
-
- Common::File _hFileTable[17];
-
-public:
- ScummEngine_v60he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v6(detector, syst, gs, md5sum, substResFileNameIndex) {}
-
- virtual void scummInit();
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void saveOrLoad(Serializer *s);
-
- void localizeArray(int slot, byte scriptSlot);
- void redimArray(int arrayId, int newX, int newY, int d);
- int readFileToArray(int slot, int32 size);
- void writeFileFromArray(int slot, int resID);
- int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2);
- void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2);
- virtual void decodeParseString(int a, int b);
- void swapObjects(int object1, int object2);
-
- /* HE version 60 script opcodes */
- void o60_setState();
- void o60_roomOps();
- void o60_actorOps();
- void o60_wait();
- void o60_kernelSetFunctions();
- void o60_kernelGetFunctions();
- void o60_openFile();
- void o60_closeFile();
- void o60_deleteFile();
- void o60_readFile();
- void o60_rename();
- void o60_writeFile();
- void o60_soundOps();
- void o60_seekFilePos();
- void o60_localizeArrayToScript();
- void o60_redimArray();
- void o60_readFilePos();
-};
-
-#ifndef DISABLE_HE
-class ScummEngine_v70he : public ScummEngine_v60he {
- friend class ResExtractor;
- friend class Wiz;
-
-protected:
- typedef void (ScummEngine_v70he::*OpcodeProcv70he)();
- struct OpcodeEntryv70he {
- OpcodeProcv70he proc;
- const char *desc;
- };
-
- const OpcodeEntryv70he *_opcodesv70he;
-
- ResExtractor *_resExtractor;
-
- byte *_heV7RoomOffsets;
-
- int32 _heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags, _heSndSoundFreq;
-
- bool _skipProcessActors;
-
-public:
- ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
- ~ScummEngine_v70he();
-
- Wiz *_wiz;
-
- byte *heFindResourceData(uint32 tag, byte *ptr);
- byte *heFindResource(uint32 tag, byte *ptr);
- byte *findWrappedBlock(uint32 tag, byte *ptr, int state, bool flagError);
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void initScummVars();
-
- virtual void saveOrLoad(Serializer *s);
-
- virtual void readRoomsOffsets();
- virtual void readGlobalObjects();
- virtual void readIndexBlock(uint32 blocktype, uint32 itemsize);
-
- virtual int getActorFromPos(int x, int y);
-
- int getStringCharWidth(byte chr);
- virtual int setupStringArray(int size);
- void appendSubstring(int dst, int src, int len2, int len);
-
- virtual void setCursorFromImg(uint img, uint room, uint imgindex);
-
- virtual void clearDrawQueues();
-
- void remapHEPalette(const uint8 *src, uint8 *dst);
-
- /* HE version 70 script opcodes */
- void o70_startSound();
- void o70_pickupObject();
- void o70_getActorRoom();
- void o70_resourceRoutines();
- void o70_systemOps();
- void o70_kernelSetFunctions();
- void o70_seekFilePos();
- void o70_copyString();
- void o70_getStringWidth();
- void o70_getStringLen();
- void o70_appendString();
- void o70_concatString();
- void o70_compareString();
- void o70_isResourceLoaded();
- void o70_readINI();
- void o70_writeINI();
- void o70_getStringLenForWidth();
- void o70_getCharIndexInString();
- void o70_setFilePath();
- void o70_setWindowCaption();
- void o70_polygonOps();
- void o70_polygonHit();
-
- byte VAR_NUM_SOUND_CHANNELS;
- byte VAR_WIZ_TCOLOR;
-};
-
-class ScummEngine_v71he : public ScummEngine_v70he {
-public:
- ScummEngine_v71he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
-protected:
- virtual void saveOrLoad(Serializer *s);
-
- virtual void redrawBGAreas();
-
- virtual void processActors();
- void preProcessAuxQueue();
- void postProcessAuxQueue();
-
-public:
- /* Actor AuxQueue stuff (HE) */
- AuxBlock _auxBlocks[16];
- uint16 _auxBlocksNum;
- AuxEntry _auxEntries[16];
- uint16 _auxEntriesNum;
-
- void queueAuxBlock(Actor *a);
- void queueAuxEntry(int actorNum, int subIndex);
-};
-
-class ScummEngine_v72he : public ScummEngine_v71he {
-protected:
- typedef void (ScummEngine_v72he::*OpcodeProcV72he)();
- struct OpcodeEntryV72he {
- OpcodeProcV72he proc;
- const char *desc;
- };
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
- struct ArrayHeader {
- int32 type; //0
- int32 dim1start; //4
- int32 dim1end; //8
- int32 dim2start; //0C
- int32 dim2end; //10
- byte data[1]; //14
- } GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
- const OpcodeEntryV72he *_opcodesV72he;
-
- int _stringLength;
- byte _stringBuffer[4096];
-
- WizParameters _wizParams;
-
-public:
- ScummEngine_v72he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
- virtual void scummInit();
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void initScummVars();
- virtual void readArrayFromIndexFile();
-
- virtual byte *getStringAddress(int i);
- virtual void readMAXS(int blockSize);
-
- virtual void redrawBGAreas();
-
- ArrayHeader *defineArray(int array, int type, int dim2start, int dim2end, int dim1start, int dim1end);
- virtual int readArray(int array, int idx2, int idx1);
- virtual void writeArray(int array, int idx2, int idx1, int value);
- void redimArray(int arrayId, int newDim2start, int newDim2end,
- int newDim1start, int newDim1end, int type);
- void checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end);
- void copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
- int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end);
- void copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num);
- virtual int setupStringArray(int size);
- int readFileToArray(int slot, int32 size);
- void writeFileFromArray(int slot, int32 resID);
-
- virtual void decodeParseString(int a, int b);
- void decodeScriptString(byte *dst, bool scriptString = false);
- void copyScriptString(byte *dst, int dstSize);
- int convertFilePath(byte *dst, bool setFilePath = false);
-
- int findObject(int x, int y, int num, int *args);
- int getSoundResourceSize(int id);
-
- virtual bool handleNextCharsetCode(Actor *a, int *c);
-
- /* HE version 72 script opcodes */
- void o72_pushDWord();
- void o72_getScriptString();
- void o72_isAnyOf();
- void o72_resetCutscene();
- void o72_findObjectWithClassOf();
- void o72_getObjectImageX();
- void o72_getObjectImageY();
- void o72_captureWizImage();
- void o72_getTimer();
- void o72_setTimer();
- void o72_getSoundPosition();
- void o72_startScript();
- void o72_startObject();
- void o72_drawObject();
- void o72_printWizImage();
- void o72_getArrayDimSize();
- void o72_getNumFreeArrays();
- void o72_roomOps();
- void o72_actorOps();
- void o72_verbOps();
- void o72_findObject();
- void o72_arrayOps();
- void o72_systemOps();
- void o72_talkActor();
- void o72_talkEgo();
- void o72_dimArray();
- void o72_dim2dimArray();
- void o72_traceStatus();
- void o72_debugInput();
- void o72_drawWizImage();
- void o72_kernelGetFunctions();
- void o72_jumpToScript();
- void o72_openFile();
- void o72_readFile();
- void o72_writeFile();
- void o72_findAllObjects();
- void o72_deleteFile();
- void o72_rename();
- void o72_getPixel();
- void o72_pickVarRandom();
- void o72_redimArray();
- void o72_readINI();
- void o72_writeINI();
- void o72_getResourceSize();
- void o72_setFilePath();
- void o72_setWindowCaption();
-
- byte VAR_NUM_ROOMS;
- byte VAR_NUM_SCRIPTS;
- byte VAR_NUM_SOUNDS;
- byte VAR_NUM_COSTUMES;
- byte VAR_NUM_IMAGES;
- byte VAR_NUM_CHARSETS;
-
- byte VAR_POLYGONS_ONLY;
-};
-
-class ScummEngine_v80he : public ScummEngine_v72he {
-protected:
- typedef void (ScummEngine_v80he::*OpcodeProcV80he)();
- struct OpcodeEntryV80he {
- OpcodeProcV80he proc;
- const char *desc;
- };
-
- const OpcodeEntryV80he *_opcodesV80he;
-
- int32 _heSndResId, _curSndId, _sndPtrOffs, _sndTmrOffs;
-
-public:
- ScummEngine_v80he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void initScummVars();
-
- virtual void initCharset(int charset);
-
- virtual void clearDrawQueues();
-
- void createSound(int snd1id, int snd2id);
-
- void drawLine(int x1, int y1, int x, int unk1, int unk2, int type, int id);
- void drawPixel(int x, int y, int flags);
-
- /* HE version 80 script opcodes */
- void o80_createSound();
- void o80_getFileSize();
- void o80_stringToInt();
- void o80_getSoundVar();
- void o80_localizeArrayToRoom();
- void o80_sourceDebug();
- void o80_readConfigFile();
- void o80_writeConfigFile();
- void o80_cursorCommand();
- void o80_setState();
- void o80_drawWizPolygon();
- void o80_drawLine();
- void o80_pickVarRandom();
-
- byte VAR_PLATFORM;
- byte VAR_WINDOWS_VERSION;
- byte VAR_CURRENT_CHARSET;
- byte VAR_COLOR_DEPTH;
-};
-
-class ScummEngine_v90he : public ScummEngine_v80he {
- friend class LogicHE;
- friend class Sprite;
-
-protected:
- typedef void (ScummEngine_v90he::*OpcodeProcV90he)();
- struct OpcodeEntryV90he {
- OpcodeProcV90he proc;
- const char *desc;
- };
-
- const OpcodeEntryV90he *_opcodesV90he;
-
- FloodFillParameters _floodFillParams;
-
- struct VideoParameters {
- byte filename[260];
- int32 status;
- int32 flags;
- int32 unk2;
- int32 wizResNum;
- };
-
- VideoParameters _videoParams;
-
- int32 _heObject, _heObjectNum;
- int32 _hePaletteNum;
-
- int32 _curMaxSpriteId;
- int32 _curSpriteId;
- int32 _curSpriteGroupId;
-
-public:
- ScummEngine_v90he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
- ~ScummEngine_v90he();
-
- virtual void scummInit();
-
- LogicHE *_logicHE;
- Sprite *_sprite;
-
-protected:
- virtual void allocateArrays();
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void setupScummVars();
- virtual void initScummVars();
-
- virtual void saveOrLoad(Serializer *s);
-
- virtual void readMAXS(int blockSize);
-
- virtual void processActors();
-
- int computeWizHistogram(int resnum, int state, int x, int y, int w, int h);
- void getArrayDim(int array, int *dim2start, int *dim2end, int *dim1start, int *dim1end);
- void sortArray(int array, int dim2start, int dim2end, int dim1start, int dim1end, int sortOrder);
-
-public:
- int getGroupSpriteArray(int spriteGroupId);
-
-protected:
- uint8 *getHEPaletteIndex(int palSlot);
- int getHEPaletteColor(int palSlot, int color);
- int getHEPaletteSimilarColor(int palSlot, int red, int green, int start, int end);
- int getHEPaletteColorComponent(int palSlot, int color, int component);
- void setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b);
- void setHEPaletteFromPtr(int palSlot, const uint8 *palData);
- void setHEPaletteFromCostume(int palSlot, int resId);
- void setHEPaletteFromImage(int palSlot, int resId, int state);
- void setHEPaletteFromRoom(int palSlot, int resId, int state);
- void restoreHEPalette(int palSlot);
- void copyHEPalette(int dstPalSlot, int srcPalSlot);
- void copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor);
-
-
- void setDefaultCursor();
-
-protected:
- /* HE version 90 script opcodes */
- void o90_dup_n();
- void o90_min();
- void o90_max();
- void o90_sin();
- void o90_cos();
- void o90_sqrt();
- void o90_atan2();
- void o90_getSegmentAngle();
- void o90_getActorData();
- void o90_startScriptUnk();
- void o90_jumpToScriptUnk();
- void o90_videoOps();
- void o90_getVideoData();
- void o90_wizImageOps();
- void o90_getDistanceBetweenPoints();
- void o90_getSpriteInfo();
- void o90_setSpriteInfo();
- void o90_getSpriteGroupInfo();
- void o90_setSpriteGroupInfo();
- void o90_getWizData();
- void o90_floodFill();
- void o90_mod();
- void o90_shl();
- void o90_shr();
- void o90_xor();
- void o90_findAllObjectsWithClassOf();
- void o90_getPolygonOverlap();
- void o90_cond();
- void o90_dim2dim2Array();
- void o90_redim2dimArray();
- void o90_getLinesIntersectionPoint();
- void o90_sortArray();
- void o90_getObjectData();
- void o90_getPaletteData();
- void o90_paletteOps();
- void o90_fontUnk();
- void o90_getActorAnimProgress();
- void o90_kernelGetFunctions();
- void o90_kernelSetFunctions();
-
- byte VAR_NUM_SPRITE_GROUPS;
- byte VAR_NUM_SPRITES;
- byte VAR_NUM_PALETTES;
- byte VAR_NUM_UNK;
-
- byte VAR_U32_VERSION;
- byte VAR_U32_ARRAY_UNK;
-};
-
-class ScummEngine_v99he : public ScummEngine_v90he {
-public:
- ScummEngine_v99he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v90he(detector, syst, gs, md5sum, substResFileNameIndex) {}
-
- virtual void scummInit();
-
-protected:
- virtual void initScummVars();
-
- virtual void readMAXS(int blockSize);
-
- virtual void saveOrLoad(Serializer *s);
-
- virtual void copyPalColor(int dst, int src);
- virtual void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
- virtual void setPaletteFromPtr(const byte *ptr, int numcolor = -1);
- virtual void setPalColor(int index, int r, int g, int b);
- virtual void updatePalette();
-};
-
-class ScummEngine_v100he : public ScummEngine_v99he {
-protected:
- typedef void (ScummEngine_v100he::*OpcodeProcV100he)();
- struct OpcodeEntryV100he {
- OpcodeProcV100he proc;
- const char *desc;
- };
-
- int32 _heResId, _heResType;
-
- const OpcodeEntryV100he *_opcodesV100he;
-
-public:
- ScummEngine_v100he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v99he(detector, syst, gs, md5sum, substResFileNameIndex) {}
-
-protected:
- virtual void setupOpcodes();
- virtual void executeOpcode(byte i);
- virtual const char *getOpcodeDesc(byte i);
-
- virtual void saveOrLoad(Serializer *s);
-
- virtual void decodeParseString(int a, int b);
-
- /* HE version 100 script opcodes */
- void o100_actorOps();
- void o100_arrayOps();
- void o100_dim2dimArray();
- void o100_redim2dimArray();
- void o100_dimArray();
- void o100_drawLine();
- void o100_drawObject();
- void o100_floodFill();
- void o100_setSpriteGroupInfo();
- void o100_resourceRoutines();
- void o100_wizImageOps();
- void o100_jumpToScript();
- void o100_createSound();
- void o100_dim2dim2Array();
- void o100_paletteOps();
- void o100_jumpToScriptUnk();
- void o100_startScriptUnk();
- void o100_redimArray();
- void o100_roomOps();
- void o100_startSound();
- void o100_setSpriteInfo();
- void o100_startScript();
- void o100_systemOps();
- void o100_cursorCommand();
- void o100_videoOps();
- void o100_wait();
- void o100_writeFile();
- void o100_isResourceLoaded();
- void o100_getResourceSize();
- void o100_getSpriteGroupInfo();
- void o100_getPaletteData();
- void o100_readFile();
- void o100_getSpriteInfo();
- void o100_getWizData();
- void o100_getVideoData();
-};
-#endif
-
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/logic_he.cpp b/scumm/logic_he.cpp
deleted file mode 100644
index 76de561721..0000000000
--- a/scumm/logic_he.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2005-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/intern_he.h"
-#include "scumm/logic_he.h"
-
-namespace Scumm {
-
-LogicHE::LogicHE(ScummEngine_v90he *vm) : _vm(vm) {
- // Originally it used 0x930 and stored both floats and doubles inside
- _userData = (float *)calloc(550, sizeof(float));
- _userDataD = (double *)calloc(30, sizeof(double));
-}
-
-LogicHE::~LogicHE() {
- free(_userData);
- free(_userDataD);
-}
-
-void LogicHE::writeScummVar(int var, int32 value) {
- _vm->writeVar(var, value);
-}
-
-static int32 scumm_round(double arg) {
- return (int32)(arg + 0.5);
-}
-
-int LogicHE::versionID() {
- return 1;
-}
-
-int LogicHE::getFromArray(int arg0, int idx2, int idx1) {
- _vm->VAR(_vm->VAR_U32_ARRAY_UNK) = arg0;
- return _vm->readArray(116, idx2, idx1);
-}
-
-void LogicHE::putInArray(int arg0, int idx2, int idx1, int val) {
- _vm->VAR(_vm->VAR_U32_ARRAY_UNK) = arg0;
- _vm->writeArray(116, idx2, idx1, val);
-}
-
-int32 LogicHE::dispatch(int op, int numArgs, int32 *args) {
-#if 1
- char tmp[32], str[256];
-
- if (numArgs > 0)
- snprintf(tmp, 32, "%d", args[0]);
- else
- *tmp = 0;
-
- snprintf(str, 256, "LogicHE::dispatch(%d, %d, [%s", op, numArgs, tmp);
-
- for (int i = 1; i < numArgs; i++) {
- snprintf(tmp, 32, ", %d", args[i]);
- strncat(str, tmp, 256);
- }
- strncat(str, "])", 256);
-
- debug(0, str);
-#else
- // Used for parallel trace utility
- for (int i = 0; i < numArgs; i++)
- debug(0, "args[%d] = %d;", i, args[i]);
-
- debug(0, "dispatch(%d, %d, args);", op, numArgs);
-
-#endif
-
- return 1;
-}
-
-/***********************
- * Putt-Putt Joins the Race
- *
- */
-
-int LogicHErace::versionID() {
- return 1;
-}
-
-int32 LogicHErace::dispatch(int op, int numArgs, int32 *args) {
- int32 res;
-
- switch (op) {
- case 1003:
- res = op_1003(args);
- break;
-
- case 1004:
- res = op_1004(args);
- break;
-
- case 1100:
- res = op_1100(args);
- break;
-
- case 1101:
- res = op_1101(args);
- break;
-
- case 1102:
- res = op_1102(args);
- break;
-
- case 1103:
- res = op_1103(args);
- break;
-
- case 1110:
- res = op_1110();
- break;
-
- case 1120:
- res = op_1120(args);
- break;
-
- case 1130:
- res = op_1130(args);
- break;
-
- case 1140:
- res = op_1140(args);
- break;
-
- default:
- res = 0;
- break;
-
- }
-
- return res;
-}
-
-#define RAD2DEG (180 / PI)
-#define DEG2RAD (PI / 180)
-
-int32 LogicHErace::op_1003(int32 *args) {
- int value = args[2] ? args[2] : 1;
-
- writeScummVar(108, (int32)(atan2((double)args[0], (double)args[1]) * RAD2DEG * value));
-
- return 1;
-}
-
-int32 LogicHErace::op_1004(int32 *args) {
- int value = args[1] ? args[1] : 1;
-
- writeScummVar(108, (int32)(sqrt((float)args[0]) * value));
-
- return 1;
-}
-
-int32 LogicHErace::op_1100(int32 *args) {
- _userData[516] = (float)args[0] / args[10];
- _userData[517] = (float)args[1] / args[10];
- _userData[518] = (float)args[2] / args[10];
- _userData[519] = (float)args[3] / args[10];
- _userData[520] = (float)args[4] / args[10];
-
- op_sub1(_userData[520]);
-
- _userData[521] = (float)args[5] / args[10];
-
- op_sub2(_userData[521]);
-
- _userData[532] = (float)args[10];
-
- _userData[524] = (float)args[8];
- _userData[525] = (float)args[9];
- _userData[522] = (float)args[6] / args[10];
- _userData[523] = (float)args[7] / args[10];
- _userData[526] = (float)args[6] / args[8] / args[10];
- _userData[527] = (float)args[7] / args[9] / args[10];
-
- writeScummVar(108, (int32)((float)args[6] / args[8] * args[10]));
-
- writeScummVar(109, (int32)((float)args[7] / args[9] * args[10]));
-
- _userData[528] = (float)(_userData[519] - _userData[523] * 0.5);
- _userData[529] = (float)(_userData[519] + _userData[523] * 0.5);
-
- writeScummVar(110, (int32)(_userData[528] * args[10]));
- writeScummVar(111, (int32)(_userData[529] * args[10]));
-
- _userData[530] = (float)(_userData[517] / tan(_userData[529] * DEG2RAD));
- _userData[531] = (float)(_userData[517] / tan(_userData[528] * DEG2RAD));
-
- writeScummVar(112, (int32)(_userData[530] * args[10]));
- writeScummVar(113, (int32)(_userData[531] * args[10]));
-
- return 1;
-}
-
-int32 LogicHErace::op_1101(int32 *args) {
- int32 retval;
- float temp;
-
- temp = args[0] / _userData[532];
-
- if (_userData[519] == temp) {
- retval = (int32)temp;
- } else {
- _userData[519] = temp;
- op_sub3(temp);
- retval = 1;
- }
-
- temp = args[1] / _userData[532];
-
- if (_userData[520] != temp) {
- _userData[520] = temp;
- op_sub1(temp);
- retval = 1;
- }
-
- temp = args[2] / _userData[532];
-
- if (_userData[521] != temp) {
- _userData[521] = temp;
- op_sub2(temp);
- retval = 1;
- }
-
- return retval;
-}
-
-int32 LogicHErace::op_1102(int32 *args) {
- int32 retval;
- float temp;
-
- temp = args[0] / _userData[532];
- if (_userData[516] != temp) {
- _userData[516] = temp;
- retval = 1;
- } else {
- retval = (int32)_userData[532];
- }
-
- temp = args[1] / _userData[532];
- if (_userData[517] != temp) {
- _userData[517] = temp;
- retval = 1;
- }
-
- temp = args[2] / _userData[532];
- if (_userData[518] != temp) {
- _userData[518] = temp;
- retval = 1;
- }
-
- return retval;
-}
-
-int32 LogicHErace::op_1103(int32 *args) {
- double angle = args[0] / args[1] * DEG2RAD;
-
- writeScummVar(108, (int32)(sin(angle) * args[2]));
- writeScummVar(109, (int32)(cos(angle) * args[2]));
-
- return 1;
-}
-
-int32 LogicHErace::op_1110() {
- writeScummVar(108, (int32)(_userData[526] * _userData[532] * _userData[532]));
- writeScummVar(109, (int32)(_userData[527] * _userData[532] * _userData[532]));
- writeScummVar(110, (int32)(_userData[532]));
-
- return 1;
-}
-
-int32 LogicHErace::op_1120(int32 *args) {
- double a0, a1, a2, expr;
- double res1, res2;
-
- a0 = args[0] / _userData[532] - _userData[516];
- a1 = args[1] / _userData[532] - _userData[517];
- a2 = args[2] / _userData[532] - _userData[518];
-
- expr = a2 * _userDataD[17] + a1 * _userDataD[14] + a0 * _userDataD[11];
-
- res1 = (atan2(a2 * _userDataD[15] + a1 * _userDataD[12] + a0 * _userDataD[9], expr) * RAD2DEG)
- / _userData[526];
- res2 = (atan2(a2 * _userDataD[16] + a1 * _userDataD[13] + a0 * _userDataD[10], expr) * RAD2DEG
- - _userData[528]) / _userData[527];
-
- writeScummVar(108, (int32)res1);
- writeScummVar(109, (int32)res2);
-
- return 1;
-}
-
-int32 LogicHErace::op_1130(int32 *args) {
- double cs = cos(args[0] / _userData[532] * DEG2RAD);
- double sn = sin(args[0] / _userData[532] * DEG2RAD);
-
- writeScummVar(108, (int32)(cs * args[1] + sn * args[2]));
-
- writeScummVar(109, (int32)(cs * args[2] - sn * args[1]));
-
- return 1;
-}
-
-int32 LogicHErace::op_1140(int32 *args) {
- double arg2 = -args[2] * args[2];
- double arg3 = -args[3] * args[3];
- double sq = sqrt(arg2 + arg3);
- double res;
-
- arg2 = arg2 / sq;
- arg3 = arg3 / sq;
-
- res = (args[0] - 2 * (arg2 * args[0] + arg3 * args[1]) * arg2) * 0.86956525;
-
- writeScummVar(108, (int32)res);
-
- res = args[1] - 2 * (arg2 * args[0] + arg3 * args[1]) * arg3;
-
- if (-args[3] * args[3] >= 0)
- res *= 0.83333331f;
-
- writeScummVar(109, (int32)res);
-
- return 1;
-}
-
-void LogicHErace::op_sub1(float arg) {
- _userDataD[10] = _userDataD[12] = _userDataD[14] = _userDataD[16] = 0;
- _userDataD[13] = 1;
-
- _userDataD[9] = cos(arg * DEG2RAD);
- _userDataD[15] = sin(arg * DEG2RAD);
- _userDataD[11] = -_userDataD[15];
- _userDataD[17] = _userDataD[9];
-}
-
-void LogicHErace::op_sub2(float arg) {
- _userDataD[20] = _userDataD[21] = _userDataD[24] = _userDataD[25] = 0;
- _userDataD[26] = 1;
-
- _userDataD[19] = sin(arg * DEG2RAD);
- _userDataD[18] = cos(arg * DEG2RAD);
- _userDataD[21] = -_userDataD[19];
- _userDataD[22] = _userDataD[18];
-}
-
-void LogicHErace::op_sub3(float arg) {
- _userDataD[1] = _userDataD[2] = _userDataD[3] = _userDataD[6] = 0;
- _userDataD[0] = 1;
-
- _userDataD[4] = cos(arg * DEG2RAD);
- _userDataD[5] = sin(arg * DEG2RAD);
- _userDataD[7] = -_userDataD[5];
- _userDataD[8] = _userDataD[4];
-}
-
-/***********************
- * Freddi Fish's One-Stop Fun Shop
- * Pajama Sam's One-Stop Fun Shop
- * Putt-Putt's One-Stop Fun Shop
- *
- */
-
-int LogicHEfunshop::versionID() {
- return 1;
-}
-
-int32 LogicHEfunshop::dispatch(int op, int numArgs, int32 *args) {
- switch (op) {
- case 1004:
- op_1004(args);
- break;
-
- case 1005:
- op_1005(args);
- break;
-
- default:
- break;
-
- }
-
- return 0;
-}
-
-void LogicHEfunshop::op_1004(int32 *args) {
- double data[8], at, sq;
- int32 x, y;
- int i=0;
-
- for (i = 0; i <= 6; i += 2) {
- data[i] = getFromArray(args[0], 0, 519 + i);
- data[i + 1] = getFromArray(args[0], 0, 519 + i + 1);
- }
- int s = checkShape((int32)data[0], (int32)data[1], (int32)data[4], (int32)data[5],
- (int32)data[2], (int32)data[3], (int32)data[6], (int32)data[7], &x, &y);
-
- if (s != 1) {
- error("LogicHEfunshop::op_1004: Your shape has defied the laws of physics\n");
- return;
- }
-
- for (i = 0; i <= 6; i += 2) {
- data[i] -= (double)x;
- data[i + 1] -= (double)y;
- }
-
- double a1 = (double)args[1] * DEG2RAD;
-
- for (i = 0; i <= 6; i += 2) {
- at = atan2(data[i + 1], data[i]);
- sq = sqrt(data[i + 1] * data[i + 1] + data[i] * data[i]);
-
- if (at <= 0)
- at += 2 * PI;
-
- data[i] = cos(at + a1) * sq;
- data[i + 1] = sin(at + a1) * sq;
- }
-
- int minx = 2;
- int miny = 3;
-
- for (i = 0; i <= 6; i += 2) {
- if (data[i] < data[minx])
- minx = i;
- if (data[i + 1] < data[miny])
- miny = i + 1;
- }
-
- for (i = 0; i <= 6; i += 2) {
- data[i] -= data[minx];
- data[i + 1] -= data[miny];
-
- putInArray(args[0], 0, 519 + i, scumm_round(data[i]));
- putInArray(args[0], 0, 519 + i + 1, scumm_round(data[i + 1]));
- }
-}
-
-void LogicHEfunshop::op_1005(int32 *args) {
- double data[8];
- double args1, args2;
- int i=0;
- for (i = 520; i <= 526; i += 2) {
- data[i - 520] = getFromArray(args[0], 0, i - 1);
- data[i - 520 + 1] = getFromArray(args[0], 0, i);
- }
-
- args1 = args[1] * 0.01 + 1;
- args2 = args[2] * 0.01 + 1;
-
- for (i = 0; i < 4; i++) {
- data[2 * i] *= args1;
- data[2 * i + 1] *= args2;
- }
-
- for (i = 520; i <= 526; i += 2) {
- putInArray(args[0], 0, i - 1, scumm_round(data[i - 520]));
- putInArray(args[0], 0, i, scumm_round(data[i - 520 + 1]));
- }
-}
-
-int LogicHEfunshop::checkShape(int32 data0, int32 data1, int32 data4, int32 data5, int32 data2, int32 data3, int32 data6, int32 data7, int32 *x, int32 *y) {
- int32 diff5_1, diff0_4, diff7_3, diff2_6;
- int32 diff1, diff2;
- int32 delta, delta2;
- int32 sum1, sum2;
-
- diff0_4 = data0 - data4;
- diff5_1 = data5 - data1;
- diff1 = data1 * data4 - data0 * data5;
- sum1 = diff0_4 * data3 + diff1 + diff5_1 * data2;
- sum2 = diff0_4 * data7 + diff1 + diff5_1 * data6;
-
- if (sum1 != 0 && sum2 != 0) {
- sum2 ^= sum1;
-
- if (sum2 >= 0)
- return 0;
- }
-
- diff2_6 = data2 - data6;
- diff7_3 = data7 - data3;
- diff2 = data3 * data6 - data2 * data7;
- sum1 = diff2_6 * data1 + diff2 + diff7_3 * data0;
- sum2 = diff2_6 * data5 + diff2 + diff7_3 * data4;;
-
- if (sum1 != 0 && sum2 != 0) {
- sum2 ^= sum1;
-
- if (sum2 >= 0)
- return 0;
- }
-
- delta = diff2_6 * diff5_1 - diff0_4 * diff7_3;
-
- if (delta == 0) {
- return 2;
- }
-
- if (delta < 0) {
- data7 = -((delta + 1) >> 1);
- } else {
- data7 = delta >> 1;
- }
-
- delta2 = diff2 * diff0_4 - diff1 * diff2_6;
-
- if (delta2 < 0) {
- delta2 -= data7;
- } else {
- delta2 += data7;
- }
-
- *x = delta2 / delta;
-
- delta2 = diff1 * diff7_3 - diff2 * diff5_1;
-
- if (delta2 < 0) {
- delta2 -= data7;
- } else {
- delta2 += data7;
- }
-
- *y = delta2 / delta;
-
- return 1;
-}
-
-/***********************
- * Backyard Football
- * Backyard Football Demo
- *
- */
-
-int LogicHEfootball::versionID() {
- return 1;
-}
-
-int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) {
- int res = 0;
-
- switch (op) {
- case 1004:
- res = op_1004(args);
- break;
-
- case 1006:
- res = op_1006(args);
- break;
-
- case 1007:
- res = op_1007(args);
- break;
-
- case 1010:
- res = op_1010(args);
- break;
-
- case 1022:
- res = op_1022(args);
- break;
-
- case 1023:
- res = op_1023(args);
- break;
-
- case 1024:
- res = op_1024(args);
- break;
-
- case 8221968:
- // Someone had a fun and used his birthday as opcode number
- res = getFromArray(args[0], args[1], args[2]);
- break;
-
- case 1492: case 1493: case 1494: case 1495: case 1496:
- case 1497: case 1498: case 1499: case 1500: case 1501:
- case 1502: case 1503: case 1504: case 1505: case 1506:
- case 1507: case 1508: case 1509: case 1510: case 1511:
- case 1512: case 1513: case 1514: case 1555:
- // DirectPlay-related
- // 1513: initialize
- // 1555: set fake lag
- break;
-
- case 2200: case 2201: case 2202: case 2203: case 2204:
- case 2205: case 2206: case 2207: case 2208: case 2209:
- case 2210: case 2211: case 2212: case 2213: case 2214:
- case 2215: case 2216: case 2217: case 2218: case 2219:
- case 2220: case 2221: case 2222: case 2223: case 2224:
- case 2225: case 2226: case 2227: case 2228:
- // Boneyards-related
- break;
-
- case 3000: case 3001: case 3002: case 3003: case 3004:
- // Internet-related
- // 3000: check for updates
- // 3001: check network status
- // 3002: autoupdate
- // 3003: close connection
- break;
-
- default:
- LogicHE::dispatch(op, numArgs, args);
- error("Tell me how to reproduce it");
- }
-
- return res;
-}
-
-int LogicHEfootball::op_1004(int32 *args) {
- double res, a2, a4, a5;
-
- a5 = ((double)args[4] - (double)args[1]) / ((double)args[5] - (double)args[2]);
- a4 = ((double)args[3] - (double)args[0]) / ((double)args[5] - (double)args[2]);
- a2 = (double)args[2] - (double)args[0] * a4 - args[1] * a5;
-
- res = (double)args[6] * a4 + (double)args[7] * a5 + a2;
- writeScummVar(108, (int32)res);
-
- writeScummVar(109, (int32)a2);
- writeScummVar(110, (int32)a5);
- writeScummVar(111, (int32)a4);
-
- return 1;
-}
-
-int LogicHEfootball::op_1006(int32 *args) {
- double res;
-
- res = (1.0 - args[1] * 2.9411764e-4 * 5.3050399e-2) * args[0] * 1.2360656e-1 +
- args[1] * 1.1764706e-2 + 46;
- writeScummVar(108, (int32)res);
-
- res = 640.0 - args[2] * 1.2360656e-1 - args[1] * 1.1588235e-1 - 26;
- writeScummVar(109, (int32)res);
-
- return 1;
-}
-
-int LogicHEfootball::op_1007(int32 *args) {
- double res, temp;
-
- temp = (double)args[1] * 0.32;
-
- if (temp > 304.0)
- res = -args[2] * 0.142;
- else
- res = args[2] * 0.142;
-
- res += temp;
-
- writeScummVar(108, (int32)res);
-
- res = (1000.0 - args[2]) * 0.48;
-
- writeScummVar(109, (int32)res);
-
- return 1;
-}
-
-int LogicHEfootball::op_1010(int32 *args) {
- double a1 = (640.0 - (double)args[1] - 26.0) * 8.6294413;
- double res;
-
- res = ((double)args[0] - 46 - a1 * 1.1764706e-2) /
- ((1.0 - a1 * 2.9411764e-4 * 5.3050399e-2) * 1.2360656e-1);
- writeScummVar(108, (int32)res);
-
- writeScummVar(109, (int32)a1);
-
- return 1;
-}
-
-int LogicHEfootball::op_1022(int32 *args) {
- double res;
- double var10 = args[4] - args[1];
- double var8 = args[5] - args[2];
- double var6 = args[3] - args[0];
-
- res = sqrt(var8 * var8 + var6 * var6 + var10 * var10);
-
- if (res >= (double)args[6]) {
- var8 = (double)args[6] * var8 / res;
- var10 = (double)args[6] * var10 / res;
- res = (double)args[6] * var6 / res;
- }
-
- writeScummVar(108, (int32)res);
- writeScummVar(109, (int32)var10);
- writeScummVar(110, (int32)var8);
-
- return 1;
-}
-
-int LogicHEfootball::op_1023(int32 *args) {
- double var10, var18, var20, var28, var30, var30_;
- double argf[7];
-
- for (int i = 0; i < 7; i++)
- argf[i] = args[i];
-
- var10 = (argf[3] - argf[1]) / (argf[2] - argf[0]);
- var28 = var10 * var10 + 1;
- var20 = argf[0] * var10;
- var18 = (argf[5] + argf[1] + var20) * argf[4] * var10 * 2 +
- argf[6] * argf[6] * var28 + argf[4] * argf[4] -
- argf[0] * argf[0] * var10 * var10 -
- argf[5] * argf[0] * var10 * 2 -
- argf[5] * argf[1] * 2 -
- argf[1] * argf[1] - argf[5] * argf[5];
-
- if (var18 >= 0) {
- var18 = sqrt(var18);
-
- var30_ = argf[4] + argf[5] * var10 + argf[1] * var10 + argf[0] * var10 * var10;
- var30 = (var30_ - var18) / var28;
- var18 = (var30_ + var18) / var28;
-
- if ((argf[0] - var30 < 0) && (argf[0] - var18 < 0)) {
- var30_ = var30;
- var30 = var18;
- var18 = var30_;
- }
- var28 = var18 * var10 - var20 - argf[1];
- var20 = var30 * var10 - var20 - argf[1];
- } else {
- var18 = 0;
- var20 = 0;
- var28 = 0;
- var30 = 0;
- }
-
- writeScummVar(108, (int32)var18);
- writeScummVar(109, (int32)var28);
- writeScummVar(110, (int32)var30);
- writeScummVar(111, (int32)var20);
-
- return 1;
-}
-int LogicHEfootball::op_1024(int32 *args) {
- writeScummVar(108, 0);
- writeScummVar(109, 0);
- writeScummVar(110, 0);
- writeScummVar(111, 0);
-
- return 1;
-}
-
-
-} // End of namespace Scumm
diff --git a/scumm/logic_he.h b/scumm/logic_he.h
deleted file mode 100644
index c237f6182c..0000000000
--- a/scumm/logic_he.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2005-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(LOGIC_HE_H) && !defined(DISABLE_HE)
-#define LOGIC_HE_H
-
-#include "common/stdafx.h"
-
-namespace Scumm {
-
-class ScummEngine_v90he;
-
-class LogicHE {
-public:
- float *_userData;
- double *_userDataD;
- ScummEngine_v90he *_vm;
-
- LogicHE(ScummEngine_v90he *vm);
- virtual ~LogicHE();
-
- void writeScummVar(int var, int32 value);
- int getFromArray(int arg0, int idx2, int idx1);
- void putInArray(int arg0, int idx2, int idx1, int val);
-
- void beforeBootScript(void) {};
- void initOnce() {};
- void startOfFrame() {};
- void endOfFrame() {};
- void processKeyStroke(int keyPressed) {};
-
- virtual int versionID();
- virtual int32 dispatch(int op, int numArgs, int32 *args);
-};
-
-class LogicHErace : public LogicHE {
-public:
- LogicHErace(ScummEngine_v90he *vm) : LogicHE(vm) {}
-
- int versionID();
- int32 dispatch(int op, int numArgs, int32 *args);
-
-private:
- int32 op_1003(int32 *args);
- int32 op_1004(int32 *args);
- int32 op_1100(int32 *args);
- int32 op_1101(int32 *args);
- int32 op_1102(int32 *args);
- int32 op_1103(int32 *args);
- int32 op_1110();
- int32 op_1120(int32 *args);
- int32 op_1130(int32 *args);
- int32 op_1140(int32 *args);
-
- void op_sub1(float arg);
- void op_sub2(float arg);
- void op_sub3(float arg);
-};
-
-class LogicHEfunshop : public LogicHE {
-public:
- LogicHEfunshop(ScummEngine_v90he *vm) : LogicHE(vm) {}
-
- int versionID();
- int32 dispatch(int op, int numArgs, int32 *args);
-
-private:
- void op_1004(int32 *args);
- void op_1005(int32 *args);
- int checkShape(int32 data0, int32 data1, int32 data4, int32 data5, int32 data2, int32 data3, int32 data6, int32 data7, int32 *x, int32 *y);
-};
-
-class LogicHEfootball : public LogicHE {
-public:
- LogicHEfootball(ScummEngine_v90he *vm) : LogicHE(vm) {}
-
- int versionID();
- int32 dispatch(int op, int numArgs, int32 *args);
-
-private:
- int op_1004(int32 *args);
- int op_1006(int32 *args);
- int op_1007(int32 *args);
- int op_1010(int32 *args);
- int op_1022(int32 *args);
- int op_1023(int32 *args);
- int op_1024(int32 *args);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/midiparser_eup.cpp b/scumm/midiparser_eup.cpp
deleted file mode 100644
index a9c40f99c5..0000000000
--- a/scumm/midiparser_eup.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "sound/midiparser.h"
-#include "sound/mididrv.h"
-#include "common/util.h"
-
-namespace Scumm {
-
-/**
- * The FM-TOWNS Euphony version of MidiParser.
- */
-class MidiParser_EUP : public MidiParser {
-protected:
- byte _instruments[6][50]; // Two extra bytes for SysEx ID and channel #
- byte *_instr_to_channel;
- struct {
- byte *enable;
- int8 *channel;
- int8 *volume;
- int8 *transpose;
- } _presets;
- bool _loop;
- byte _presend; // Tracks which startup implied events have been sent.
- uint32 _base_tick; // Events times are relative to this base.
-
-protected:
- void parseNextEvent (EventInfo &info);
- void resetTracking();
-
-public:
- bool loadMusic (byte *data, uint32 size);
-};
-
-
-
-//////////////////////////////////////////////////
-//
-// MidiParser_EUP implementation
-//
-//////////////////////////////////////////////////
-
-void MidiParser_EUP::parseNextEvent (EventInfo &info) {
- byte *pos = _position._play_pos;
-
- // FIXME: The presend is for sending init events
- // that aren't actually in the stream. This would
- // be for, e.g., instrument setup. Right now, we
- // don't actually use the instruments specified
- // in the music header. We're sending fixed GM
- // program changes to get a reasonable "one-size-
- // fits-all" sound until we actually support the
- // FM synthesis capabilities of FM-TOWNS.
- for (; _presend < 12; ++_presend) {
- if (_instr_to_channel[_presend >> 1] >= 16)
- continue;
- info.start = pos;
- info.delta = 0;
- if (_presend & 1) {
- byte *data = &_instruments[_presend >> 1][0];
- data[1] = _instr_to_channel[_presend >> 1];
- info.event = 0xF0;
- info.ext.data = data;
- info.length = 48;
- } else {
- info.event = 0xB0 | (_presend >> 1);
- info.basic.param1 = 121;
- info.basic.param2 = 0;
- }
- ++_presend;
- return;
- }
-
- while (true) {
- byte cmd = *pos;
- if ((cmd & 0xF0) == 0x90) {
- byte preset = pos[1];
- byte channel = _presets.channel[preset];
- if (channel >= 16)
- channel = cmd & 0x0F;
- uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _base_tick;
- int note = (int) pos[4] + _presets.transpose[preset];
- int volume = (int) pos[5];
- // HACK: Loom-Towns distaff tracks seem to
- // contain zero-volume note events, so change
- // those to full volume.
- if (!volume)
- volume = 127;
- volume += _presets.volume[preset];
- if (volume > 127)
- volume = 127;
- else if (volume < 0)
- volume = 0;
- pos += 6;
- if (_presets.enable[preset]) {
- uint16 duration = pos[1] | (pos[2] << 4);
- info.start = pos;
- uint32 last = _position._last_event_tick;
- info.delta = (tick < last) ? 0 : (tick - last);
- info.event = 0x90 | channel;
- info.length = duration;
- info.basic.param1 = note;
- info.basic.param2 = volume;
- pos += 6;
- break;
- }
- pos += 6;
- } else if (cmd == 0xF2) {
- // This is a "measure marker" of sorts.
- // It advances the "base time", to which
- // all event times are relative.
- _base_tick += (pos[3] << 7) | pos[2];
- pos += 6;
- } else if (cmd == 0xF8) {
- // TODO: Implement this.
- pos += 6;
- } else if (cmd == 0xFD || cmd == 0xFE) {
- // End of track.
- if (_loop && false) {
- // TODO: Implement this.
- } else {
- info.start = pos;
- uint32 last = _position._last_event_tick;
- info.delta = (_base_tick < last) ? 0 : (_base_tick - last);
- info.event = 0xFF;
- info.length = 0;
- info.ext.type = 0x2F;
- info.ext.data = pos;
- break;
- }
- } else {
- error("Unknown Euphony music event 0x%02X", (int) cmd);
- memset(&info, 0, sizeof(info));
- pos = 0;
- break;
- }
- }
- _position._play_pos = pos;
-}
-
-bool MidiParser_EUP::loadMusic (byte *data, uint32 size) {
- unloadMusic();
- byte *pos = data;
- int i;
-
- if (memcmp(pos, "SO", 2)) {
- error("'SO' header expected but found '%c%c' instead.", pos[0], pos[1]);
- return false;
- }
-
- byte numInstruments = pos[16];
- pos += 16 + 2;
- for (i = 0; i < numInstruments; ++i) {
- _instruments[i][0] = 0x7C;
- memcpy (&_instruments[i][2], pos, 48);
- pos += 48;
- }
-
- // Load the prest pointers
- _presets.enable = pos;
- pos += 32;
- _presets.channel = (int8 *) pos;
- pos += 32;
- _presets.volume = (int8 *) pos;
- pos += 32;
- _presets.transpose = (int8 *) pos;
- pos += 32;
-
- pos += 8; // Unknown bytes
- _instr_to_channel = pos; // Instrument-to-channel mapping
- pos += 6;
- pos += 4; // Skip the music size for now.
- pos++; // Unknown byte
- byte tempo = *pos++;
- _loop = (*pos++ != 1);
- pos++; // Unknown byte
-
- _num_tracks = 1;
- _ppqn = 120;
- _tracks[0] = pos;
-
- // Note that we assume the original data passed in
- // will persist beyond this call, i.e. we do NOT
- // copy the data to our own buffer. Take warning....
- resetTracking();
- setTempo (1000000 * 60 / tempo);
- setTrack (0);
- return true;
-}
-
-void MidiParser_EUP::resetTracking() {
- MidiParser::resetTracking();
- _presend = 0;
- _base_tick = 0;
-}
-
-MidiParser *MidiParser_createEUP() { return new MidiParser_EUP; }
-
-} // End of namespace Scumm
diff --git a/scumm/midiparser_ro.cpp b/scumm/midiparser_ro.cpp
deleted file mode 100644
index b240ffb5fd..0000000000
--- a/scumm/midiparser_ro.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "sound/midiparser.h"
-#include "sound/mididrv.h"
-#include "common/util.h"
-
-namespace Scumm {
-
-//////////////////////////////////////////////////
-//
-// The Standard MIDI File version of MidiParser
-//
-//////////////////////////////////////////////////
-
-class MidiParser_RO : public MidiParser {
-protected:
- int _markerCount; // Number of markers encountered in stream so far
- int _lastMarkerCount; // Cache markers until parsed event is actually consumed
-
-protected:
- void compressToType0();
- void parseNextEvent (EventInfo &info);
-
-public:
- bool loadMusic (byte *data, uint32 size);
- uint32 getTick() { return (uint32) _markerCount * _ppqn / 2; }
-};
-
-
-
-//////////////////////////////////////////////////
-//
-// MidiParser_RO implementation
-//
-//////////////////////////////////////////////////
-
-void MidiParser_RO::parseNextEvent (EventInfo &info) {
- _markerCount += _lastMarkerCount;
- _lastMarkerCount = 0;
-
- info.delta = 0;
- do {
- info.start = _position._play_pos;
- info.event = *(_position._play_pos++);
- if (info.command() == 0xA) {
- ++_lastMarkerCount;
- info.event = 0xF0;
- } else if (info.event == 0xF0) {
- byte delay = *(_position._play_pos++);
- info.delta += delay;
- continue;
- }
- break;
- } while (true);
-
- // Seems to indicate EOT
- if (info.event == 0) {
- info.event = 0xFF;
- info.ext.type = 0x2F;
- info.length = 0;
- info.ext.data = 0;
- return;
- }
-
- if (info.event < 0x80)
- return;
-
- _position._running_status = info.event;
- switch (info.command()) {
- case 0xC:
- info.basic.param1 = *(_position._play_pos++);
- info.basic.param2 = 0;
- break;
-
- case 0x8: case 0x9: case 0xB:
- info.basic.param1 = *(_position._play_pos++);
- info.basic.param2 = *(_position._play_pos++);
- if (info.command() == 0x9 && info.basic.param2 == 0)
- info.event = info.channel() | 0x80;
- info.length = 0;
- break;
-
- case 0xF: // Marker and EOT messages
- info.length = 0;
- info.ext.data = 0;
- if (info.event == 0xFF) {
- _autoLoop = true;
- info.ext.type = 0x2F;
- } else {
- info.ext.type = 0x7F; // Bogus META
- }
- info.event = 0xFF;
- break;
- }
-}
-
-bool MidiParser_RO::loadMusic (byte *data, uint32 size) {
- unloadMusic();
- byte *pos = data;
-
- if (memcmp (pos, "RO", 2)) {
- error("'RO' header expected but found '%c%c' instead", pos[0], pos[1]);
- return false;
- }
-
- _num_tracks = 1;
- _ppqn = 120;
- _tracks[0] = pos + 2;
- _markerCount = _lastMarkerCount = 0;
-
- // Note that we assume the original data passed in
- // will persist beyond this call, i.e. we do NOT
- // copy the data to our own buffer. Take warning....
- resetTracking();
- setTempo (500000);
- setTrack (0);
- return true;
-}
-
-MidiParser *MidiParser_createRO() { return new MidiParser_RO; }
-
-} // End of namespace Scumm
diff --git a/scumm/module.mk b/scumm/module.mk
deleted file mode 100644
index 547a64e174..0000000000
--- a/scumm/module.mk
+++ /dev/null
@@ -1,110 +0,0 @@
-MODULE := scumm
-
-MODULE_OBJS := \
- scumm/actor.o \
- scumm/akos.o \
- scumm/base-costume.o \
- scumm/bomp.o \
- scumm/boxes.o \
- scumm/camera.o \
- scumm/charset.o \
- scumm/costume.o \
- scumm/cursor.o \
- scumm/debugger.o \
- scumm/dialogs.o \
- scumm/gfx.o \
- scumm/imuse.o \
- scumm/imuse_player.o \
- scumm/input.o \
- scumm/instrument.o \
- scumm/help.o \
- scumm/midiparser_ro.o \
- scumm/midiparser_eup.o \
- scumm/object.o \
- scumm/palette.o \
- scumm/player_mod.o \
- scumm/player_v1.o \
- scumm/player_nes.o \
- scumm/player_v2.o \
- scumm/player_v2a.o \
- scumm/player_v3a.o \
- scumm/resource.o \
- scumm/resource_v2.o \
- scumm/resource_v3.o \
- scumm/resource_v4.o \
- scumm/room.o \
- scumm/saveload.o \
- scumm/script.o \
- scumm/script_c64.o \
- scumm/script_v2.o \
- scumm/script_v5.o \
- scumm/script_v6.o \
- scumm/script_v6he.o \
- scumm/scumm.o \
- scumm/sound.o \
- scumm/sound_he.o \
- scumm/string.o \
- scumm/usage_bits.o \
- scumm/util.o \
- scumm/vars.o \
- scumm/verbs.o \
- scumm/thumbnail.o
-
-ifndef DISABLE_SCUMM_7_8
-MODULE_OBJS += \
- scumm/nut_renderer.o \
- scumm/script_v8.o \
- scumm/imuse_digi/dimuse.o \
- scumm/imuse_digi/dimuse_bndmgr.o \
- scumm/imuse_digi/dimuse_codecs.o \
- scumm/imuse_digi/dimuse_music.o \
- scumm/imuse_digi/dimuse_sndmgr.o \
- scumm/imuse_digi/dimuse_script.o \
- scumm/imuse_digi/dimuse_track.o \
- scumm/imuse_digi/dimuse_tables.o \
- scumm/insane/insane.o \
- scumm/insane/insane_ben.o \
- scumm/insane/insane_enemy.o \
- scumm/insane/insane_scenes.o \
- scumm/insane/insane_iact.o \
- scumm/smush/chunk.o \
- scumm/smush/codec1.o \
- scumm/smush/codec37.o \
- scumm/smush/codec47.o \
- scumm/smush/imuse_channel.o \
- scumm/smush/smush_player.o \
- scumm/smush/saud_channel.o \
- scumm/smush/smush_mixer.o \
- scumm/smush/smush_font.o
-endif
-
-ifndef DISABLE_HE
-MODULE_OBJS += \
- scumm/floodfill_he.o \
- scumm/logic_he.o \
- scumm/palette_he.o \
- scumm/resource_v7he.o \
- scumm/script_v7he.o \
- scumm/script_v72he.o \
- scumm/script_v80he.o \
- scumm/script_v90he.o \
- scumm/script_v100he.o \
- scumm/sprite_he.o \
- scumm/wiz_he.o
-endif
-
-MODULE_DIRS += \
- scumm \
- scumm/imuse_digi \
- scumm/insane \
- scumm/smush
-
-# This module can be built as a plugin
-ifdef BUILD_PLUGINS
-PLUGIN := 1
-# HACK HACK evil HACK HACK
-PLUGIN_LDFLAGS += -lz
-endif
-
-# Include common rules
-include $(srcdir)/common.rules
diff --git a/scumm/music.h b/scumm/music.h
deleted file mode 100644
index b837fced51..0000000000
--- a/scumm/music.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * /scummvm/scummvm/scumm/player_v3a.h
- *
- */
-
-#ifndef SCUMM_MUSIC_H
-#define SCUMM_MUSIC_H
-
-#include "common/scummsys.h"
-
-namespace Scumm {
-
-/**
- * Pure virtual base class for the various music/sound engines used in Scumm
- * games. In particular, the iMuse code provides a subclass of this. There are
- * several other subclasses providing music and sound capabilities for
- * several Scumm games.
- * Having this base class for all music engines allows uniform access to the
- * core music/sound functionality, thus simplifying the client code.
- *
- * Instantiated by class Scumm.
- */
-class MusicEngine {
-public:
- virtual ~MusicEngine() {}
-
- /**
- * Set the output volume.
- * @param vol the new output volume
- */
- virtual void setMusicVolume(int vol) = 0;
-
- /**
- * Start playing the sound with the given id.
- * @param sound the sound to start
- */
- virtual void startSound(int sound) = 0;
-
- /**
- * Stop playing the sound with the given id.
- * @param sound the sound to stop
- */
- virtual void stopSound(int sound) = 0;
-
- /**
- * Start playing all currently playing sounds.
- */
- virtual void stopAllSounds() = 0;
-
- /**
- * Query the status of the sound with the given id. Usually this is just
- * a boolean telling us whether the sound is playing or not.
- * @param sound the sound to for which we want the status
- * @return the status of the specified sound
- */
- virtual int getSoundStatus(int sound) const = 0;
-
- /**
- * Get the value of the music timer. Used for synchronising scripts with
- * the music/sound.
- * @return the music timer
- */
- virtual int getMusicTimer() const { return 0; }
-
- /**
- * Terminate the music engine. Called just before the music engine
- * is deleted.
- */
- virtual void terminate() {}
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/nut_renderer.cpp b/scumm/nut_renderer.cpp
deleted file mode 100644
index e7d3e6f7c9..0000000000
--- a/scumm/nut_renderer.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/nut_renderer.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-NutRenderer::NutRenderer(ScummEngine *vm) :
- _vm(vm),
- _loaded(false),
- _numChars(0) {
- memset(_chars, 0, sizeof(_chars));
-}
-
-NutRenderer::~NutRenderer() {
- for (int i = 0; i < _numChars; i++) {
- delete []_chars[i].src;
- }
-}
-
-void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
-
-static void smush_decode_codec21(byte *dst, const byte *src, int width, int height, int pitch) {
- while (height--) {
- uint8 *dstPtrNext = dst + pitch;
- const uint8 *srcPtrNext = src + 2 + READ_LE_UINT16(src); src += 2;
- int len = width;
- do {
- int offs = READ_LE_UINT16(src); src += 2;
- dst += offs;
- len -= offs;
- if (len <= 0) {
- break;
- }
- int w = READ_LE_UINT16(src) + 1; src += 2;
- len -= w;
- if (len < 0) {
- w += len;
- }
- // the original codec44 handles this part slightly differently (this is the only difference with codec21) :
- // src bytes equal to 255 are replaced by 0 in dst
- // src bytes equal to 1 are replaced by a color passed as an argument in the original function
- // other src bytes values are copied as-is
- memcpy(dst, src, w); dst += w; src += w;
- } while (len > 0);
- dst = dstPtrNext;
- src = srcPtrNext;
- }
-}
-
-bool NutRenderer::loadFont(const char *filename) {
- if (_loaded) {
- debug(0, "NutRenderer::loadFont() Font already loaded, ok, loading...");
- }
-
- ScummFile file;
- _vm->openFile(file, filename);
- if (!file.isOpen()) {
- error("NutRenderer::loadFont() Can't open font file: %s", filename);
- return false;
- }
-
- uint32 tag = file.readUint32BE();
- if (tag != 'ANIM') {
- error("NutRenderer::loadFont() there is no ANIM chunk in font header");
- return false;
- }
-
- uint32 length = file.readUint32BE();
- byte *dataSrc = (byte *)malloc(length);
- file.read(dataSrc, length);
- file.close();
-
- if (READ_BE_UINT32(dataSrc) != 'AHDR') {
- error("NutRenderer::loadFont() there is no AHDR chunk in font header");
- free(dataSrc);
- return false;
- }
-
- _numChars = READ_LE_UINT16(dataSrc + 10);
- assert(_numChars <= ARRAYSIZE(_chars));
- uint32 offset = 0;
- for (int l = 0; l < _numChars; l++) {
- offset += READ_BE_UINT32(dataSrc + offset + 4) + 8;
- if (READ_BE_UINT32(dataSrc + offset) != 'FRME') {
- error("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset);
- break;
- }
- offset += 8;
- if (READ_BE_UINT32(dataSrc + offset) != 'FOBJ') {
- error("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset);
- break;
- }
- int codec = READ_LE_UINT16(dataSrc + offset + 8);
- _chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
- _chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
- _chars[l].width = READ_LE_UINT16(dataSrc + offset + 14);
- _chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
- const int srcSize = _chars[l].width * _chars[l].height;
- _chars[l].src = new byte[srcSize];
- // If characters have transparency, then bytes just get skipped and
- // so there may appear some garbage. That's why we have to fill it
- // with zeroes first.
- memset(_chars[l].src, 0, srcSize);
-
- const uint8 *fobjptr = dataSrc + offset + 22;
- switch (codec) {
- case 1:
- smush_decode_codec1(_chars[l].src, fobjptr, 0, 0, _chars[l].width, _chars[l].height, _chars[l].width);
- break;
- case 21:
- case 44:
- smush_decode_codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width);
- break;
- default:
- error("NutRenderer::loadFont: unknown codec: %d", codec);
- }
- }
-
- free(dataSrc);
- _loaded = true;
- return true;
-}
-
-int NutRenderer::getCharWidth(byte c) const {
- if (!_loaded) {
- error("NutRenderer::getCharWidth() Font is not loaded");
- return 0;
- }
-
- if (c >= 0x80 && _vm->_useCJKMode)
- return _vm->_2byteWidth / 2;
-
- if (c >= _numChars)
- error("invalid character in NutRenderer::getCharWidth : %d (%d)", c, _numChars);
-
- return _chars[c].width;
-}
-
-int NutRenderer::getCharHeight(byte c) const {
- if (!_loaded) {
- error("NutRenderer::getCharHeight() Font is not loaded");
- return 0;
- }
-
- if (c >= 0x80 && _vm->_useCJKMode)
- return _vm->_2byteHeight;
-
- if (c >= _numChars)
- error("invalid character in NutRenderer::getCharHeight : %d (%d)", c, _numChars);
-
- return _chars[c].height;
-}
-
-void NutRenderer::drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow) {
- if (!_loaded) {
- error("NutRenderer::drawShadowChar() Font is not loaded");
- return;
- }
-
- // HACK: we draw the character a total of 7 times: 6 times shifted
- // and in black for the shadow, and once in the right color and position.
- // This way we achieve the exact look as the original CMI had. However,
- // the question remains whether they did it this way, too, or if there is
- // some "font shadow" resource we don't know yet.
-
- static const int offsetX[7] = { -1, 0, 1, 0, 1, 2, 0 };
- static const int offsetY[7] = { 0, -1, 0, 1, 2, 1, 0 };
- const int cTable[7] = { 0, 0, 0, 0, 0, 0, color };
- int i = 0;
-
- if (!showShadow)
- i = 6;
-
- for (; i < 7; i++) {
- x += offsetX[i];
- y += offsetY[i];
- color = cTable[i];
-
- if (c >= 256 && _vm->_useCJKMode)
- draw2byte(s, c, x, y, color);
- else
- drawChar(s, (byte)c, x, y, color);
-
- x -= offsetX[i];
- y -= offsetY[i];
- }
-}
-
-void NutRenderer::drawFrame(byte *dst, int c, int x, int y) {
- const int width = MIN(_chars[c].width, _vm->_screenWidth - x);
- const int height = MIN(_chars[c].height, _vm->_screenHeight - y);
- const byte *src = _chars[c].src;
- const int srcPitch = _chars[c].width;
- byte bits = 0;
-
- const int minX = x < 0 ? -x : 0;
- const int minY = y < 0 ? -y : 0;
-
- if (height <= 0 || width <= 0) {
- return;
- }
-
- dst += _vm->_screenWidth * y + x;
- if (minY) {
- src += minY * srcPitch;
- dst += minY * _vm->_screenWidth;
- }
-
- for (int ty = minY; ty < height; ty++) {
- for (int tx = minX; tx < width; tx++) {
- bits = src[tx];
- if (bits != 231 && bits) {
- dst[tx] = bits;
- }
- }
- src += srcPitch;
- dst += _vm->_screenWidth;
- }
-}
-
-void NutRenderer::drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color) {
- byte *dst = (byte *)s.pixels + y * s.pitch + x;
- const int width = MIN(_chars[c].width, s.w - x);
- const int height = MIN(_chars[c].height, s.h - y);
- const byte *src = _chars[c].src;
- const int srcPitch = _chars[c].width;
-
- const int minX = x < 0 ? -x : 0;
- const int minY = y < 0 ? -y : 0;
-
- if (height <= 0 || width <= 0) {
- return;
- }
-
- if (minY) {
- src += minY * srcPitch;
- dst += minY * s.pitch;
- }
-
- for (int ty = minY; ty < height; ty++) {
- for (int tx = minX; tx < width; tx++) {
- if (src[tx] != 0) {
- dst[tx] = color;
- }
- }
- src += srcPitch;
- dst += s.pitch;
- }
-}
-
-void NutRenderer::draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color) {
- if (!_loaded) {
- error("NutRenderer::draw2byte() Font is not loaded");
- return;
- }
-
- byte *dst = (byte *)s.pixels + y * s.pitch + x;
- const int width = _vm->_2byteWidth;
- const int height = MIN(_vm->_2byteHeight, s.h - y);
- const byte *src = _vm->get2byteCharPtr(c);
- byte bits = 0;
-
- if (height <= 0 || width <= 0) {
- return;
- }
-
- for (int ty = 0; ty < height; ty++) {
- for (int tx = 0; tx < width; tx++) {
- if ((tx & 7) == 0)
- bits = *src++;
- if (x + tx < 0 || x + tx >= s.w || y + ty < 0)
- continue;
- if (bits & revBitMask(tx % 8)) {
- dst[tx] = color;
- }
- }
- dst += s.pitch;
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/nut_renderer.h b/scumm/nut_renderer.h
deleted file mode 100644
index 8972fef949..0000000000
--- a/scumm/nut_renderer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#if !defined(NUT_RENDERER_H) && !defined(DISABLE_SCUMM_7_8)
-#define NUT_RENDERER_H
-
-#include "common/file.h"
-#include "graphics/surface.h"
-
-namespace Scumm {
-
-class ScummEngine;
-
-class NutRenderer {
-protected:
- ScummEngine *_vm;
- bool _loaded;
- int _numChars;
- struct {
- int xoffs;
- int yoffs;
- int width;
- int height;
- byte *src;
- } _chars[256];
-
- void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);
- void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color);
-
-public:
- NutRenderer(ScummEngine *vm);
- virtual ~NutRenderer();
- int getNumChars() const { return _numChars; }
-
- bool loadFont(const char *filename);
-
- void drawFrame(byte *dst, int c, int x, int y);
- void drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow);
-
- int getCharWidth(byte c) const;
- int getCharHeight(byte c) const;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/object.cpp b/scumm/object.cpp
deleted file mode 100644
index 0472edcc15..0000000000
--- a/scumm/object.cpp
+++ /dev/null
@@ -1,1779 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/bomp.h"
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/usage_bits.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
-struct BompHeader { /* Bomp header */
- union {
- struct {
- uint16 unk;
- uint16 width, height;
- } GCC_PACK old;
-
- struct {
- uint32 width, height;
- } GCC_PACK v8;
- } GCC_PACK;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-
-bool ScummEngine::getClass(int obj, int cls) const {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in getClass");
- cls &= 0x7F;
- checkRange(32, 1, cls, "Class %d out of range in getClass");
-
- if (_features & GF_SMALL_HEADER) {
- // Translate the new (V5) object classes to the old classes
- // (for those which differ).
- switch (cls) {
- case kObjectClassUntouchable:
- cls = 24;
- break;
- case kObjectClassPlayer:
- cls = 23;
- break;
- case kObjectClassXFlip:
- cls = 19;
- break;
- case kObjectClassYFlip:
- cls = 18;
- break;
- }
- }
-
- return (_classData[obj] & (1 << (cls - 1))) != 0;
-}
-
-void ScummEngine::putClass(int obj, int cls, bool set) {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in putClass");
- cls &= 0x7F;
- checkRange(32, 1, cls, "Class %d out of range in putClass");
-
- if (_features & GF_SMALL_HEADER) {
- // Translate the new (V5) object classes to the old classes
- // (for those which differ).
- switch (cls) {
- case kObjectClassUntouchable:
- cls = 24;
- break;
- case kObjectClassPlayer:
- cls = 23;
- break;
- case kObjectClassXFlip:
- cls = 19;
- break;
- case kObjectClassYFlip:
- cls = 18;
- break;
- }
- }
-
- if (set)
- _classData[obj] |= (1 << (cls - 1));
- else
- _classData[obj] &= ~(1 << (cls - 1));
-
- if (_version <= 4 && obj >= 1 && obj < _numActors) {
- _actors[obj].classChanged(cls, set);
- }
-}
-
-int ScummEngine::getOwner(int obj) const {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in getOwner");
- return _objectOwnerTable[obj];
-}
-
-void ScummEngine::putOwner(int obj, int owner) {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in putOwner");
- checkRange(0xFF, 0, owner, "Owner %d out of range in putOwner");
- _objectOwnerTable[obj] = owner;
-}
-
-int ScummEngine::getState(int obj) {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in getState");
-
- if (!_copyProtection) {
- // I knew LucasArts sold cracked copies of the original Maniac Mansion,
- // at least as part of Day of the Tentacle. Apparently they also sold
- // cracked versions of the enhanced version. At least in Germany.
- //
- // This will keep the security door open at all times. I can only
- // assume that 182 and 193 each correspond to one particular side of
- // the it. Fortunately it does not prevent frustrated players from
- // blowing up the mansion, should they feel the urge to.
-
- if (_gameId == GID_MANIAC && (obj == 182 || obj == 193))
- _objectStateTable[obj] |= 0x08;
- }
-
- return _objectStateTable[obj];
-}
-
-void ScummEngine::putState(int obj, int state) {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in putState");
- checkRange(0xFF, 0, state, "State %d out of range in putState");
- _objectStateTable[obj] = state;
-}
-
-int ScummEngine::getObjectRoom(int obj) const {
- checkRange(_numGlobalObjects - 1, 0, obj, "Object %d out of range in getObjectRoom");
- return _objectRoomTable[obj];
-}
-
-int ScummEngine::getObjectIndex(int object) const {
- int i;
-
- if (object < 1)
- return -1;
-
- for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_objs[i].obj_nr == object)
- return i;
- }
- return -1;
-}
-
-int ScummEngine::whereIsObject(int object) const {
- int i;
-
- if (object >= _numGlobalObjects)
- return WIO_NOT_FOUND;
-
- if (object < 1)
- return WIO_NOT_FOUND;
-
- if (_objectOwnerTable[object] != OF_OWNER_ROOM) {
- for (i = 0; i < _numInventory; i++)
- if (_inventory[i] == object)
- return WIO_INVENTORY;
- return WIO_NOT_FOUND;
- }
-
- for (i = (_numLocalObjects-1); i > 0; i--)
- if (_objs[i].obj_nr == object) {
- if (_objs[i].fl_object_index)
- return WIO_FLOBJECT;
- return WIO_ROOM;
- }
-
- return WIO_NOT_FOUND;
-}
-
-int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
- if (object < _numActors) {
- Actor *act = derefActorSafe(object, "getObjectOrActorXY");
- if (act)
- return act->getActorXYPos(x, y);
- else
- return -1;
- }
-
- switch (whereIsObject(object)) {
- case WIO_NOT_FOUND:
- return -1;
- case WIO_INVENTORY:
- if (_objectOwnerTable[object] < _numActors)
- return derefActor(_objectOwnerTable[object], "getObjectOrActorXY(2)")->getActorXYPos(x, y);
- else
- return -1;
- }
- getObjectXYPos(object, x, y);
- return 0;
-}
-
-/**
- * Return the position of an object.
- * Returns X, Y and direction in angles
- */
-void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
- int idx = getObjectIndex(object);
- assert(idx >= 0);
- ObjectData &od = _objs[idx];
- int state;
- const byte *ptr;
- const ImageHeader *imhd;
-
- if (_version >= 6) {
- state = getState(object) - 1;
- if (state < 0)
- state = 0;
-
- ptr = getOBIMFromObjectData(od);
- if (!ptr) {
- // FIXME: We used to assert here, but it seems that in the nexus
- // in The Dig, this can happen, at least with old savegames, and
- // it's safe to continue...
- debug(0, "getObjectXYPos: Can't find object %d", object);
- return;
- }
- imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), ptr);
- assert(imhd);
- if (_version == 8) {
- switch (FROM_LE_32(imhd->v8.version)) {
- case 800:
- x = od.x_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x44);
- y = od.y_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x48);
- break;
- case 801:
- x = od.x_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].x);
- y = od.y_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].y);
- break;
- default:
- error("Unsupported image header version %d\n", FROM_LE_32(imhd->v8.version));
- }
- } else if (_version == 7) {
- x = od.x_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].x);
- y = od.y_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].y);
- } else {
- x = od.x_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].x);
- y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y);
- }
- } else {
- x = od.walk_x;
- y = od.walk_y;
- }
- if (_version == 8)
- dir = fromSimpleDir(1, od.actordir);
- else
- dir = oldDirToNewDir(od.actordir & 3);
-}
-
-static int getDist(int x, int y, int x2, int y2) {
- int a = ABS(y - y2);
- int b = ABS(x - x2);
- return MAX(a, b);
-}
-
-int ScummEngine::getObjActToObjActDist(int a, int b) {
- int x, y, x2, y2;
- Actor *acta = NULL;
- Actor *actb = NULL;
-
- if (a < _numActors)
- acta = derefActorSafe(a, "getObjActToObjActDist");
-
- if (b < _numActors)
- actb = derefActorSafe(b, "getObjActToObjActDist(2)");
-
- if (acta && actb && acta->getRoom() == actb->getRoom() && acta->getRoom() && !acta->isInCurrentRoom())
- return 0;
-
- if (getObjectOrActorXY(a, x, y) == -1)
- return 0xFF;
-
- if (getObjectOrActorXY(b, x2, y2) == -1)
- return 0xFF;
-
- // Perform adjustXYToBeInBox() *only* if the first item is an
- // actor and the second is an object. This used to not check
- // whether the second item is a non-actor, which caused bug
- // #853874).
- if (acta && !actb) {
- AdjustBoxResult r = acta->adjustXYToBeInBox(x2, y2);
- x2 = r.x;
- y2 = r.y;
- }
-
- // Now compute the distance between the two points
- if (_version <= 2) {
- // For V1/V2 games, distances are measured in the original "character"
- // based coordinate system, instead of pixels. Otherwise various scripts
- // will break. See bugs #853874, #774529
- x /= 8;
- y /= 2;
- x2 /= 8;
- y2 /= 2;
- }
-
- return getDist(x, y, x2, y2);
-}
-
-int ScummEngine::findObject(int x, int y) {
- int i, b;
- byte a;
- const int mask = (_version <= 2) ? 0x8 : 0xF;
-
- for (i = 1; i < _numLocalObjects; i++) {
- if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable))
- continue;
-
- if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
- if (_objs[i].flags == 0 && _objs[i].state & 0x2)
- continue;
- } else {
- if (_version <= 2 && _objs[i].state & 0x2)
- continue;
- }
-
- b = i;
- do {
- a = _objs[b].parentstate;
- b = _objs[b].parent;
- if (b == 0) {
-#ifndef DISABLE_HE
- if (_heversion >= 70) {
- if (((ScummEngine_v70he *)this)->_wiz->polygonHit(_objs[i].obj_nr, x, y))
- return _objs[i].obj_nr;
- }
-#endif
- if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&
- _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y)
- return _objs[i].obj_nr;
- break;
- }
- } while ((_objs[b].state & mask) == a);
- }
-
- return 0;
-}
-
-void ScummEngine::drawRoomObject(int i, int arg) {
- ObjectData *od;
- byte a;
- const int mask = (_version <= 2) ? 0x8 : 0xF;
-
- od = &_objs[i];
- if ((i < 1) || (od->obj_nr < 1) || !od->state)
- return;
-
- do {
- a = od->parentstate;
- if (!od->parent) {
- if (_version <= 6 || od->fl_object_index == 0)
- drawObject(i, arg);
- break;
- }
- od = &_objs[od->parent];
- } while ((od->state & mask) == a);
-}
-
-void ScummEngine::drawRoomObjects(int arg) {
- int i;
- const int mask = (_version <= 2) ? 0x8 : 0xF;
-
- if (_heversion >= 60) {
- // In HE games, normal objects are drawn, followed by FlObjects.
- for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_objs[i].obj_nr > 0 && (_objs[i].state & mask) && _objs[i].fl_object_index == 0)
- drawRoomObject(i, arg);
- }
- for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_objs[i].obj_nr > 0 && (_objs[i].state & mask) && _objs[i].fl_object_index != 0)
- drawRoomObject(i, arg);
- }
- } else if (_gameId == GID_SAMNMAX) {
- // In Sam & Max, objects are drawn in reverse order.
- for (i = 1; i < _numLocalObjects; i++)
- if (_objs[i].obj_nr > 0)
- drawRoomObject(i, arg);
- } else {
- for (i = (_numLocalObjects-1); i > 0; i--)
- if (_objs[i].obj_nr > 0 && (_objs[i].state & mask)) {
- drawRoomObject(i, arg);
- }
- }
-}
-
-static const uint32 IMxx_tags[] = {
- MKID('IM00'),
- MKID('IM01'),
- MKID('IM02'),
- MKID('IM03'),
- MKID('IM04'),
- MKID('IM05'),
- MKID('IM06'),
- MKID('IM07'),
- MKID('IM08'),
- MKID('IM09'),
- MKID('IM0A'),
- MKID('IM0B'),
- MKID('IM0C'),
- MKID('IM0D'),
- MKID('IM0E'),
- MKID('IM0F'),
- MKID('IM10')
-};
-
-void ScummEngine::drawObject(int obj, int arg) {
- if (_skipDrawObject)
- return;
-
- ObjectData &od = _objs[obj];
- int height, width;
- const byte *ptr;
- int x, a, numstrip;
- int tmp;
-
- if (_bgNeedsRedraw)
- arg = 0;
-
- if (od.obj_nr == 0)
- return;
-
- checkRange(_numGlobalObjects - 1, 0, od.obj_nr, "Object %d out of range in drawObject");
-
- const int xpos = od.x_pos / 8;
- const int ypos = od.y_pos;
-
- width = od.width / 8;
- height = od.height &= 0xFFFFFFF8; // Mask out last 3 bits
-
- // Short circuit for objects which aren't visible at all.
- if (width == 0 || xpos > _screenEndStrip || xpos + width < _screenStartStrip)
- return;
-
- ptr = getOBIMFromObjectData(od);
-
- if (_features & GF_OLD_BUNDLE)
- ptr += 0;
- else
- ptr = getObjectImage(ptr, getState(od.obj_nr));
-
- if (!ptr)
- return;
-
- x = 0xFFFF;
-
- for (a = numstrip = 0; a < width; a++) {
- tmp = xpos + a;
- if (tmp < _screenStartStrip || _screenEndStrip < tmp)
- continue;
- if (arg > 0 && _screenStartStrip + arg <= tmp)
- continue;
- if (arg < 0 && tmp <= _screenEndStrip + arg)
- continue;
- setGfxUsageBit(tmp, USAGE_BIT_DIRTY);
- if (tmp < x)
- x = tmp;
- numstrip++;
- }
-
- if (numstrip != 0) {
- byte flags = od.flags | Gdi::dbObjectMode;
-
- // Sam & Max needs this to fix object-layering problems with
- // the inventory and conversation icons.
- if ((_gameId == GID_SAMNMAX && getClass(od.obj_nr, kObjectClassIgnoreBoxes)) ||
- (_gameId == GID_FT && getClass(od.obj_nr, kObjectClassPlayer)))
- flags |= Gdi::dbDrawMaskOnAll;
-
- if (_heversion >= 70 && findResource(MKID('SMAP'), ptr) == NULL)
- gdi.drawBMAPObject(ptr, &virtscr[0], obj, od.x_pos, od.y_pos, od.width, od.height);
- else
- gdi.drawBitmap(ptr, &virtscr[0], x, ypos, width * 8, height, x - xpos, numstrip, flags);
- }
-}
-
-void ScummEngine::clearRoomObjects() {
- int i;
-
- if (_features & GF_SMALL_HEADER) {
- for (i = 0; i < _numLocalObjects; i++) {
- _objs[i].obj_nr = 0;
- }
- } else {
- storeFlObject(-1);
-
- for (i = 0; i < _numLocalObjects; i++) {
- if (_objs[i].obj_nr < 1) // Optimise codepath
- continue;
-
- // Nuke all non-flObjects (flObjects are nuked in script.cpp)
- if (_objs[i].fl_object_index == 0) {
- _objs[i].obj_nr = 0;
- } else {
- // Nuke all unlocked flObjects
- if (!res.isLocked(rtFlObject, _objs[i].fl_object_index)) {
- res.nukeResource(rtFlObject, _objs[i].fl_object_index);
- _objs[i].obj_nr = 0;
- _objs[i].fl_object_index = 0;
- } else if (_heversion >= 70) {
- storeFlObject(i);
- _objs[i].obj_nr = 0;
- _objs[i].fl_object_index = 0;
- }
- }
- }
- }
-}
-
-void ScummEngine::storeFlObject(int slot) {
- if (slot == -1) {
- _numStoredFlObjects = 0;
- } else {
- memcpy(&_storedFlObjects[_numStoredFlObjects], &_objs[slot], sizeof(_objs[slot]));
- _numStoredFlObjects++;
- if (_numStoredFlObjects > 100)
- error("Too many flobjects saved on room transition.");
- }
-}
-
-void ScummEngine::restoreFlObjects() {
- if (!_numStoredFlObjects)
- return;
-
- int i, slot;
-
- for (i = 0; i < _numStoredFlObjects; i++) {
- slot = findLocalObjectSlot();
- memcpy(&_objs[slot], &_storedFlObjects[i], sizeof(_objs[slot]));
- }
-
- _numStoredFlObjects = 0;
-}
-
-void ScummEngine::loadRoomObjects() {
- int i, j;
- ObjectData *od;
- const byte *ptr;
- uint16 obim_id;
- const byte *room, *searchptr, *rootptr;
- const CodeHeader *cdhd;
-
- CHECK_HEAP
- room = getResourceAddress(rtRoom, _roomResource);
-
- if (_numObjectsInRoom == 0)
- return;
-
- if (_numObjectsInRoom > _numLocalObjects)
- error("More than %d objects in room %d", _numLocalObjects, _roomResource);
-
- if (_version == 8)
- searchptr = rootptr = getResourceAddress(rtRoomScripts, _roomResource);
- else
- searchptr = rootptr = room;
- assert(searchptr);
-
- // Load in new room objects
- ResourceIterator obcds(searchptr, false);
- for (i = 0; i < _numObjectsInRoom; i++) {
- od = &_objs[findLocalObjectSlot()];
-
- ptr = obcds.findNext(MKID('OBCD'));
- if (ptr == NULL)
- error("Room %d missing object code block(s)", _roomResource);
-
- od->OBCDoffset = ptr - rootptr;
- cdhd = (const CodeHeader *)findResourceData(MKID('CDHD'), ptr);
-
- if (_version >= 7)
- od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id));
- else if (_version == 6)
- od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id));
- else
- od->obj_nr = READ_LE_UINT16(&(cdhd->v5.obj_id));
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "roomobj-%d-", _roomResource);
- ptr = findResource(MKID('VERB'), ptr);
- dumpResource(buf, od->obj_nr, ptr);
- }
-
- }
-
- searchptr = room;
- ResourceIterator obims(room, false);
- for (i = 0; i < _numObjectsInRoom; i++) {
- ptr = obims.findNext(MKID('OBIM'));
- if (ptr == NULL)
- error("Room %d missing image blocks(s)", _roomResource);
-
- obim_id = getObjectIdFromOBIM(ptr);
-
- for (j = 1; j < _numLocalObjects; j++) {
- if (_objs[j].obj_nr == obim_id)
- _objs[j].OBIMoffset = ptr - room;
- }
- }
-
- for (i = 1; i < _numLocalObjects; i++) {
- if (_objs[i].obj_nr && !_objs[i].fl_object_index)
- setupRoomObject(&_objs[i], room);
- }
-
- CHECK_HEAP
-}
-
-void ScummEngine_v3old::loadRoomObjects() {
- int i;
- ObjectData *od;
- const byte *room, *ptr;
-
- CHECK_HEAP
- room = getResourceAddress(rtRoom, _roomResource);
-
- if (_numObjectsInRoom == 0)
- return;
-
- if (_numObjectsInRoom > _numLocalObjects)
- error("More than %d objects in room %d", _numLocalObjects, _roomResource);
-
- if (_version <= 2)
- ptr = room + 28;
- else
- ptr = room + 29;
-
- for (i = 0; i < _numObjectsInRoom; i++) {
- od = &_objs[findLocalObjectSlot()];
-
- od->OBIMoffset = READ_LE_UINT16(ptr);
- od->OBCDoffset = READ_LE_UINT16(ptr + 2 * _numObjectsInRoom);
- setupRoomObject(od, room);
-
- ptr += 2;
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "roomobj-%d-", _roomResource);
- dumpResource(buf, od->obj_nr, room + od->OBCDoffset);
- }
- }
-
- CHECK_HEAP
-}
-
-void ScummEngine_v4::loadRoomObjects() {
- int i, j;
- ObjectData *od;
- const byte *ptr;
- uint16 obim_id;
- const byte *room;
-
- CHECK_HEAP
- room = getResourceAddress(rtRoom, _roomResource);
-
- if (_numObjectsInRoom == 0)
- return;
-
- if (_numObjectsInRoom > _numLocalObjects)
- error("More than %d objects in room %d", _numLocalObjects, _roomResource);
-
- ResourceIterator obcds(room, true);
- for (i = 0; i < _numObjectsInRoom; i++) {
- od = &_objs[findLocalObjectSlot()];
-
- ptr = obcds.findNext(MKID('OBCD'));
- if (ptr == NULL)
- error("Room %d missing object code block(s)", _roomResource);
-
- od->OBCDoffset = ptr - room;
- od->obj_nr = READ_LE_UINT16(ptr + 6);
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "roomobj-%d-", _roomResource);
- dumpResource(buf, od->obj_nr, ptr);
- }
- }
-
- ResourceIterator obims(room, true);
- for (i = 0; i < _numObjectsInRoom; i++) {
- ptr = obims.findNext(MKID('OBIM'));
- if (ptr == NULL)
- error("Room %d missing image blocks(s)", _roomResource);
-
- obim_id = READ_LE_UINT16(ptr + 6);
-
- for (j = 1; j < _numLocalObjects; j++) {
- if (_objs[j].obj_nr == obim_id)
- _objs[j].OBIMoffset = ptr - room;
- }
- }
-
- for (i = 1; i < _numLocalObjects; i++) {
- if (_objs[i].obj_nr && !_objs[i].fl_object_index) {
- setupRoomObject(&_objs[i], room);
- }
- }
-
- CHECK_HEAP
-}
-
-void ScummEngine_c64::setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr) {
- assert(room);
- const byte *ptr = room + od->OBCDoffset;
- ptr -= 2;
-
- od->obj_nr = *(ptr + 6);
- od->flags = *(ptr + 7);
-
- od->x_pos = *(ptr + 8) * 8;
- od->y_pos = ((*(ptr + 9)) & 0x7F) * 8;
-
- od->parentstate = (*(ptr + 9) & 0x80) ? 1 : 0;
- od->parentstate *= 8;
-
- od->width = *(ptr + 10) * 8;
-
- od->parent = *(ptr + 11);
-
- od->walk_x = *(ptr + 12) * 8;
- od->walk_y = (*(ptr + 13) & 0x1f) * 8;
- od->actordir = (*(ptr + 14)) & 7;
- od->height = *(ptr + 14) & 0xf8;
-}
-
-void ScummEngine_v4::setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr) {
- assert(room);
- const byte *ptr = room + od->OBCDoffset;
-
- if (_features & GF_OLD_BUNDLE)
- ptr -= 2;
-
- od->obj_nr = READ_LE_UINT16(ptr + 6);
-
- od->x_pos = *(ptr + 9) * 8;
- od->y_pos = ((*(ptr + 10)) & 0x7F) * 8;
-
- od->parentstate = (*(ptr + 10) & 0x80) ? 1 : 0;
- if (_version <= 2)
- od->parentstate *= 8;
-
- od->width = *(ptr + 11) * 8;
-
- od->parent = *(ptr + 12);
-
- if (_version <= 2) {
- od->walk_x = *(ptr + 13) * 8;
- od->walk_y = (*(ptr + 14) & 0x1f) * 8;
- od->actordir = (*(ptr + 15)) & 7;
- od->height = *(ptr + 15) & 0xf8;
- } else {
- od->walk_x = READ_LE_UINT16(ptr + 13);
- od->walk_y = READ_LE_UINT16(ptr + 15);
- od->actordir = (*(ptr + 17)) & 7;
- od->height = *(ptr + 17) & 0xf8;
- }
-}
-
-void ScummEngine::setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr) {
- const CodeHeader *cdhd = NULL;
- const ImageHeader *imhd = NULL;
-
- assert(room);
-
- if (searchptr == NULL) {
- if (_version == 8)
- searchptr = getResourceAddress(rtRoomScripts, _roomResource);
- else
- searchptr = room;
- }
-
- cdhd = (const CodeHeader *)findResourceData(MKID('CDHD'), searchptr + od->OBCDoffset);
- if (cdhd == NULL)
- error("Room %d missing CDHD blocks(s)", _roomResource);
- if (od->OBIMoffset)
- imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), room + od->OBIMoffset);
-
- od->flags = Gdi::dbAllowMaskOr;
-
- if (_version == 8) {
- od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id));
-
- od->parent = cdhd->v7.parent;
- od->parentstate = cdhd->v7.parentstate;
-
- od->x_pos = (int)READ_LE_UINT32(&imhd->v8.x_pos);
- od->y_pos = (int)READ_LE_UINT32(&imhd->v8.y_pos);
- od->width = (uint)READ_LE_UINT32(&imhd->v8.width);
- od->height = (uint)READ_LE_UINT32(&imhd->v8.height);
- // HACK: This is done since an angle doesn't fit into a byte (360 > 256)
- od->actordir = toSimpleDir(1, READ_LE_UINT32(&imhd->v8.actordir));
- if (FROM_LE_32(imhd->v8.version) == 801)
- od->flags = ((((byte)READ_LE_UINT32(&imhd->v8.flags)) & 16) == 0) ? Gdi::dbAllowMaskOr : 0;
-
- } else if (_version == 7) {
- od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id));
-
- od->parent = cdhd->v7.parent;
- od->parentstate = cdhd->v7.parentstate;
-
- od->x_pos = READ_LE_UINT16(&imhd->v7.x_pos);
- od->y_pos = READ_LE_UINT16(&imhd->v7.y_pos);
- od->width = READ_LE_UINT16(&imhd->v7.width);
- od->height = READ_LE_UINT16(&imhd->v7.height);
- od->actordir = (byte)READ_LE_UINT16(&imhd->v7.actordir);
-
- } else if (_version == 6) {
- od->obj_nr = READ_LE_UINT16(&(cdhd->v6.obj_id));
-
- od->width = READ_LE_UINT16(&cdhd->v6.w);
- od->height = READ_LE_UINT16(&cdhd->v6.h);
- od->x_pos = ((int16)READ_LE_UINT16(&cdhd->v6.x));
- od->y_pos = ((int16)READ_LE_UINT16(&cdhd->v6.y));
- if (cdhd->v6.flags == 0x80) {
- od->parentstate = 1;
- } else {
- od->parentstate = (cdhd->v6.flags & 0xF);
- }
- od->parent = cdhd->v6.parent;
- od->actordir = cdhd->v6.actordir;
-
- if (_heversion >= 60 && imhd)
- od->flags = ((imhd->old.flags & 1) != 0) ? Gdi::dbAllowMaskOr : 0;
-
- } else {
- od->obj_nr = READ_LE_UINT16(&(cdhd->v5.obj_id));
-
- od->width = cdhd->v5.w * 8;
- od->height = cdhd->v5.h * 8;
- od->x_pos = cdhd->v5.x * 8;
- od->y_pos = cdhd->v5.y * 8;
- if (cdhd->v5.flags == 0x80) {
- od->parentstate = 1;
- } else {
- od->parentstate = (cdhd->v5.flags & 0xF);
- }
- od->parent = cdhd->v5.parent;
- od->walk_x = READ_LE_UINT16(&cdhd->v5.walk_x);
- od->walk_y = READ_LE_UINT16(&cdhd->v5.walk_y);
- od->actordir = cdhd->v5.actordir;
- }
-
- od->fl_object_index = 0;
-}
-
-void ScummEngine::updateObjectStates() {
- int i;
- ObjectData *od = &_objs[1];
- for (i = 1; i < _numLocalObjects; i++, od++) {
- if (od->obj_nr > 0)
- od->state = getState(od->obj_nr);
- }
-}
-
-void ScummEngine::processDrawQue() {
- int i, j;
- for (i = 0; i < _drawObjectQueNr; i++) {
- j = _drawObjectQue[i];
- if (j)
- drawObject(j, 0);
- }
- _drawObjectQueNr = 0;
-}
-
-void ScummEngine::addObjectToDrawQue(int object) {
- if ((unsigned int)_drawObjectQueNr >= ARRAYSIZE(_drawObjectQue))
- error("Draw Object Que overflow");
- _drawObjectQue[_drawObjectQueNr++] = object;
-}
-
-void ScummEngine::removeObjectFromDrawQue(int object) {
- if (_drawObjectQueNr <= 0)
- return;
-
- int i;
- for (i = 0; i < _drawObjectQueNr; i++) {
- if (_drawObjectQue[i] == object)
- _drawObjectQue[i] = 0;
- }
-}
-
-void ScummEngine::clearDrawObjectQueue() {
- _drawObjectQueNr = 0;
-}
-
-void ScummEngine::clearDrawQueues() {
- clearDrawObjectQueue();
-}
-
-void ScummEngine_v6::clearDrawQueues() {
- ScummEngine::clearDrawQueues();
-
- _blastObjectQueuePos = 0;
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v70he::clearDrawQueues() {
- ScummEngine_v6::clearDrawQueues();
-
- _wiz->polygonClear();
-}
-
-void ScummEngine_v80he::clearDrawQueues() {
- ScummEngine_v70he::clearDrawQueues();
-
- _wiz->clearWizBuffer();
-}
-#endif
-
-void ScummEngine::clearOwnerOf(int obj) {
- int i, j;
- uint16 *a;
-
- stopObjectScript(obj);
-
- if (getOwner(obj) == OF_OWNER_ROOM) {
- i = 0;
- do {
- if (_objs[i].obj_nr == obj) {
- if (!_objs[i].fl_object_index)
- return;
- res.nukeResource(rtFlObject, _objs[i].fl_object_index);
- _objs[i].obj_nr = 0;
- _objs[i].fl_object_index = 0;
- }
- } while (++i < _numLocalObjects);
- return;
- }
-
- for (i = 0; i < _numInventory; i++) {
- if (_inventory[i] == obj) {
- j = whereIsObject(obj);
- if (j == WIO_INVENTORY) {
- res.nukeResource(rtInventory, i);
- _inventory[i] = 0;
- }
- a = _inventory;
- for (i = 0; i < _numInventory - 1; i++, a++) {
- if (!a[0] && a[1]) {
- a[0] = a[1];
- a[1] = 0;
- res.address[rtInventory][i] = res.address[rtInventory][i + 1];
- res.address[rtInventory][i + 1] = NULL;
- }
- }
- return;
- }
- }
-}
-
-/**
- * Mark the rectangle covered by the given object as dirty, thus eventually
- * ensuring a redraw of that area. This function is typically invoked when an
- * object gets removed from the current room, or when its state changed.
- */
-void ScummEngine::markObjectRectAsDirty(int obj) {
- int i, strip;
-
- for (i = 1; i < _numLocalObjects; i++) {
- if (_objs[i].obj_nr == (uint16)obj) {
- if (_objs[i].width != 0) {
- const int minStrip = MAX(_screenStartStrip, _objs[i].x_pos / 8);
- const int maxStrip = MIN(_screenEndStrip+1, _objs[i].x_pos / 8 + _objs[i].width / 8);
- for (strip = minStrip; strip < maxStrip; strip++) {
- setGfxUsageBit(strip, USAGE_BIT_DIRTY);
- }
- }
- _bgNeedsRedraw = true;
- return;
- }
- }
-}
-
-const byte *ScummEngine::getObjOrActorName(int obj) {
- byte *objptr;
- int i;
-
- if (obj < _numActors)
- return derefActor(obj, "getObjOrActorName")->getActorName();
-
- for (i = 0; i < _numNewNames; i++) {
- if (_newNames[i] == obj) {
- debug(5, "Found new name for object %d at _newNames[%d]", obj, i);
- return getResourceAddress(rtObjectName, i);
- }
- }
-
- objptr = getOBCDFromObject(obj);
- if (objptr == NULL)
- return NULL;
-
- if (_features & GF_SMALL_HEADER) {
- byte offset = 0;
-
- if (_version <= 2)
- offset = *(objptr + 14);
- else if (_features & GF_OLD_BUNDLE)
- offset = *(objptr + 16);
- else
- offset = *(objptr + 18);
-
- return (objptr + offset);
- }
-
- return findResourceData(MKID('OBNA'), objptr);
-}
-
-void ScummEngine::setObjectName(int obj) {
- int i;
-
- if (obj < _numActors)
- error("Can't set actor %d name with new-name-of", obj);
-
- for (i = 0; i < _numNewNames; i++) {
- if (_newNames[i] == obj) {
- res.nukeResource(rtObjectName, i);
- _newNames[i] = 0;
- break;
- }
- }
-
- for (i = 0; i < _numNewNames; i++) {
- if (_newNames[i] == 0) {
- loadPtrToResource(rtObjectName, i, NULL);
- _newNames[i] = obj;
- runInventoryScript(0);
- return;
- }
- }
-
- error("New name of %d overflows name table (max = %d)", obj, _numNewNames);
-}
-
-uint32 ScummEngine::getOBCDOffs(int object) const {
- int i;
-
- if (_objectOwnerTable[object] != OF_OWNER_ROOM)
- return 0;
- for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_objs[i].obj_nr == object) {
- if (_objs[i].fl_object_index != 0)
- return 8;
- return _objs[i].OBCDoffset;
- }
- }
- return 0;
-}
-
-byte *ScummEngine::getOBCDFromObject(int obj) {
- int i;
- byte *ptr;
-
- if (_objectOwnerTable[obj] != OF_OWNER_ROOM) {
- for (i = 0; i < _numInventory; i++) {
- if (_inventory[i] == obj)
- return getResourceAddress(rtInventory, i);
- }
- } else {
- for (i = (_numLocalObjects-1); i > 0; --i) {
- if (_objs[i].obj_nr == obj) {
- if (_objs[i].fl_object_index) {
- assert(_objs[i].OBCDoffset == 8);
- ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index);
- } else if (_version == 8)
- ptr = getResourceAddress(rtRoomScripts, _roomResource);
- else
- ptr = getResourceAddress(rtRoom, _roomResource);
- assert(ptr);
- return ptr + _objs[i].OBCDoffset;
- }
- }
- }
- return 0;
-}
-
-const byte *ScummEngine::getOBIMFromObjectData(const ObjectData &od) {
- const byte *ptr;
-
- if (od.fl_object_index) {
- ptr = getResourceAddress(rtFlObject, od.fl_object_index);
- ptr = findResource(MKID('OBIM'), ptr);
- } else {
- ptr = getResourceAddress(rtRoom, _roomResource);
- if (ptr)
- ptr += od.OBIMoffset;
- }
- return ptr;
-}
-
-const byte *ScummEngine::getObjectImage(const byte *ptr, int state) {
- assert(ptr);
- if (_features & GF_OLD_BUNDLE)
- ptr += 0;
- else if (_features & GF_SMALL_HEADER) {
- ptr += 8;
- } else if (_version == 8) {
- // The OBIM contains an IMAG, which in turn contains a WRAP, which contains
- // an OFFS chunk and multiple BOMP/SMAP chunks. To find the right BOMP/SMAP,
- // we use the offsets in the OFFS chunk,
- ptr = findResource(MKID('IMAG'), ptr);
- if (!ptr)
- return 0;
-
- ptr = findResource(MKID('WRAP'), ptr);
- if (!ptr)
- return 0;
-
- ptr = findResource(MKID('OFFS'), ptr);
- if (!ptr)
- return 0;
-
- // Get the address of the specified SMAP (corresponding to IMxx)
- ptr += READ_LE_UINT32(ptr + 4 + 4*state);
- } else {
- ptr = findResource(IMxx_tags[state], ptr);
- }
-
- return ptr;
-}
-
-int ScummEngine::getObjectImageCount(int object) {
- const byte *ptr;
- const ImageHeader *imhd;
- int objnum;
-
- objnum = getObjectIndex(object);
- if (objnum == -1)
- return 0;
-
- ptr = getOBIMFromObjectData(_objs[objnum]);
- imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), ptr);
- if (!imhd)
- return 0;
-
- if (_version == 8) {
- return (READ_LE_UINT32(&imhd->v8.image_count));
- } else if (_version == 7) {
- return(READ_LE_UINT16(&imhd->v7.image_count));
- } else {
- return (READ_LE_UINT16(&imhd->old.image_count));
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-int ScummEngine_v8::getObjectIdFromOBIM(const byte *obim) {
- // In V8, IMHD has no obj_id, but rather a name string. We map the name
- // back to an object id using a table derived from the DOBJ resource.
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), obim);
- ObjectNameId *found = (ObjectNameId *)bsearch(imhd->v8.name, _objectIDMap, _objectIDMapSize,
- sizeof(ObjectNameId), (int (*)(const void*, const void*))strcmp);
- assert(found);
- return found->id;
-}
-
-int ScummEngine_v7::getObjectIdFromOBIM(const byte *obim) {
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), obim);
- return READ_LE_UINT16(&imhd->v7.obj_id);
-}
-#endif
-
-int ScummEngine::getObjectIdFromOBIM(const byte *obim) {
- if (_features & GF_SMALL_HEADER)
- return READ_LE_UINT16(obim + 6);
-
- const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), obim);
- return READ_LE_UINT16(&imhd->old.obj_id);
-}
-
-void ScummEngine::addObjectToInventory(uint obj, uint room) {
- int idx, slot;
- uint32 size;
- const byte *ptr;
- byte *dst;
- FindObjectInRoom foir;
-
- debug(1, "Adding object %d from room %d into inventory", obj, room);
-
- CHECK_HEAP
- if (whereIsObject(obj) == WIO_FLOBJECT) {
- idx = getObjectIndex(obj);
- assert(idx >= 0);
- ptr = getResourceAddress(rtFlObject, _objs[idx].fl_object_index) + 8;
- size = READ_BE_UINT32(ptr + 4);
- } else {
- findObjectInRoom(&foir, foCodeHeader, obj, room);
- if (_features & GF_OLD_BUNDLE)
- size = READ_LE_UINT16(foir.obcd);
- else if (_features & GF_SMALL_HEADER)
- size = READ_LE_UINT32(foir.obcd);
- else
- size = READ_BE_UINT32(foir.obcd + 4);
- ptr = foir.obcd;
- }
-
- slot = getInventorySlot();
- _inventory[slot] = obj;
- dst = res.createResource(rtInventory, slot, size);
- assert(dst);
- memcpy(dst, ptr, size);
-
- CHECK_HEAP
-}
-
-void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint room) {
-
- const CodeHeader *cdhd;
- int i, numobj;
- const byte *roomptr, *obcdptr, *obimptr, *searchptr;
- int id2;
- int obim_id;
-
- id2 = getObjectIndex(id);
- if (findWhat & foCheckAlreadyLoaded && id2 != -1) {
- assert(_version >= 6);
- if (findWhat & foCodeHeader) {
- fo->obcd = obcdptr = getOBCDFromObject(id);
- assert(obcdptr);
- fo->cdhd = (const CodeHeader *)findResourceData(MKID('CDHD'), obcdptr);
- }
- if (findWhat & foImageHeader) {
- fo->obim = obimptr = getOBIMFromObjectData(_objs[id2]);
- assert(obimptr);
- }
- return;
- }
-
- fo->roomptr = roomptr = getResourceAddress(rtRoom, room);
- if (!roomptr)
- error("findObjectInRoom: failed getting roomptr to %d", room);
-
- if (_features & GF_OLD_BUNDLE) {
- numobj = roomptr[20];
- } else {
- const RoomHeader *roomhdr = (const RoomHeader *)findResourceData(MKID('RMHD'), roomptr);
-
- if (_version == 8)
- numobj = READ_LE_UINT32(&(roomhdr->v8.numObjects));
- else if (_version == 7)
- numobj = READ_LE_UINT16(&(roomhdr->v7.numObjects));
- else
- numobj = READ_LE_UINT16(&(roomhdr->old.numObjects));
- }
-
- if (numobj == 0)
- error("findObjectInRoom: No object found in room %d", room);
- if (numobj > _numLocalObjects)
- error("findObjectInRoom: More (%d) than %d objects in room %d", numobj, _numLocalObjects, room);
-
- if (_features & GF_OLD_BUNDLE) {
- if (_version <= 2)
- searchptr = roomptr + 28;
- else
- searchptr = roomptr + 29;
-
- for (i = 0; i < numobj; i++) {
- obimptr = roomptr + READ_LE_UINT16(searchptr);
- obcdptr = roomptr + READ_LE_UINT16(searchptr + 2 * numobj);
- id2 = READ_LE_UINT16(obcdptr + 4);
-
- if (id2 == (uint16)id) {
- if (findWhat & foCodeHeader) {
- fo->obcd = obcdptr;
- fo->cdhd = (const CodeHeader *)(obcdptr + 10); // TODO - FIXME
- }
- if (findWhat & foImageHeader) {
- fo->obim = obimptr;
- }
- break;
- }
- searchptr += 2;
- }
- return;
- }
-
- if (findWhat & foCodeHeader) {
- if (_version == 8)
- searchptr = getResourceAddress(rtRoomScripts, room);
- else
- searchptr = roomptr;
- assert(searchptr);
- ResourceIterator obcds(searchptr, (_features & GF_SMALL_HEADER) != 0);
- for (i = 0; i < numobj; i++) {
- obcdptr = obcds.findNext(MKID('OBCD'));
- if (obcdptr == NULL)
- error("findObjectInRoom: Not enough code blocks in room %d", room);
- cdhd = (const CodeHeader *)findResourceData(MKID('CDHD'), obcdptr);
-
- if (_features & GF_SMALL_HEADER)
- id2 = READ_LE_UINT16(obcdptr + 6);
- else if (_version >= 7)
- id2 = READ_LE_UINT16(&(cdhd->v7.obj_id));
- else if (_version == 6)
- id2 = READ_LE_UINT16(&(cdhd->v6.obj_id));
- else
- id2 = READ_LE_UINT16(&(cdhd->v5.obj_id));
-
- if (id2 == (uint16)id) {
- fo->obcd = obcdptr;
- fo->cdhd = cdhd;
- break;
- }
- }
- if (i == numobj)
- error("findObjectInRoom: Object %d not found in room %d", id, room);
- }
-
- roomptr = fo->roomptr;
- if (findWhat & foImageHeader) {
- ResourceIterator obims(roomptr, (_features & GF_SMALL_HEADER) != 0);
- for (i = 0; i < numobj; i++) {
- obimptr = obims.findNext(MKID('OBIM'));
- if (obimptr == NULL)
- error("findObjectInRoom: Not enough image blocks in room %d", room);
- obim_id = getObjectIdFromOBIM(obimptr);
-
- if (obim_id == (uint16)id) {
- fo->obim = obimptr;
- break;
- }
- }
- if (i == numobj)
- error("findObjectInRoom: Object %d image not found in room %d", id, room);
- }
-}
-
-int ScummEngine::getInventorySlot() {
- int i;
- for (i = 0; i < _numInventory; i++) {
- if (_inventory[i] == 0)
- return i;
- }
- error("Inventory full, %d max items", _numInventory);
- return -1;
-}
-
-void ScummEngine::setOwnerOf(int obj, int owner) {
- ScriptSlot *ss;
-
- // In Sam & Max this is necessary, or you won't get your stuff back
- // from the Lost and Found tent after riding the Cone of Tragedy. But
- // it probably applies to all V6+ games. See bugs #493153 and #907113.
- // FT disassembly is checked, behaviour is correct. [sev]
-
- int arg = (_version >= 6) ? obj : 0;
-
- if (owner == 0) {
- clearOwnerOf(obj);
- ss = &vm.slot[_currentScript];
- if (ss->where == WIO_INVENTORY && _inventory[ss->number] == obj) {
- putOwner(obj, 0);
- runInventoryScript(arg);
- stopObjectCode();
- return;
- }
- }
-
- putOwner(obj, owner);
- runInventoryScript(arg);
-}
-
-int ScummEngine::getObjX(int obj) {
- if (obj < _numActors) {
- if (obj < 1)
- return 0; /* fix for indy4's map */
- return derefActor(obj, "getObjX")->_pos.x;
- } else {
- if (whereIsObject(obj) == WIO_NOT_FOUND)
- return -1;
- int x, y;
- getObjectOrActorXY(obj, x, y);
- return x;
- }
-}
-
-int ScummEngine::getObjY(int obj) {
- if (obj < _numActors) {
- if (obj < 1)
- return 0; /* fix for indy4's map */
- return derefActor(obj, "getObjY")->_pos.y;
- } else {
- if (whereIsObject(obj) == WIO_NOT_FOUND)
- return -1;
- int x, y;
- getObjectOrActorXY(obj, x, y);
- return y;
- }
-}
-
-int ScummEngine::getObjOldDir(int obj) {
- return newDirToOldDir(getObjNewDir(obj));
-}
-
-int ScummEngine::getObjNewDir(int obj) {
- int dir;
- if (obj < _numActors) {
- dir = derefActor(obj, "getObjNewDir")->getFacing();
- } else {
- int x, y;
- getObjectXYPos(obj, x, y, dir);
- }
- return dir;
-}
-
-int ScummEngine::findInventory(int owner, int idx) {
- int count = 1, i, obj;
- for (i = 0; i < _numInventory; i++) {
- obj = _inventory[i];
- if (obj && getOwner(obj) == owner && count++ == idx)
- return obj;
- }
- return 0;
-}
-
-int ScummEngine::getInventoryCount(int owner) {
- int i, obj;
- int count = 0;
- for (i = 0; i < _numInventory; i++) {
- obj = _inventory[i];
- if (obj && getOwner(obj) == owner)
- count++;
- }
- return count;
-}
-
-void ScummEngine::setObjectState(int obj, int state, int x, int y) {
- int i;
-
- i = getObjectIndex(obj);
- if (i == -1) {
- debug(0, "setObjectState: no such object %d", obj);
- return;
- }
-
- if (x != -1 && x != 0x7FFFFFFF) {
- _objs[i].x_pos = x * 8;
- _objs[i].y_pos = y * 8;
- }
-
- addObjectToDrawQue(i);
- if (_version >= 7) {
- int imagecount;
- if (state == 0xFF) {
- state = getState(obj);
- imagecount = getObjectImageCount(obj);
-
- if (state < imagecount)
- state++;
- else
- state = 1;
- }
-
- if (state == 0xFE)
- state = _rnd.getRandomNumber(getObjectImageCount(obj));
- }
- putState(obj, state);
-}
-
-int ScummEngine::getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f) {
- int i, j;
- int x, y;
- int x2, y2;
-
- j = i = 0xFF;
-
- if (is_obj_1) {
- if (getObjectOrActorXY(b, x, y) == -1)
- return -1;
- if (b < _numActors)
- i = derefActor(b, "getDistanceBetween_is_obj_1")->_scalex;
- } else {
- x = b;
- y = c;
- }
-
- if (is_obj_2) {
- if (getObjectOrActorXY(e, x2, y2) == -1)
- return -1;
- if (e < _numActors)
- j = derefActor(e, "getDistanceBetween_is_obj_2")->_scalex;
- } else {
- x2 = e;
- y2 = f;
- }
-
- return getDist(x, y, x2, y2) * 0xFF / ((i + j) / 2);
-}
-
-void ScummEngine::nukeFlObjects(int min, int max) {
- ObjectData *od;
- int i;
-
- debug(0, "nukeFlObjects(%d,%d)", min, max);
-
- for (i = (_numLocalObjects-1), od = _objs; --i >= 0; od++)
- if (od->fl_object_index && od->obj_nr >= min && od->obj_nr <= max) {
- res.nukeResource(rtFlObject, od->fl_object_index);
- od->obj_nr = 0;
- od->fl_object_index = 0;
- }
-}
-
-void ScummEngine_v6::enqueueObject(int objectNumber, int objectX, int objectY, int objectWidth,
- int objectHeight, int scaleX, int scaleY, int image, int mode) {
- BlastObject *eo;
-
- if (_blastObjectQueuePos >= (int)ARRAYSIZE(_blastObjectQueue)) {
- error("enqueueObject: overflow");
- }
-
- int idx = getObjectIndex(objectNumber);
- assert(idx >= 0);
-
- eo = &_blastObjectQueue[_blastObjectQueuePos++];
- eo->number = objectNumber;
- eo->rect.left = objectX;
- eo->rect.top = objectY + _screenTop;
- if (objectWidth == 0) {
- eo->rect.right = eo->rect.left + _objs[idx].width;
- } else {
- eo->rect.right = eo->rect.left + objectWidth;
- }
- if (objectHeight == 0) {
- eo->rect.bottom = eo->rect.top + _objs[idx].height;
- } else {
- eo->rect.bottom = eo->rect.top + objectHeight;
- }
-
- eo->scaleX = scaleX;
- eo->scaleY = scaleY;
- eo->image = image;
-
- eo->mode = mode;
-}
-
-void ScummEngine_v6::drawBlastObjects() {
- BlastObject *eo;
- int i;
-
- eo = _blastObjectQueue;
- for (i = 0; i < _blastObjectQueuePos; i++, eo++) {
- drawBlastObject(eo);
- }
-}
-
-void ScummEngine_v6::drawBlastObject(BlastObject *eo) {
- VirtScreen *vs;
- const byte *bomp, *ptr;
- int objnum;
- BompDrawData bdd;
-
- vs = &virtscr[0];
-
- checkRange(_numGlobalObjects - 1, 30, eo->number, "Illegal Blast object %d");
-
- objnum = getObjectIndex(eo->number);
- if (objnum == -1)
- error("drawBlastObject: getObjectIndex on BlastObject %d failed", eo->number);
-
- ptr = getOBIMFromObjectData(_objs[objnum]);
- if (!ptr)
- error("BlastObject object %d image not found", eo->number);
-
- const byte *img = getObjectImage(ptr, eo->image);
- if (_version == 8) {
- assert(img);
- bomp = img + 8;
- } else {
- if (!img)
- img = getObjectImage(ptr, 1); // Backward compatibility with samnmax blast objects
- assert(img);
- bomp = findResourceData(MKID('BOMP'), img);
- }
-
- if (!bomp)
- error("object %d is not a blast object", eo->number);
-
- if (_version == 8) {
- bdd.srcwidth = READ_LE_UINT32(&((const BompHeader *)bomp)->v8.width);
- bdd.srcheight = READ_LE_UINT32(&((const BompHeader *)bomp)->v8.height);
- } else {
- bdd.srcwidth = READ_LE_UINT16(&((const BompHeader *)bomp)->old.width);
- bdd.srcheight = READ_LE_UINT16(&((const BompHeader *)bomp)->old.height);
- }
-
- bdd.dst = *vs;
- bdd.dst.pixels = vs->getPixels(0, 0);
- // Skip the bomp header
- if (_version == 8) {
- bdd.dataptr = bomp + 8;
- } else {
- bdd.dataptr = bomp + 10;
- }
- bdd.x = eo->rect.left;
- bdd.y = eo->rect.top;
- bdd.scale_x = (byte)eo->scaleX;
- bdd.scale_y = (byte)eo->scaleY;
- bdd.maskPtr = NULL;
-
- if ((bdd.scale_x != 255) || (bdd.scale_y != 255)) {
- bdd.shadowMode = 0;
- } else {
- bdd.shadowMode = eo->mode;
- }
- drawBomp(bdd, false);
-
- markRectAsDirty(vs->number, bdd.x, bdd.x + bdd.srcwidth, bdd.y, bdd.y + bdd.srcheight);
-}
-
-void ScummEngine_v6::removeBlastObjects() {
- BlastObject *eo;
- int i;
-
- eo = _blastObjectQueue;
- for (i = 0; i < _blastObjectQueuePos; i++, eo++) {
- removeBlastObject(eo);
- }
- _blastObjectQueuePos = 0;
-}
-
-void ScummEngine_v6::removeBlastObject(BlastObject *eo) {
- VirtScreen *vs = &virtscr[0];
-
- Common::Rect r;
- int left_strip, right_strip;
- int i;
-
- r = eo->rect;
-
- r.clip(Common::Rect(vs->w, vs->h));
-
- if (r.width() <= 0 || r.height() <= 0)
- return;
-
- left_strip = r.left / 8;
- right_strip = (r.right + (vs->xstart % 8)) / 8;
-
- if (left_strip < 0)
- left_strip = 0;
- if (right_strip > gdi._numStrips - 1)
- right_strip = gdi._numStrips - 1;
- for (i = left_strip; i <= right_strip; i++)
- gdi.resetBackground(r.top, r.bottom, i);
-
- markRectAsDirty(kMainVirtScreen, r, USAGE_BIT_RESTORED);
-}
-
-int ScummEngine::findLocalObjectSlot() {
- int i;
-
- for (i = 1; i < _numLocalObjects; i++) {
- if (!_objs[i].obj_nr) {
- memset(&_objs[i], 0, sizeof(_objs[i]));
- return i;
- }
- }
-
- return -1;
-}
-
-int ScummEngine::findFlObjectSlot() {
- int i;
- for (i = 1; i < _numFlObject; i++) {
- if (res.address[rtFlObject][i] == NULL)
- return i;
- }
- error("findFlObjectSlot: Out of FLObject slots");
- return -1;
-}
-
-void ScummEngine::loadFlObject(uint object, uint room) {
- FindObjectInRoom foir;
- int i, slot, objslot;
- ObjectData *od;
- byte *flob;
- uint32 obcd_size, obim_size, flob_size;
- bool isRoomLocked, isRoomScriptsLocked;
-
- // Don't load an already loaded object
- if (getObjectIndex(object) != -1)
- return;
-
- // Don't load an already stored object
- for (i = 0; i < _numStoredFlObjects; i++) {
- if (_storedFlObjects[i].obj_nr == object)
- return;
- }
-
- // Locate the object in the room resource
- findObjectInRoom(&foir, foImageHeader | foCodeHeader, object, room);
-
- // Add an entry for the new floating object in the local object table
- objslot = findLocalObjectSlot();
- if (objslot == -1)
- error("loadFlObject: Local Object Table overflow");
-
- od = &_objs[objslot];
-
- // Dump object script
- if (_dumpScripts) {
- char buf[32];
- const byte *ptr = foir.obcd;
- sprintf(buf, "roomobj-%d-", room);
- ptr = findResource(MKID('VERB'), ptr);
- dumpResource(buf, object, ptr);
- }
-
- // Setup sizes
- obcd_size = READ_BE_UINT32(foir.obcd + 4);
- od->OBCDoffset = 8;
- od->OBIMoffset = obcd_size + 8;
- obim_size = READ_BE_UINT32(foir.obim + 4);
- flob_size = obcd_size + obim_size + 8;
-
- // Lock room/roomScripts for the given room. They contains the OBCD/OBIM
- // data, and a call to createResource might expire them, hence we lock them.
- isRoomLocked = res.isLocked(rtRoom, room);
- isRoomScriptsLocked = res.isLocked(rtRoomScripts, room);
- if (!isRoomLocked)
- res.lock(rtRoom, room);
- if (_version == 8 && !isRoomScriptsLocked)
- res.lock(rtRoomScripts, room);
-
- // Allocate slot & memory for floating object
- slot = findFlObjectSlot();
- flob = res.createResource(rtFlObject, slot, flob_size);
- assert(flob);
-
- // Copy object code + object image to floating object
- ((uint32 *)flob)[0] = MKID('FLOB');
- ((uint32 *)flob)[1] = TO_BE_32(flob_size);
-
- memcpy(flob + 8, foir.obcd, obcd_size);
- memcpy(flob + 8 + obcd_size, foir.obim, obim_size);
-
- // Unlock room/roomScripts
- if (!isRoomLocked)
- res.unlock(rtRoom, room);
- if (_version == 8 && !isRoomScriptsLocked)
- res.unlock(rtRoomScripts, room);
-
- // Setup local object flags
- setupRoomObject(od, flob, flob);
-
- od->fl_object_index = slot;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/object.h b/scumm/object.h
deleted file mode 100644
index edb779b5eb..0000000000
--- a/scumm/object.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef OBJECT_H
-#define OBJECT_H
-
-namespace Scumm {
-
-enum ObjectClass {
- kObjectClassNeverClip = 20,
- kObjectClassAlwaysClip = 21,
- kObjectClassIgnoreBoxes = 22,
- kObjectClassYFlip = 29,
- kObjectClassXFlip = 30,
- kObjectClassPlayer = 31, // Actor is controlled by the player
- kObjectClassUntouchable = 32
-};
-
-struct ObjectData {
- uint32 OBIMoffset;
- uint32 OBCDoffset;
- int16 walk_x, walk_y;
- uint16 obj_nr;
- int16 x_pos;
- int16 y_pos;
- uint16 width;
- uint16 height;
- byte actordir;
- byte parent;
- byte parentstate;
- byte state;
- byte fl_object_index;
- byte flags;
-};
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
-struct RoomHeader {
- union {
- struct {
- uint16 width, height;
- uint16 numObjects;
- } GCC_PACK old;
-
- struct {
- uint32 version;
- uint16 width, height;
- uint16 numObjects;
- } GCC_PACK v7;
-
- struct {
- uint32 version;
- uint32 width, height;
- uint32 numObjects;
- uint32 numZBuffer;
- uint32 transparency;
- } GCC_PACK v8;
- } GCC_PACK;
-} GCC_PACK;
-
-struct CodeHeader {
- union {
- struct {
- uint16 obj_id;
- byte x, y, w, h;
- byte flags;
- byte parent;
- int16 walk_x;
- int16 walk_y;
- byte actordir;
- } GCC_PACK v5;
-
- struct {
- uint16 obj_id;
- int16 x, y;
- uint16 w, h;
- byte flags, parent;
- uint16 unk1;
- uint16 unk2;
- byte actordir;
- } GCC_PACK v6;
-
- struct {
- uint32 version;
- uint16 obj_id;
- byte parent;
- byte parentstate;
- } GCC_PACK v7;
-
- } GCC_PACK;
-} GCC_PACK;
-
-struct ImageHeader { /* file format */
- union {
- struct {
- uint16 obj_id;
- uint16 image_count;
- uint16 unk[1];
- byte flags;
- byte unk1;
- uint16 unk2[2];
- uint16 width;
- uint16 height;
- uint16 hotspot_num;
- struct {
- int16 x, y;
- } GCC_PACK hotspot[15];
- } GCC_PACK old;
-
- struct {
- uint32 version;
- uint16 obj_id;
- uint16 image_count;
- int16 x_pos, y_pos;
- uint16 width, height;
- byte unk2[3];
- byte actordir;
- uint16 hotspot_num;
- struct {
- int16 x, y;
- } GCC_PACK hotspot[15];
- } GCC_PACK v7;
-
- struct {
- char name[32];
- uint32 unk_1[2];
- uint32 version; // 801 in COMI, 800 in the COMI demo
- uint32 image_count;
- uint32 x_pos;
- uint32 y_pos;
- uint32 width;
- uint32 height;
- uint32 actordir;
- uint32 flags; // This field is missing in the COMI demo (version == 800) !
- struct {
- int32 x, y;
- } GCC_PACK hotspot[15];
- } GCC_PACK v8;
- } GCC_PACK;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-struct FindObjectInRoom {
- const CodeHeader *cdhd;
- const byte *obcd;
- const byte *obim;
- const byte *roomptr;
-};
-
-enum FindObjectWhat {
- foCodeHeader = 1,
- foImageHeader = 2,
- foCheckAlreadyLoaded = 4
-};
-
-} // End of namespace Scumm
-
-
-#endif
diff --git a/scumm/palette.cpp b/scumm/palette.cpp
deleted file mode 100644
index d8b8f643f1..0000000000
--- a/scumm/palette.cpp
+++ /dev/null
@@ -1,969 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "common/util.h"
-
-#include "scumm/scumm.h"
-#include "scumm/intern.h"
-#include "scumm/resource.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-void ScummEngine::setupC64Palette() {
- setPalColor( 0, 0x00, 0x00, 0x00);
- setPalColor( 1, 0xFD, 0xFE, 0xFC);
- setPalColor( 2, 0xBE, 0x1A, 0x24);
- setPalColor( 3, 0x30, 0xE6, 0xC6);
- setPalColor( 4, 0xB4, 0x1A, 0xE2);
- setPalColor( 5, 0x1F, 0xD2, 0x1E);
- setPalColor( 6, 0x21, 0x1B, 0xAE);
- setPalColor( 7, 0xDF, 0xF6, 0x0A);
- setPalColor( 8, 0xB8, 0x41, 0x04);
- setPalColor( 9, 0x6A, 0x33, 0x04);
- setPalColor(10, 0xFE, 0x4A, 0x57);
- setPalColor(11, 0x42, 0x45, 0x40);
- setPalColor(12, 0x70, 0x74, 0x6F);
- setPalColor(13, 0x59, 0xFE, 0x59);
- setPalColor(14, 0x5F, 0x53, 0xFE);
- setPalColor(15, 0xA4, 0xA7, 0xA2);
-
- setPalColor(16, 255, 85, 255);
-}
-
-void ScummEngine::setupNESPalette() {
- setPalColor(0x00,0x24,0x24,0x24); // 0x1D
- setPalColor(0x01,0x00,0x24,0x92);
- setPalColor(0x02,0x00,0x00,0xDB);
- setPalColor(0x03,0x6D,0x49,0xDB);
- setPalColor(0x04,0x92,0x00,0x6D);
- setPalColor(0x05,0xB6,0x00,0x6D);
- setPalColor(0x06,0xB6,0x24,0x00);
- setPalColor(0x07,0x92,0x49,0x00);
- setPalColor(0x08,0x6D,0x49,0x00);
- setPalColor(0x09,0x24,0x49,0x00);
- setPalColor(0x0A,0x00,0x6D,0x24);
- setPalColor(0x0B,0x00,0x92,0x00);
- setPalColor(0x0C,0x00,0x49,0x49);
- setPalColor(0x0D,0x00,0x00,0x00);
- setPalColor(0x0E,0x00,0x00,0x00);
- setPalColor(0x0F,0x00,0x00,0x00);
-
- setPalColor(0x10,0xB6,0xB6,0xB6);
- setPalColor(0x11,0x00,0x6D,0xDB);
- setPalColor(0x12,0x00,0x49,0xFF);
- setPalColor(0x13,0x92,0x00,0xFF);
- setPalColor(0x14,0xB6,0x00,0xFF);
- setPalColor(0x15,0xFF,0x00,0x92);
- setPalColor(0x16,0xFF,0x00,0x00);
- setPalColor(0x17,0xDB,0x6D,0x00);
- setPalColor(0x18,0x92,0x6D,0x00);
- setPalColor(0x19,0x24,0x92,0x00);
- setPalColor(0x1A,0x00,0x92,0x00);
- setPalColor(0x1B,0x00,0xB6,0x6D);
- setPalColor(0x1C,0x00,0x92,0x92);
- setPalColor(0x1D,0x6D,0x6D,0x6D); // 0x00
- setPalColor(0x1E,0x00,0x00,0x00);
- setPalColor(0x1F,0x00,0x00,0x00);
-
- setPalColor(0x20,0xFF,0xFF,0xFF);
- setPalColor(0x21,0x6D,0xB6,0xFF);
- setPalColor(0x22,0x92,0x92,0xFF);
- setPalColor(0x23,0xDB,0x6D,0xFF);
- setPalColor(0x24,0xFF,0x00,0xFF);
- setPalColor(0x25,0xFF,0x6D,0xFF);
- setPalColor(0x26,0xFF,0x92,0x00);
- setPalColor(0x27,0xFF,0xB6,0x00);
- setPalColor(0x28,0xDB,0xDB,0x00);
- setPalColor(0x29,0x6D,0xDB,0x00);
- setPalColor(0x2A,0x00,0xFF,0x00);
- setPalColor(0x2B,0x49,0xFF,0xDB);
- setPalColor(0x2C,0x00,0xFF,0xFF);
- setPalColor(0x2D,0x49,0x49,0x49);
- setPalColor(0x2E,0x00,0x00,0x00);
- setPalColor(0x2F,0x00,0x00,0x00);
-
- setPalColor(0x30,0xFF,0xFF,0xFF);
- setPalColor(0x31,0xB6,0xDB,0xFF);
- setPalColor(0x32,0xDB,0xB6,0xFF);
- setPalColor(0x33,0xFF,0xB6,0xFF);
- setPalColor(0x34,0xFF,0x92,0xFF);
- setPalColor(0x35,0xFF,0xB6,0xB6);
- setPalColor(0x36,0xFF,0xDB,0x92);
- setPalColor(0x37,0xFF,0xFF,0x49);
- setPalColor(0x38,0xFF,0xFF,0x6D);
- setPalColor(0x39,0xB6,0xFF,0x49);
- setPalColor(0x3A,0x92,0xFF,0x6D);
- setPalColor(0x3B,0x49,0xFF,0xDB);
- setPalColor(0x3C,0x92,0xDB,0xFF);
- setPalColor(0x3D,0x92,0x92,0x92);
- setPalColor(0x3E,0x00,0x00,0x00);
- setPalColor(0x3F,0x00,0x00,0x00);
-}
-
-void ScummEngine::setupAmigaPalette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 0, 0, 187);
- setPalColor( 2, 0, 187, 0);
- setPalColor( 3, 0, 187, 187);
- setPalColor( 4, 187, 0, 0);
- setPalColor( 5, 187, 0, 187);
- setPalColor( 6, 187, 119, 0);
- setPalColor( 7, 187, 187, 187);
- setPalColor( 8, 119, 119, 119);
- setPalColor( 9, 119, 119, 255);
- setPalColor(10, 0, 255, 0);
- setPalColor(11, 0, 255, 255);
- setPalColor(12, 255, 136, 136);
- setPalColor(13, 255, 0, 255);
- setPalColor(14, 255, 255, 0);
- setPalColor(15, 255, 255, 255);
-}
-
-void ScummEngine::setupHercPalette() {
- setPalColor( 0, 0, 0, 0);
-
- if (_renderMode == Common::kRenderHercA)
- setPalColor( 1, 0xAE, 0x69, 0x38);
- else
- setPalColor( 1, 0x00, 0xFF, 0x00);
-
- // Setup cursor palette
- setPalColor( 7, 170, 170, 170);
- setPalColor( 8, 85, 85, 85);
- setPalColor(15, 255, 255, 255);
-}
-
-void ScummEngine::setupCGAPalette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 0, 168, 168);
- setPalColor( 2, 168, 0, 168);
- setPalColor( 3, 168, 168, 168);
-
- // Setup cursor palette
- setPalColor( 7, 170, 170, 170);
- setPalColor( 8, 85, 85, 85);
- setPalColor(15, 255, 255, 255);
-}
-
-void ScummEngine::setupEGAPalette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 0, 0, 170);
- setPalColor( 2, 0, 170, 0);
- setPalColor( 3, 0, 170, 170);
- setPalColor( 4, 170, 0, 0);
- setPalColor( 5, 170, 0, 170);
- setPalColor( 6, 170, 85, 0);
- setPalColor( 7, 170, 170, 170);
- setPalColor( 8, 85, 85, 85);
- setPalColor( 9, 85, 85, 255);
- setPalColor(10, 85, 255, 85);
- setPalColor(11, 85, 255, 255);
- setPalColor(12, 255, 85, 85);
- setPalColor(13, 255, 85, 255);
- setPalColor(14, 255, 255, 85);
- setPalColor(15, 255, 255, 255);
-}
-
-void ScummEngine::setupV1Palette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 255, 255, 255);
- setPalColor( 2, 170, 0, 0);
- setPalColor( 3, 0, 170, 170);
- setPalColor( 4, 170, 0, 170);
- setPalColor( 5, 0, 170, 0);
- setPalColor( 6, 0, 0, 170);
- setPalColor( 7, 255, 255, 85);
- setPalColor( 8, 255, 85, 85);
- setPalColor( 9, 170, 85, 0);
- setPalColor(10, 255, 85, 85);
- setPalColor(11, 85, 85, 85);
- setPalColor(12, 170, 170, 170);
- setPalColor(13, 85, 255, 85);
- setPalColor(14, 85, 85, 255);
-
- if (_gameId == GID_ZAK)
- setPalColor(15, 170, 170, 170);
- else
- setPalColor(15, 85, 85, 85);
-
- setPalColor(16, 255, 85, 255);
-}
-
-void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) {
- int i;
- byte *dest, r, g, b;
-
- if (numcolor < 0) {
- if (_features & GF_SMALL_HEADER) {
- if (_features & GF_OLD256)
- numcolor = READ_LE_UINT16(ptr);
- else
- numcolor = READ_LE_UINT16(ptr) / 3;
- ptr += 2;
- } else {
- numcolor = getResourceDataSize(ptr) / 3;
- }
- }
-
- checkRange(256, 0, numcolor, "Too many colors (%d) in Palette");
-
- dest = _currentPalette;
-
- for (i = 0; i < numcolor; i++) {
- r = *ptr++;
- g = *ptr++;
- b = *ptr++;
-
- // Only SCUMM 5/6 games use 6/6/6 style palettes
- if (_version >= 5 && _version <= 6) {
- if ((_heversion <= 73 && i < 15) || i == 15 || r < 252 || g < 252 || b < 252) {
- *dest++ = r;
- *dest++ = g;
- *dest++ = b;
- } else {
- dest += 3;
- }
- } else {
- *dest++ = r;
- *dest++ = g;
- *dest++ = b;
- }
- }
-
- if (_heversion >= 90 || _version == 8) {
- memcpy(_darkenPalette, _currentPalette, 768);
- }
-
- setDirtyColors(0, numcolor - 1);
-}
-
-void ScummEngine::setDirtyColors(int min, int max) {
- if (_palDirtyMin > min)
- _palDirtyMin = min;
- if (_palDirtyMax < max)
- _palDirtyMax = max;
-}
-
-void ScummEngine::initCycl(const byte *ptr) {
- int j;
- ColorCycle *cycl;
-
- memset(_colorCycle, 0, sizeof(_colorCycle));
-
- if (_features & GF_SMALL_HEADER) {
- cycl = _colorCycle;
- for (j = 0; j < 16; ++j, ++cycl) {
- uint16 delay = READ_BE_UINT16(ptr);
- ptr += 2;
- byte start = *ptr++;
- byte end = *ptr++;
-
- if (!delay || delay == 0x0aaa || start >= end)
- continue;
-
- cycl->counter = 0;
- cycl->delay = 16384 / delay;
- cycl->flags = 2;
- cycl->start = start;
- cycl->end = end;
- }
- } else {
- memset(_colorUsedByCycle, 0, sizeof(_colorUsedByCycle));
- while ((j = *ptr++) != 0) {
- if (j < 1 || j > 16) {
- error("Invalid color cycle index %d", j);
- }
- cycl = &_colorCycle[j - 1];
-
- ptr += 2;
- cycl->counter = 0;
- cycl->delay = 16384 / READ_BE_UINT16(ptr);
- ptr += 2;
- cycl->flags = READ_BE_UINT16(ptr);
- ptr += 2;
- cycl->start = *ptr++;
- cycl->end = *ptr++;
-
- for (int i = cycl->start; i <= cycl->end; ++i) {
- _colorUsedByCycle[i] = 1;
- }
- }
- }
-}
-
-void ScummEngine::stopCycle(int i) {
- ColorCycle *cycl;
-
- checkRange(16, 0, i, "Stop Cycle %d Out Of Range");
- if (i != 0) {
- _colorCycle[i - 1].delay = 0;
- return;
- }
-
- for (i = 0, cycl = _colorCycle; i < 16; i++, cycl++)
- cycl->delay = 0;
-}
-
-/**
- * Cycle the colors in the given palette in the intervael [cycleStart, cycleEnd]
- * either one step forward or backward.
- */
-static void doCyclePalette(byte *palette, int cycleStart, int cycleEnd, int size, bool forward) {
- byte *start = palette + cycleStart * size;
- byte *end = palette + cycleEnd * size;
- int num = cycleEnd - cycleStart;
- byte tmp[6];
-
- assert(size <= 6);
-
- if (forward) {
- memmove(tmp, end, size);
- memmove(start + size, start, num * size);
- memmove(start, tmp, size);
- } else {
- memmove(tmp, start, size);
- memmove(start, start + size, num * size);
- memmove(end, tmp, size);
- }
-}
-
-/**
- * Adjust an 'indirect' color palette for the color cycling performed on its
- * master palette. An indirect palette is a palette which contains indices
- * pointing into another palette - it provides a level of indirection to map
- * palette colors to other colors. Now when the target palette is cycled, the
- * indirect palette suddenly point at the wrong color(s). This function takes
- * care of adjusting an indirect palette by searching through it and replacing
- * all indices that are in the cycle range by the new (cycled) index.
- *
- * Finally, the palette entries still have to be cycled normally.
- */
-static void doCycleIndirectPalette(byte *palette, int cycleStart, int cycleEnd, bool forward) {
- int num = cycleEnd - cycleStart + 1;
- int i;
- int offset = forward ? 1 : num - 1;
-
- for (i = 0; i < 256; i++) {
- if (cycleStart <= palette[i] && palette[i] <= cycleEnd) {
- palette[i] = (palette[i] - cycleStart + offset) % num + cycleStart;
- }
- }
-
- doCyclePalette(palette, cycleStart, cycleEnd, 1, forward);
-}
-
-
-void ScummEngine::cyclePalette() {
- ColorCycle *cycl;
- int valueToAdd;
- int i, j;
-
- valueToAdd = VAR(VAR_TIMER);
- if (valueToAdd < VAR(VAR_TIMER_NEXT))
- valueToAdd = VAR(VAR_TIMER_NEXT);
-
- for (i = 0, cycl = _colorCycle; i < 16; i++, cycl++) {
- if (!cycl->delay || cycl->start > cycl->end)
- continue;
- cycl->counter += valueToAdd;
- if (cycl->counter >= cycl->delay) {
- cycl->counter %= cycl->delay;
-
- setDirtyColors(cycl->start, cycl->end);
- moveMemInPalRes(cycl->start, cycl->end, cycl->flags & 2);
-
- doCyclePalette(_currentPalette, cycl->start, cycl->end, 3, !(cycl->flags & 2));
-
- if (_shadowPalette) {
- if (_version >= 7) {
- for (j = 0; j < NUM_SHADOW_PALETTE; j++)
- doCycleIndirectPalette(_shadowPalette + j * 256, cycl->start, cycl->end, !(cycl->flags & 2));
- } else {
- doCycleIndirectPalette(_shadowPalette, cycl->start, cycl->end, !(cycl->flags & 2));
- }
- }
- }
- }
-}
-
-/**
- * Perform color cycling on the palManipulate data, too, otherwise
- * color cycling will be disturbed by the palette fade.
- */
-void ScummEngine::moveMemInPalRes(int start, int end, byte direction) {
- if (!_palManipCounter)
- return;
-
- doCyclePalette(_palManipPalette, start, end, 3, !direction);
- doCyclePalette(_palManipIntermediatePal, start, end, 6, !direction);
-}
-
-void ScummEngine::palManipulateInit(int resID, int start, int end, int time) {
- byte *pal, *target, *between;
- byte *string1, *string2, *string3;
- int i;
-
- string1 = getStringAddress(resID);
- string2 = getStringAddress(resID + 1);
- string3 = getStringAddress(resID + 2);
- if (!string1 || !string2 || !string3) {
- error("palManipulateInit(%d,%d,%d,%d): Cannot obtain string resources %d, %d and %d",
- resID, start, end, time, resID, resID + 1, resID + 2);
- return;
- }
-
- string1 += start;
- string2 += start;
- string3 += start;
-
- _palManipStart = start;
- _palManipEnd = end;
- _palManipCounter = 0;
-
- if (!_palManipPalette)
- _palManipPalette = (byte *)calloc(0x300, 1);
- if (!_palManipIntermediatePal)
- _palManipIntermediatePal = (byte *)calloc(0x600, 1);
-
- pal = _currentPalette + start * 3;
- target = _palManipPalette + start * 3;
- between = _palManipIntermediatePal + start * 6;
-
- for (i = start; i < end; ++i) {
- *target++ = *string1++;
- *target++ = *string2++;
- *target++ = *string3++;
- *(uint16 *)between = ((uint16) *pal++) << 8;
- between += 2;
- *(uint16 *)between = ((uint16) *pal++) << 8;
- between += 2;
- *(uint16 *)between = ((uint16) *pal++) << 8;
- between += 2;
- }
-
- _palManipCounter = time;
-}
-
-void ScummEngine_v6::palManipulateInit(int resID, int start, int end, int time) {
- byte *pal, *target, *between;
- const byte *new_pal;
- int i;
-
- new_pal = getPalettePtr(resID, _roomResource);
-
- new_pal += start*3;
-
- _palManipStart = start;
- _palManipEnd = end;
- _palManipCounter = 0;
-
- if (!_palManipPalette)
- _palManipPalette = (byte *)calloc(0x300, 1);
- if (!_palManipIntermediatePal)
- _palManipIntermediatePal = (byte *)calloc(0x600, 1);
-
- pal = _currentPalette + start * 3;
- target = _palManipPalette + start * 3;
- between = _palManipIntermediatePal + start * 6;
-
- for (i = start; i < end; ++i) {
- *target++ = *new_pal++;
- *target++ = *new_pal++;
- *target++ = *new_pal++;
- *(uint16 *)between = ((uint16) *pal++) << 8;
- between += 2;
- *(uint16 *)between = ((uint16) *pal++) << 8;
- between += 2;
- *(uint16 *)between = ((uint16) *pal++) << 8;
- between += 2;
- }
-
- _palManipCounter = time;
-}
-
-
-void ScummEngine::palManipulate() {
- byte *target, *pal, *between;
- int i, j;
-
- if (!_palManipCounter || !_palManipPalette || !_palManipIntermediatePal)
- return;
-
- target = _palManipPalette + _palManipStart * 3;
- pal = _currentPalette + _palManipStart * 3;
- between = _palManipIntermediatePal + _palManipStart * 6;
-
- for (i = _palManipStart; i < _palManipEnd; ++i) {
- j = (*((uint16 *)between) += ((*target++ << 8) - *((uint16 *)between)) / _palManipCounter);
- *pal++ = j >> 8;
- between += 2;
- j = (*((uint16 *)between) += ((*target++ << 8) - *((uint16 *)between)) / _palManipCounter);
- *pal++ = j >> 8;
- between += 2;
- j = (*((uint16 *)between) += ((*target++ << 8) - *((uint16 *)between)) / _palManipCounter);
- *pal++ = j >> 8;
- between += 2;
- }
- setDirtyColors(_palManipStart, _palManipEnd);
- _palManipCounter--;
-}
-
-void ScummEngine::setupShadowPalette(int slot, int redScale, int greenScale, int blueScale, int startColor, int endColor) {
- byte *table;
- int i;
- byte *curpal;
-
- if (slot < 0 || slot >= NUM_SHADOW_PALETTE)
- error("setupShadowPalette: invalid slot %d", slot);
-
- if (startColor < 0 || startColor > 255 || endColor < 0 || startColor > 255 || endColor < startColor)
- error("setupShadowPalette: invalid range from %d to %d", startColor, endColor);
-
- table = _shadowPalette + slot * 256;
- for (i = 0; i < 256; i++)
- table[i] = i;
-
- table += startColor;
- curpal = _currentPalette + startColor * 3;
- for (i = startColor; i <= endColor; i++) {
- *table++ = remapPaletteColor((curpal[0] * redScale) >> 8,
- (curpal[1] * greenScale) >> 8,
- (curpal[2] * blueScale) >> 8,
- -1);
- curpal += 3;
- }
-}
-
-static inline uint colorWeight(int red, int green, int blue) {
- return 3 * red * red + 6 * green * green + 2 * blue * blue;
-}
-
-void ScummEngine::setupShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor, int start, int end) {
- const byte *basepal = getPalettePtr(_curPalIndex, _roomResource);
- const byte *compareptr;
- const byte *pal = basepal + start * 3;
- byte *table = _shadowPalette + start;
- int i;
-
- // This is an implementation based on the original games code.
- //
- // The four known rooms where setupShadowPalette is used in atlantis are:
- //
- // 1) FOA Room 53: subway departing Knossos for Atlantis.
- // 2) FOA Room 48: subway crashing into the Atlantis entrance area
- // 3) FOA Room 82: boat/sub shadows while diving near Thera
- // 4) FOA Room 23: the big machine room inside Atlantis
- //
- // There seems to be no explanation for why this function is called
- // from within Room 23 (the big machine), as it has no shadow effects
- // and thus doesn't result in any visual differences.
-
- if (_gameId == GID_SAMNMAX) {
- for (i = 0; i < 256; i++)
- _shadowPalette[i] = i;
- }
-
- for (i = start; i < end; i++) {
- int r = (int) ((pal[0] >> 2) * redScale) >> 8;
- int g = (int) ((pal[1] >> 2) * greenScale) >> 8;
- int b = (int) ((pal[2] >> 2) * blueScale) >> 8;
- pal += 3;
-
- uint8 bestitem = 0;
- uint bestsum = 32000;
-
- compareptr = basepal + startColor * 3;
- for (int j = startColor; j <= endColor; j++, compareptr += 3) {
- int ar = compareptr[0] >> 2;
- int ag = compareptr[1] >> 2;
- int ab = compareptr[2] >> 2;
-
- uint sum = ABS(ar - r) + ABS(ag - g) + ABS(ab - b);
-
- if (sum < bestsum) {
- bestsum = sum;
- bestitem = j;
- }
- }
- *table++ = bestitem;
- }
-}
-
-void ScummEngine::darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor) {
- int max;
- if (_version >= 5 && _version <= 6 && _heversion <= 60) {
- max = 252;
- } else {
- max = 255;
- }
-
- if (startColor <= endColor) {
- const byte *cptr;
- const byte *palptr;
- int color, idx, j;
-
- if (_heversion >= 90 || _version == 8) {
- palptr = _darkenPalette;
- } else {
- palptr = getPalettePtr(_curPalIndex, _roomResource);
- }
- for (j = startColor; j <= endColor; j++) {
- idx = (_heversion == 70) ? _HEV7ActorPalette[j] : j;
- cptr = palptr + idx * 3;
-
- if (_heversion == 70)
- setDirtyColors(idx, idx);
-
- color = *cptr++;
- color = color * redScale / 0xFF;
- if (color > max)
- color = max;
- _currentPalette[idx * 3 + 0] = color;
-
- color = *cptr++;
- color = color * greenScale / 0xFF;
- if (color > max)
- color = max;
- _currentPalette[idx * 3 + 1] = color;
-
- color = *cptr++;
- color = color * blueScale / 0xFF;
- if (color > max)
- color = max;
- _currentPalette[idx * 3 + 2] = color;
- }
- if (_heversion != 70)
- setDirtyColors(startColor, endColor);
- }
-}
-
-#ifndef DISABLE_SCUMM_7_8
-static int HSL2RGBHelper(int n1, int n2, int hue) {
- if (hue > 360)
- hue = hue - 360;
- else if (hue < 0)
- hue = hue + 360;
-
- if (hue < 60)
- return n1 + (n2 - n1) * hue / 60;
- if (hue < 180)
- return n2;
- if (hue < 240)
- return n1 + (n2 - n1) * (240 - hue) / 60;
- return n1;
-}
-
-/**
- * This function scales the HSL (Hue, Saturation and Lightness)
- * components of the palette colors. It's used in CMI when Guybrush
- * walks from the beach towards the swamp.
- */
-void ScummEngine_v8::desaturatePalette(int hueScale, int satScale, int lightScale, int startColor, int endColor) {
-
- if (startColor <= endColor) {
- const byte *cptr;
- byte *cur;
- int j;
-
- cptr = _darkenPalette + startColor * 3;
- cur = _currentPalette + startColor * 3;
-
- for (j = startColor; j <= endColor; j++) {
- int R = *cptr++;
- int G = *cptr++;
- int B = *cptr++;
-
- // RGB to HLS (Foley and VanDam)
-
- const int min = MIN(R, MIN(G, B));
- const int max = MAX(R, MAX(G, B));
- const int diff = (max - min);
- const int sum = (max + min);
-
- if (diff != 0) {
- int H, S, L;
-
- if (sum <= 255)
- S = 255 * diff / sum;
- else
- S = 255 * diff / (255 * 2 - sum);
-
- if (R == max)
- H = 60 * (G - B) / diff;
- else if (G == max)
- H = 120 + 60 * (B - R) / diff;
- else
- H = 240 + 60 * (R - G) / diff;
-
- if (H < 0)
- H = H + 360;
-
- // Scale the result
-
- H = (H * hueScale) / 255;
- S = (S * satScale) / 255;
- L = (sum * lightScale) / 255;
-
- // HLS to RGB (Foley and VanDam)
-
- int m1, m2;
- if (L <= 255)
- m2 = L * (255 + S) / (255 * 2);
- else
- m2 = L * (255 - S) / (255 * 2) + S;
-
- m1 = L - m2;
-
- R = HSL2RGBHelper(m1, m2, H + 120);
- G = HSL2RGBHelper(m1, m2, H);
- B = HSL2RGBHelper(m1, m2, H - 120);
- } else {
- // Maximal color = minimal color -> R=G=B -> it's a grayscale.
- R = G = B = (R * lightScale) / 255;
- }
-
- *cur++ = R;
- *cur++ = G;
- *cur++ = B;
- }
-
- setDirtyColors(startColor, endColor);
- }
-}
-#endif
-
-
-int ScummEngine::remapPaletteColor(int r, int g, int b, int threshold) {
- int i;
- int ar, ag, ab;
- uint sum, bestsum, bestitem = 0;
-
- int startColor = (_version == 8) ? 24 : 1;
- byte *pal = _currentPalette + startColor * 3;
-
- if (r > 255)
- r = 255;
- if (g > 255)
- g = 255;
- if (b > 255)
- b = 255;
-
- bestsum = 0x7FFFFFFF;
-
- r &= ~3;
- g &= ~3;
- b &= ~3;
-
- for (i = startColor; i < 255; i++, pal += 3) {
- if (_version == 7 && _colorUsedByCycle[i])
- continue;
-
- ar = pal[0] & ~3;
- ag = pal[1] & ~3;
- ab = pal[2] & ~3;
- if (ar == r && ag == g && ab == b)
- return i;
-
- sum = colorWeight(ar - r, ag - g, ab - b);
-
- if (sum < bestsum) {
- bestsum = sum;
- bestitem = i;
- }
- }
-
- if (threshold != -1 && bestsum > colorWeight(threshold, threshold, threshold)) {
- // Best match exceeded threshold. Try to find an unused palette entry and
- // use it for our purpose.
- pal = _currentPalette + (256 - 2) * 3;
- for (i = 254; i > 48; i--, pal -= 3) {
- if (pal[0] >= 252 && pal[1] >= 252 && pal[2] >= 252) {
- setPalColor(i, r, g, b);
- return i;
- }
- }
- }
-
- return bestitem;
-}
-
-void ScummEngine::swapPalColors(int a, int b) {
- byte *ap, *bp;
- byte t;
-
- if ((uint) a >= 256 || (uint) b >= 256)
- error("swapPalColors: invalid values, %d, %d", a, b);
-
- ap = &_currentPalette[a * 3];
- bp = &_currentPalette[b * 3];
-
- t = ap[0];
- ap[0] = bp[0];
- bp[0] = t;
- t = ap[1];
- ap[1] = bp[1];
- bp[1] = t;
- t = ap[2];
- ap[2] = bp[2];
- bp[2] = t;
-
- setDirtyColors(a, a);
- setDirtyColors(b, b);
-}
-
-void ScummEngine::copyPalColor(int dst, int src) {
- byte *dp, *sp;
-
- if ((uint) dst >= 256 || (uint) src >= 256)
- error("copyPalColor: invalid values, %d, %d", dst, src);
-
- dp = &_currentPalette[dst * 3];
- sp = &_currentPalette[src * 3];
-
- dp[0] = sp[0];
- dp[1] = sp[1];
- dp[2] = sp[2];
-
- setDirtyColors(dst, dst);
-}
-
-void ScummEngine::setPalColor(int idx, int r, int g, int b) {
- if (_heversion == 70)
- idx = _HEV7ActorPalette[idx];
-
- _currentPalette[idx * 3 + 0] = r;
- _currentPalette[idx * 3 + 1] = g;
- _currentPalette[idx * 3 + 2] = b;
- if (_version == 8) {
- _darkenPalette[idx * 3 + 0] = r;
- _darkenPalette[idx * 3 + 1] = g;
- _darkenPalette[idx * 3 + 2] = b;
- }
- setDirtyColors(idx, idx);
-}
-
-void ScummEngine::setPalette(int palindex) {
- const byte *pals;
-
- _curPalIndex = palindex;
- pals = getPalettePtr(_curPalIndex, _roomResource);
- setPaletteFromPtr(pals);
-}
-
-void ScummEngine::setRoomPalette(int palindex, int room) {
- const byte *roomptr = getResourceAddress(rtRoom, room);
- assert(roomptr);
- const byte *pals = findResource(MKID('PALS'), roomptr);
- assert(pals);
- const byte *rgbs = findPalInPals(pals, palindex);
- assert(rgbs);
- setPaletteFromPtr(rgbs);
-}
-
-const byte *ScummEngine::findPalInPals(const byte *pal, int idx) {
- const byte *offs;
- uint32 size;
-
- pal = findResource(MKID('WRAP'), pal);
- if (pal == NULL)
- return NULL;
-
- offs = findResourceData(MKID('OFFS'), pal);
- if (offs == NULL)
- return NULL;
-
- size = getResourceDataSize(offs) / 4;
- if ((uint32)idx >= (uint32)size)
- return NULL;
-
- return offs + READ_LE_UINT32(offs + idx * sizeof(uint32));
-}
-
-const byte *ScummEngine::getPalettePtr(int palindex, int room) {
- const byte *cptr;
-
- cptr = getResourceAddress(rtRoom, room);
- assert(cptr);
- if (_CLUT_offs) {
- cptr += _CLUT_offs;
- } else {
- cptr = findPalInPals(cptr + _PALS_offs, palindex);
- assert(cptr);
- }
- return cptr;
-}
-
-void ScummEngine::updatePalette() {
- if (_palDirtyMax == -1)
- return;
-
- bool noir_mode = (_gameId == GID_SAMNMAX && readVar(0x8000));
- int first = _palDirtyMin;
- int num = _palDirtyMax - first + 1;
- int i;
-
- byte palette_colors[1024];
- byte *p = palette_colors;
-
- for (i = _palDirtyMin; i <= _palDirtyMax; i++) {
- byte *data;
-
- if (_features & GF_SMALL_HEADER && _version > 2)
- data = _currentPalette + _shadowPalette[i] * 3;
- else
- data = _currentPalette + i * 3;
-
- // Sam & Max film noir mode. Convert the colours to grayscale
- // before uploading them to the backend.
-
- if (noir_mode) {
- int r, g, b;
- byte brightness;
-
- r = data[0];
- g = data[1];
- b = data[2];
-
- brightness = (byte)((0.299 * r + 0.587 * g + 0.114 * b) + 0.5);
-
- *p++ = brightness;
- *p++ = brightness;
- *p++ = brightness;
- *p++ = 0;
- } else {
- *p++ = data[0];
- *p++ = data[1];
- *p++ = data[2];
- *p++ = 0;
- }
- }
-
- _system->setPalette(palette_colors, first, num);
-
- _palDirtyMax = -1;
- _palDirtyMin = 256;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/palette_he.cpp b/scumm/palette_he.cpp
deleted file mode 100644
index 2d6a471d79..0000000000
--- a/scumm/palette_he.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "scumm/scumm.h"
-#include "scumm/intern_he.h"
-#include "scumm/resource.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-void ScummEngine_v70he::remapHEPalette(const uint8 *src, uint8 *dst) {
- int r, g, b, sum, bestitem, bestsum;
- int ar, ag, ab;
- uint8 *palPtr;
- src += 30;
-
- if (_heversion >= 99) {
- palPtr = _hePalettes + 1024 + 30;
- } else {
- palPtr = _currentPalette + 30;
- }
-
- for (int j = 10; j < 246; j++) {
- bestitem = 0xFFFF;
- bestsum = 0xFFFF;
-
- r = *src++;
- g = *src++;
- b = *src++;
-
- uint8 *curPal = palPtr;
-
- for (int k = 10; k < 246; k++) {
- ar = r - *curPal++;
- ag = g - *curPal++;
- ab = b - *curPal++;
-
- sum = (ar * ar) + (ag * ag) + (ab * ab);
-
- if (bestitem == 0xFFFF || sum <= bestsum) {
- bestitem = k;
- bestsum = sum;
- }
- }
-
- dst[j] = bestitem;
- }
-}
-
-uint8 *ScummEngine_v90he::getHEPaletteIndex(int palSlot) {
- if (palSlot) {
- assert(palSlot >= 1 && palSlot <= _numPalettes);
- return _hePalettes + palSlot * 1024;
- } else {
- return _hePalettes + 1024;
- }
-}
-
-int ScummEngine_v90he::getHEPaletteSimilarColor(int palSlot, int red, int green, int start, int end) {
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- checkRange(255, 0, start, "Invalid palette slot %d");
- checkRange(255, 0, end, "Invalid palette slot %d");
-
- uint8 *pal = _hePalettes + palSlot * 1024 + start * 3;
-
- int bestsum = 0xFFFFFFFF;
- int bestitem = start;
-
- for (int i = start; i <= end; i++) {
- int dr = red - pal[0];
- int dg = green - pal[1];
- int sum = dr * dr + dg * dg * 2;
- if (sum == 0) {
- return i;
- }
- if (sum < bestsum) {
- bestsum = sum;
- bestitem = i;
- }
- pal += 3;
- }
- return bestitem;
-}
-
-int ScummEngine_v90he::getHEPaletteColorComponent(int palSlot, int color, int component) {
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- checkRange(255, 0, color, "Invalid palette slot %d");
-
- return _hePalettes[palSlot * 1024 + color * 3 + component % 3];
-}
-
-int ScummEngine_v90he::getHEPaletteColor(int palSlot, int color) {
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- checkRange(255, 0, color, "Invalid palette slot %d");
-
- return _hePalettes[palSlot * 1024 + 768 + color];
-}
-
-void ScummEngine_v90he::setHEPaletteColor(int palSlot, uint8 color, uint8 r, uint8 g, uint8 b) {
- debug(7, "setHEPaletteColor(%d, %d, %d, %d, %d)", palSlot, color, r, g, b);
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- uint8 *p = _hePalettes + palSlot * 1024 + color * 3;
- *(p + 0) = r;
- *(p + 1) = g;
- *(p + 2) = b;
- _hePalettes[palSlot * 1024 + 768 + color] = color;
-}
-
-void ScummEngine_v90he::setHEPaletteFromPtr(int palSlot, const uint8 *palData) {
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- uint8 *pc = _hePalettes + palSlot * 1024;
- uint8 *pi = pc + 768;
- for (int i = 0; i < 256; ++i) {
- *pc++ = *palData++;
- *pc++ = *palData++;
- *pc++ = *palData++;
- *pi++ = i;
- }
-}
-
-void ScummEngine_v90he::setHEPaletteFromCostume(int palSlot, int resId) {
- debug(7, "setHEPaletteFromCostume(%d, %d)", palSlot, resId);
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- const uint8 *data = getResourceAddress(rtCostume, resId);
- assert(data);
- const uint8 *rgbs = findResourceData(MKID('RGBS'), data);
- assert(rgbs);
- setHEPaletteFromPtr(palSlot, rgbs);
-}
-
-void ScummEngine_v90he::setHEPaletteFromImage(int palSlot, int resId, int state) {
- debug(7, "setHEPaletteFromImage(%d, %d, %d)", palSlot, resId, state);
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- uint8 *data = getResourceAddress(rtImage, resId);
- assert(data);
- const uint8 *rgbs = findWrappedBlock(MKID('RGBS'), data, state, 0);
- assert(rgbs);
- setHEPaletteFromPtr(palSlot, rgbs);
-}
-
-void ScummEngine_v90he::setHEPaletteFromRoom(int palSlot, int resId, int state) {
- debug(7, "setHEPaletteFromRoom(%d, %d, %d)", palSlot, resId, state);
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- const uint8 *data = getResourceAddress(rtRoom, resId);
- assert(data);
- const uint8 *pals = findResourceData(MKID('PALS'), data);
- assert(pals);
- const uint8 *rgbs = findPalInPals(pals, state);
- assert(rgbs);
- setHEPaletteFromPtr(palSlot, rgbs);
-}
-
-void ScummEngine_v90he::restoreHEPalette(int palSlot) {
- debug(7, "restoreHEPalette(%d)", palSlot);
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- if (palSlot != 1) {
- memcpy(_hePalettes + palSlot * 1024, _hePalettes + 1024, 1024);
- }
-}
-
-void ScummEngine_v90he::copyHEPalette(int dstPalSlot, int srcPalSlot) {
- debug(7, "copyHEPalette(%d, %d)", dstPalSlot, srcPalSlot);
- assert(dstPalSlot >= 1 && dstPalSlot <= _numPalettes);
- assert(srcPalSlot >= 1 && srcPalSlot <= _numPalettes);
- if (dstPalSlot != srcPalSlot) {
- memcpy(_hePalettes + dstPalSlot * 1024, _hePalettes + srcPalSlot * 1024, 1024);
- }
-}
-
-void ScummEngine_v90he::copyHEPaletteColor(int palSlot, uint8 dstColor, uint8 srcColor) {
- debug(7, "copyHEPaletteColor(%d, %d, %d)", palSlot, dstColor, srcColor);
- checkRange(_numPalettes, 1, palSlot, "Invalid palette %d");
- uint8 *dstPal = _hePalettes + palSlot * 1024 + dstColor * 3;
- uint8 *srcPal = _hePalettes + 1024 + srcColor * 3;
- memcpy(dstPal, srcPal, 3);
- _hePalettes[palSlot * 1024 + 768 + dstColor] = srcColor;
-}
-
-void ScummEngine_v99he::setPaletteFromPtr(const byte *ptr, int numcolor) {
- int i;
- byte *dest, r, g, b;
-
- if (numcolor < 0) {
- numcolor = getResourceDataSize(ptr) / 3;
- }
-
- checkRange(256, 0, numcolor, "Too many colors (%d) in Palette");
-
- dest = _hePalettes + 1024;
-
- for (i = 0; i < numcolor; i++) {
- r = *ptr++;
- g = *ptr++;
- b = *ptr++;
-
- if (i == 15 || r < 252 || g < 252 || b < 252) {
- *dest++ = r;
- *dest++ = g;
- *dest++ = b;
- _hePalettes[1792 + i] = i;
- } else {
- dest += 3;
- }
- }
-
- memcpy(_hePalettes, _hePalettes + 1024, 768);
-
- for (i = 0; i < 10; ++i)
- _hePalettes[1792 + i] = i;
- for (i = 246; i < 256; ++i)
- _hePalettes[1792 + i] = i;
-
- setDirtyColors(0, numcolor - 1);
-}
-
-void ScummEngine_v99he::darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor) {
- uint8 *src, *dst;
- int color, j;
-
- src = _hePalettes + startColor * 3;
- dst = _hePalettes + 1024 + startColor * 3;
- for (j = startColor; j <= endColor; j++) {
- color = *src++;
- color = color * redScale / 0xFF;
- if (color > 255)
- color = 255;
- *dst++ = color;
-
- color = *src++;
- color = color * greenScale / 0xFF;
- if (color > 255)
- color = 255;
- *dst++ = color;
-
- color = *src++;
- color = color * blueScale / 0xFF;
- if (color > 255)
- color = 255;
- *dst++ = color;
-
- _hePalettes[1792 + j] = j;
- setDirtyColors(j, endColor);
- }
-}
-
-void ScummEngine_v99he::copyPalColor(int dst, int src) {
- byte *dp, *sp;
-
- if ((uint) dst >= 256 || (uint) src >= 256)
- error("copyPalColor: invalid values, %d, %d", dst, src);
-
- dp = &_hePalettes[1024 + dst * 3];
- sp = &_hePalettes[1024 + src * 3];
-
- dp[0] = sp[0];
- dp[1] = sp[1];
- dp[2] = sp[2];
- _hePalettes[1792 + dst] = dst;
-
- setDirtyColors(dst, dst);
-}
-
-void ScummEngine_v99he::setPalColor(int idx, int r, int g, int b) {
- _hePalettes[1024 + idx * 3 + 0] = r;
- _hePalettes[1024 + idx * 3 + 1] = g;
- _hePalettes[1024 + idx * 3 + 2] = b;
- _hePalettes[1792 + idx] = idx;
- setDirtyColors(idx, idx);
-}
-
-void ScummEngine_v99he::updatePalette() {
- if (_palDirtyMax == -1)
- return;
-
- int num = _palDirtyMax - _palDirtyMin + 1;
- int i;
-
- byte palette_colors[1024];
- byte *p = palette_colors;
-
- for (i = _palDirtyMin; i <= _palDirtyMax; i++) {
- byte *data = _hePalettes + 1024 + i * 3;
-
- *p++ = data[0];
- *p++ = data[1];
- *p++ = data[2];
- *p++ = 0;
- }
-
- _system->setPalette(palette_colors, _palDirtyMin, num);
-
- _palDirtyMax = -1;
- _palDirtyMin = 256;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/player_mod.cpp b/scumm/player_mod.cpp
deleted file mode 100644
index 773d34732d..0000000000
--- a/scumm/player_mod.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/player_mod.h"
-#include "sound/mixer.h"
-#include "sound/rate.h"
-
-namespace Scumm {
-
-Player_MOD::Player_MOD(ScummEngine *scumm) {
- int i;
- _mixer = scumm->_mixer;
- _samplerate = _mixer->getOutputRate();
- _mixamt = 0;
- _mixpos = 0;
-
- for (i = 0; i < MOD_MAXCHANS; i++) {
- _channels[i].id = 0;
- _channels[i].vol = 0;
- _channels[i].freq = 0;
- _channels[i].converter = NULL;
- _channels[i].input = NULL;
- }
-
- _playproc = NULL;
- _playparam = NULL;
-
- _mixer->setupPremix(this);
-}
-
-Player_MOD::~Player_MOD() {
- // Detach the premix callback handler
- _mixer->setupPremix(0);
- for (int i = 0; i < MOD_MAXCHANS; i++) {
- if (!_channels[i].id)
- continue;
- delete _channels[i].converter;
- delete _channels[i].input;
- }
-}
-
-void Player_MOD::setMusicVolume(int vol) {
- _maxvol = vol;
-}
-
-void Player_MOD::setUpdateProc(ModUpdateProc *proc, void *param, int freq) {
- _playproc = proc;
- _playparam = param;
- _mixamt = _samplerate / freq;
-}
-void Player_MOD::clearUpdateProc() {
- _playproc = NULL;
- _playparam = NULL;
- _mixamt = 0;
-}
-
-void Player_MOD::startChannel(int id, void *data, int size, int rate, uint8 vol, int loopStart, int loopEnd, int8 pan) {
- int i;
- if (id == 0)
- error("player_mod - attempted to start channel id 0");
-
- for (i = 0; i < MOD_MAXCHANS; i++) {
- if (!_channels[i].id)
- break;
- }
- if (i == MOD_MAXCHANS) {
- warning("player_mod - too many music channels playing (%i max)",MOD_MAXCHANS);
- return;
- }
- _channels[i].id = id;
- _channels[i].vol = vol;
- _channels[i].pan = pan;
- _channels[i].freq = rate;
- _channels[i].input = makeLinearInputStream(rate, Audio::Mixer::FLAG_AUTOFREE | (loopStart != loopEnd ? Audio::Mixer::FLAG_LOOP : 0), (const byte*)data, size, loopStart, loopEnd - loopStart);
- _channels[i].converter = Audio::makeRateConverter(rate, _mixer->getOutputRate(), false, false);
-}
-
-void Player_MOD::stopChannel(int id) {
- if (id == 0)
- error("player_mod - attempted to stop channel id 0");
- for (int i = 0; i < MOD_MAXCHANS; i++) {
- if (_channels[i].id == id) {
- delete _channels[i].converter;
- _channels[i].converter = NULL;
- delete _channels[i].input;
- _channels[i].input = NULL;
- _channels[i].id = 0;
- _channels[i].vol = 0;
- _channels[i].freq = 0;
- }
- }
-}
-void Player_MOD::setChannelVol(int id, uint8 vol) {
- if (id == 0)
- error("player_mod - attempted to set volume for channel id 0");
- for (int i = 0; i < MOD_MAXCHANS; i++) {
- if (_channels[i].id == id) {
- _channels[i].vol = vol;
- break;
- }
- }
-}
-
-void Player_MOD::setChannelPan(int id, int8 pan) {
- if (id == 0)
- error("player_mod - attempted to set pan for channel id 0");
- for (int i = 0; i < MOD_MAXCHANS; i++) {
- if (_channels[i].id == id) {
- _channels[i].pan = pan;
- break;
- }
- }
-}
-
-void Player_MOD::setChannelFreq(int id, int freq) {
- if (id == 0)
- error("player_mod - attempted to set frequency for channel id 0");
- for (int i = 0; i < MOD_MAXCHANS; i++) {
- if (_channels[i].id == id) {
- _channels[i].freq = freq;
- delete _channels[i].converter;
- _channels[i].converter = Audio::makeRateConverter(freq, _mixer->getOutputRate(), false, false);
- break;
- }
- }
-}
-
-void Player_MOD::do_mix(int16 *data, uint len) {
- int i;
- int dpos = 0;
- uint dlen = 0;
- memset(data, 0, 2 * len * sizeof(int16));
- while (len) {
- if (_playproc) {
- dlen = _mixamt - _mixpos;
- if (!_mixpos)
- _playproc(_playparam);
- if (dlen <= len) {
- _mixpos = 0;
- len -= dlen;
- } else {
- _mixpos = _mixamt - len;
- dlen = len;
- len = 0;
- }
- } else {
- dlen = len;
- len = 0;
- }
- for (i = 0; i < MOD_MAXCHANS; i++)
- if (_channels[i].id) {
- Audio::st_volume_t vol_l = (127 - _channels[i].pan) * _channels[i].vol / 127;
- Audio::st_volume_t vol_r = (127 + _channels[i].pan) * _channels[i].vol / 127;
- _channels[i].converter->flow(*_channels[i].input, &data[dpos*2], dlen, vol_l, vol_r);
- }
- dpos += dlen;
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/player_mod.h b/scumm/player_mod.h
deleted file mode 100644
index 317bf7fd6e..0000000000
--- a/scumm/player_mod.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PLAYER_MOD_H
-#define PLAYER_MOD_H
-
-#include "scumm/scumm.h"
-#include "sound/audiostream.h"
-
-namespace Audio {
- class RateConverter;
-}
-
-namespace Scumm {
-
-/**
- * Generic Amiga MOD mixer - provides a 60Hz 'update' routine.
- */
-class Player_MOD : public AudioStream {
-public:
- Player_MOD(ScummEngine *scumm);
- virtual ~Player_MOD();
- virtual void setMusicVolume(int vol);
-
- virtual void startChannel(int id, void *data, int size, int rate, uint8 vol, int loopStart = 0, int loopEnd = 0, int8 pan = 0);
- virtual void stopChannel(int id);
- virtual void setChannelVol(int id, uint8 vol);
- virtual void setChannelPan(int id, int8 pan);
- virtual void setChannelFreq(int id, int freq);
-
- typedef void ModUpdateProc(void *param);
-
- virtual void setUpdateProc(ModUpdateProc *proc, void *param, int freq);
- virtual void clearUpdateProc();
-
- // AudioStream API
- int readBuffer(int16 *buffer, const int numSamples) {
- do_mix(buffer, numSamples / 2);
- return numSamples;
- }
- bool isStereo() const { return true; }
- bool endOfData() const { return false; }
- int getRate() const { return _samplerate; }
-
-private:
- enum {
- MOD_MAXCHANS = 24
- };
-
- struct soundChan {
- int id;
- uint8 vol;
- int8 pan;
- uint16 freq;
- Audio::RateConverter *converter;
- AudioStream *input;
- };
-
- Audio::Mixer *_mixer;
-
- uint32 _mixamt;
- uint32 _mixpos;
- int _samplerate;
-
- soundChan _channels[MOD_MAXCHANS];
-
- uint8 _maxvol;
-
- virtual void do_mix(int16 *buf, uint len);
-
- ModUpdateProc *_playproc;
- void *_playparam;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/player_nes.cpp b/scumm/player_nes.cpp
deleted file mode 100644
index 8564ac1e41..0000000000
--- a/scumm/player_nes.cpp
+++ /dev/null
@@ -1,1085 +0,0 @@
-
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * aint32 with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "base/engine.h"
-#include "scumm/player_nes.h"
-#include "scumm/scumm.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-static const byte channelMask[4] = {1, 2, 4, 8};
-
-static const uint16 freqTable[64] = {
- 0x07F0, 0x077E, 0x0712, 0x06AE, 0x064E, 0x05F3, 0x059E, 0x054D,
- 0x0501, 0x04B9, 0x0475, 0x0435, 0x03F8, 0x03BF, 0x0389, 0x0357,
- 0x0327, 0x02F9, 0x02CF, 0x02A6, 0x0280, 0x025C, 0x023A, 0x021A,
- 0x01FC, 0x01DF, 0x01C4, 0x01AB, 0x0193, 0x017C, 0x0167, 0x0152,
- 0x013F, 0x012D, 0x011C, 0x010C, 0x00FD, 0x00EE, 0x00E1, 0x00D4,
- 0x00C8, 0x00BD, 0x00B2, 0x00A8, 0x009F, 0x0096, 0x008D, 0x0085,
- 0x007E, 0x0076, 0x0070, 0x0069, 0x0063, 0x005E, 0x0058, 0x0053,
- 0x004F, 0x004A, 0x0046, 0x0042, 0x003E, 0x003A, 0x0037, 0x0034
-};
-
-static const byte instChannel[16] = {
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 1, 3, 3, 3
-};
-static const byte startCmd[16] = {
- 0x05, 0x03, 0x06, 0x08, 0x0B, 0x01, 0x01, 0x1A,
- 0x16, 0x06, 0x04, 0x17, 0x02, 0x10, 0x0E, 0x0D
-};
-static const byte releaseCmd[16] = {
- 0x0F, 0x00, 0x00, 0x09, 0x00, 0x14, 0x15, 0x00,
- 0x00, 0x00, 0x1B, 0x1B, 0x0F, 0x0F, 0x0F, 0x0F
-};
-static const byte nextCmd[28] = {
- 0xFF, 0xFF, 0xFF, 0xFF, 0x17, 0xFF, 0x07, 0xFF,
- 0xFF, 0x0A, 0x09, 0x0C, 0x00, 0x00, 0x00, 0x00,
- 0x11, 0x12, 0x11, 0x03, 0xFF, 0xFF, 0x18, 0x00,
- 0x19, 0x00, 0x00, 0x00
-};
-static const byte nextDelay[28] = {
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
- 0x00, 0x05, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00,
- 0x03, 0x00, 0x00, 0x00
-};
-
-namespace APUe {
-
-struct tAPU {
- int Cycles;
- int BufPos;
- int SampleRate;
-} APU;
-
-const byte LengthCounts[32] = {
- 0x0A,0xFE,
- 0x14,0x02,
- 0x28,0x04,
- 0x50,0x06,
- 0xA0,0x08,
- 0x3C,0x0A,
- 0x0E,0x0C,
- 0x1A,0x0E,
-
- 0x0C,0x10,
- 0x18,0x12,
- 0x30,0x14,
- 0x60,0x16,
- 0xC0,0x18,
- 0x48,0x1A,
- 0x10,0x1C,
- 0x20,0x1E
-};
-
-static struct {
- byte volume, envelope, wavehold, duty, swpspeed, swpdir, swpstep, swpenab;
- uint32 freq; // short
- byte Vol;
- byte CurD;
- byte Timer;
- byte EnvCtr, Envelope, BendCtr;
- bool Enabled, ValidFreq, Active;
- bool EnvClk, SwpClk;
- uint32 Cycles; // short
- int32 Pos;
-} Square0, Square1;
-
-const int8 Duties[4][8] = {
- {-4,+4,-4,-4,-4,-4,-4,-4},
- {-4,+4,+4,-4,-4,-4,-4,-4},
- {-4,+4,+4,+4,+4,-4,-4,-4},
- {+4,-4,-4,+4,+4,+4,+4,+4}
-};
-
-inline void Square0_CheckActive(void) {
- Square0.ValidFreq = (Square0.freq >= 0x8) && ((Square0.swpdir) || !((Square0.freq + (Square0.freq >> Square0.swpstep)) & 0x800));
- Square0.Active = Square0.Timer && Square0.ValidFreq;
- Square0.Pos = Square0.Active ? (Duties[Square0.duty][Square0.CurD] * Square0.Vol) : 0;
-}
-
-inline void Square0_Write(int Reg, byte Val) {
- switch (Reg) {
- case 0:
- Square0.volume = Val & 0xF;
- Square0.envelope = Val & 0x10;
- Square0.wavehold = Val & 0x20;
- Square0.duty = (Val >> 6) & 0x3;
- Square0.Vol = Square0.envelope ? Square0.volume : Square0.Envelope;
- break;
-
- case 1:
- Square0.swpstep = Val & 0x07;
- Square0.swpdir = Val & 0x08;
- Square0.swpspeed = (Val >> 4) & 0x7;
- Square0.swpenab = Val & 0x80;
- Square0.SwpClk = true;
- break;
-
- case 2:
- Square0.freq &= 0x700;
- Square0.freq |= Val;
- break;
-
- case 3:
- Square0.freq &= 0xFF;
- Square0.freq |= (Val & 0x7) << 8;
-
- if (Square0.Enabled)
- Square0.Timer = LengthCounts[(Val >> 3) & 0x1F];
-
- Square0.CurD = 0;
- Square0.EnvClk = true;
- break;
-
- case 4:
- if (!(Square0.Enabled = Val ? true : false))
- Square0.Timer = 0;
- break;
- }
- Square0_CheckActive();
-}
-
-inline void Square0_Run(void) {
- if (!--Square0.Cycles) {
- Square0.Cycles = (Square0.freq + 1) << 1;
- Square0.CurD = (Square0.CurD + 1) & 0x7;
-
- if (Square0.Active)
- Square0.Pos = Duties[Square0.duty][Square0.CurD] * Square0.Vol;
- }
-}
-
-inline void Square0_QuarterFrame(void) {
- if (Square0.EnvClk) {
- Square0.EnvClk = false;
- Square0.Envelope = 0xF;
- Square0.EnvCtr = Square0.volume + 1;
- } else if (!--Square0.EnvCtr) {
- Square0.EnvCtr = Square0.volume + 1;
-
- if (Square0.Envelope)
- Square0.Envelope--;
- else
- Square0.Envelope = Square0.wavehold ? 0xF : 0x0;
- }
-
- Square0.Vol = Square0.envelope ? Square0.volume : Square0.Envelope;
- Square0_CheckActive();
-}
-
-inline void Square0_HalfFrame(void) {
- if (!--Square0.BendCtr) {
- Square0.BendCtr = Square0.swpspeed + 1;
-
- if (Square0.swpenab && Square0.swpstep && Square0.ValidFreq) {
- int sweep = Square0.freq >> Square0.swpstep;
- Square0.freq += Square0.swpdir ? ~sweep : sweep;
- }
- }
-
- if (Square0.SwpClk) {
- Square0.SwpClk = false;
- Square0.BendCtr = Square0.swpspeed + 1;
- }
-
- if (Square0.Timer && !Square0.wavehold)
- Square0.Timer--;
-
- Square0_CheckActive();
-}
-
-inline void Square1_CheckActive(void) {
- Square1.ValidFreq = (Square1.freq >= 0x8) && ((Square1.swpdir) || !((Square1.freq + (Square1.freq >> Square1.swpstep)) & 0x800));
- Square1.Active = Square1.Timer && Square1.ValidFreq;
- Square1.Pos = Square1.Active ? (Duties[Square1.duty][Square1.CurD] * Square1.Vol) : 0;
-}
-
-inline void Square1_Write(int Reg, byte Val) {
- switch (Reg) {
- case 0:
- Square1.volume = Val & 0xF;
- Square1.envelope = Val & 0x10;
- Square1.wavehold = Val & 0x20;
- Square1.duty = (Val >> 6) & 0x3;
- Square1.Vol = Square1.envelope ? Square1.volume : Square1.Envelope;
- break;
-
- case 1:
- Square1.swpstep = Val & 0x07;
- Square1.swpdir = Val & 0x08;
- Square1.swpspeed = (Val >> 4) & 0x7;
- Square1.swpenab = Val & 0x80;
- Square1.SwpClk = true;
- break;
-
- case 2:
- Square1.freq &= 0x700;
- Square1.freq |= Val;
- break;
-
- case 3:
- Square1.freq &= 0xFF;
- Square1.freq |= (Val & 0x7) << 8;
-
- if (Square1.Enabled)
- Square1.Timer = LengthCounts[(Val >> 3) & 0x1F];
-
- Square1.CurD = 0;
- Square1.EnvClk = true;
- break;
-
- case 4:
- if (!(Square1.Enabled = Val ? true : false))
- Square1.Timer = 0;
- break;
- }
- Square1_CheckActive();
-}
-
-inline void Square1_Run(void) {
- if (!--Square1.Cycles) {
- Square1.Cycles = (Square1.freq + 1) << 1;
- Square1.CurD = (Square1.CurD + 1) & 0x7;
-
- if (Square1.Active)
- Square1.Pos = Duties[Square1.duty][Square1.CurD] * Square1.Vol;
- }
-}
-
-inline void Square1_QuarterFrame(void) {
- if (Square1.EnvClk) {
- Square1.EnvClk = false;
- Square1.Envelope = 0xF;
- Square1.EnvCtr = Square1.volume + 1;
- } else if (!--Square1.EnvCtr) {
- Square1.EnvCtr = Square1.volume + 1;
-
- if (Square1.Envelope)
- Square1.Envelope--;
- else
- Square1.Envelope = Square1.wavehold ? 0xF : 0x0;
- }
-
- Square1.Vol = Square1.envelope ? Square1.volume : Square1.Envelope;
- Square1_CheckActive();
-}
-
-inline void Square1_HalfFrame(void) {
- if (!--Square1.BendCtr) {
- Square1.BendCtr = Square1.swpspeed + 1;
-
- if (Square1.swpenab && Square1.swpstep && Square1.ValidFreq) {
- int sweep = Square1.freq >> Square1.swpstep;
- Square1.freq += Square1.swpdir ? -sweep : sweep;
- }
- }
-
- if (Square1.SwpClk) {
- Square1.SwpClk = false;
- Square1.BendCtr = Square1.swpspeed + 1;
- }
-
- if (Square1.Timer && !Square1.wavehold)
- Square1.Timer--;
-
- Square1_CheckActive();
-}
-
-static struct {
- byte linear, wavehold;
- uint32 freq; // short
- byte CurD;
- byte Timer, LinCtr;
- bool Enabled, Active;
- bool LinClk;
- uint32 Cycles; // short
- int32 Pos;
-} Triangle;
-
-const int8 TriDuty[32] = {
- -8,-7,-6,-5,-4,-3,-2,-1,
- +0,+1,+2,+3,+4,+5,+6,+7,
- +7,+6,+5,+4,+3,+2,+1,+0,
- -1,-2,-3,-4,-5,-6,-7,-8
-};
-
-inline void Triangle_CheckActive(void) {
- Triangle.Active = Triangle.Timer && Triangle.LinCtr;
-
- if (Triangle.freq < 4)
- Triangle.Pos = 0; // beyond hearing range
- else
- Triangle.Pos = TriDuty[Triangle.CurD] * 8;
-}
-
-inline void Triangle_Write(int Reg, byte Val) {
- switch (Reg) {
- case 0:
- Triangle.linear = Val & 0x7F;
- Triangle.wavehold = (Val >> 7) & 0x1;
- break;
-
- case 2:
- Triangle.freq &= 0x700;
- Triangle.freq |= Val;
- break;
-
- case 3:
- Triangle.freq &= 0xFF;
- Triangle.freq |= (Val & 0x7) << 8;
-
- if (Triangle.Enabled)
- Triangle.Timer = LengthCounts[(Val >> 3) & 0x1F];
-
- Triangle.LinClk = true;
- break;
-
- case 4:
- if (!(Triangle.Enabled = Val ? true : false))
- Triangle.Timer = 0;
- break;
- }
- Triangle_CheckActive();
-}
-
-inline void Triangle_Run(void) {
- if (!--Triangle.Cycles) {
- Triangle.Cycles = Triangle.freq + 1;
-
- if (Triangle.Active) {
- Triangle.CurD++;
- Triangle.CurD &= 0x1F;
-
- if (Triangle.freq < 4)
- Triangle.Pos = 0; // beyond hearing range
- else
- Triangle.Pos = TriDuty[Triangle.CurD] * 8;
- }
- }
-}
-
-inline void Triangle_QuarterFrame(void) {
- if (Triangle.LinClk)
- Triangle.LinCtr = Triangle.linear;
- else if (Triangle.LinCtr)
- Triangle.LinCtr--;
-
- if (!Triangle.wavehold)
- Triangle.LinClk = false;
-
- Triangle_CheckActive();
-}
-
-inline void Triangle_HalfFrame(void) {
- if (Triangle.Timer && !Triangle.wavehold)
- Triangle.Timer--;
-
- Triangle_CheckActive();
-}
-
-static struct {
- byte volume, envelope, wavehold, datatype;
- uint32 freq; // short
- uint32 CurD; // short
- byte Vol;
- byte Timer;
- byte EnvCtr, Envelope;
- bool Enabled;
- bool EnvClk;
- uint32 Cycles; // short
- int32 Pos;
-} Noise;
-
-const uint32 NoiseFreq[16] = {
- 0x004,0x008,0x010,0x020,0x040,0x060,0x080,0x0A0,
- 0x0CA,0x0FE,0x17C,0x1FC,0x2FA,0x3F8,0x7F2,0xFE4
-};
-
-inline void Noise_Write(int Reg, byte Val) {
- switch (Reg) {
- case 0:
- Noise.volume = Val & 0x0F;
- Noise.envelope = Val & 0x10;
- Noise.wavehold = Val & 0x20;
- Noise.Vol = Noise.envelope ? Noise.volume : Noise.Envelope;
-
- if (Noise.Timer)
- Noise.Pos = ((Noise.CurD & 0x4000) ? -2 : 2) * Noise.Vol;
- break;
-
- case 2:
- Noise.freq = Val & 0xF;
- Noise.datatype = Val & 0x80;
- break;
-
- case 3:
- if (Noise.Enabled)
- Noise.Timer = LengthCounts[(Val >> 3) & 0x1F];
-
- Noise.EnvClk = true;
- break;
-
- case 4:
- if (!(Noise.Enabled = Val ? true : false))
- Noise.Timer = 0;
- break;
- }
-}
-
-inline void Noise_Run(void) {
- if (!--Noise.Cycles) {
- Noise.Cycles = NoiseFreq[Noise.freq]; /* no + 1 here */
-
- if (Noise.datatype)
- Noise.CurD = (Noise.CurD << 1) | (((Noise.CurD >> 14) ^ (Noise.CurD >> 8)) & 0x1);
- else
- Noise.CurD = (Noise.CurD << 1) | (((Noise.CurD >> 14) ^ (Noise.CurD >> 13)) & 0x1);
-
- if (Noise.Timer)
- Noise.Pos = ((Noise.CurD & 0x4000) ? -2 : 2) * Noise.Vol;
- }
-}
-
-inline void Noise_QuarterFrame(void) {
- if (Noise.EnvClk) {
- Noise.EnvClk = false;
- Noise.Envelope = 0xF;
- Noise.EnvCtr = Noise.volume + 1;
- } else if (!--Noise.EnvCtr) {
- Noise.EnvCtr = Noise.volume + 1;
-
- if (Noise.Envelope)
- Noise.Envelope--;
- else
- Noise.Envelope = Noise.wavehold ? 0xF : 0x0;
- }
-
- Noise.Vol = Noise.envelope ? Noise.volume : Noise.Envelope;
-
- if (Noise.Timer)
- Noise.Pos = ((Noise.CurD & 0x4000) ? -2 : 2) * Noise.Vol;
-}
-
-inline void Noise_HalfFrame(void) {
- if (Noise.Timer && !Noise.wavehold)
- Noise.Timer--;
-}
-
-static struct {
- uint32 Cycles;
- int Num;
-} Frame;
-
-inline void Frame_Run(void) {
- if (!--Frame.Cycles) {
- Frame.Cycles = 7457;
-
- if (Frame.Num < 4) {
- Square0_QuarterFrame();
- Square1_QuarterFrame();
- Triangle_QuarterFrame();
- Noise_QuarterFrame();
-
- if (!(Frame.Num & 1)) {
- Square0_HalfFrame();
- Square1_HalfFrame();
- Triangle_HalfFrame();
- Noise_HalfFrame();
- }
- }
-
- if (Frame.Num & 1)
- Frame.Cycles++;
-
- Frame.Num++;
-
- if (Frame.Num == 5)
- Frame.Num = 0;
- }
-}
-
-void APU_WriteReg(int Addr, byte Val) {
- switch (Addr) {
- case 0x000: Square0_Write(0,Val); break;
- case 0x001: Square0_Write(1,Val); break;
- case 0x002: Square0_Write(2,Val); break;
- case 0x003: Square0_Write(3,Val); break;
- case 0x004: Square1_Write(0,Val); break;
- case 0x005: Square1_Write(1,Val); break;
- case 0x006: Square1_Write(2,Val); break;
- case 0x007: Square1_Write(3,Val); break;
- case 0x008: Triangle_Write(0,Val); break;
- case 0x009: Triangle_Write(1,Val); break;
- case 0x00A: Triangle_Write(2,Val); break;
- case 0x00B: Triangle_Write(3,Val); break;
- case 0x00C: Noise_Write(0,Val); break;
- case 0x00D: Noise_Write(1,Val); break;
- case 0x00E: Noise_Write(2,Val); break;
- case 0x00F: Noise_Write(3,Val); break;
- case 0x015: Square0_Write(4,Val & 0x1);
- Square1_Write(4,Val & 0x2);
- Triangle_Write(4,Val & 0x4);
- Noise_Write(4,Val & 0x8);
- break;
- }
-}
-
-byte APU_Read4015(void) {
- byte result =
- (( Square0.Timer) ? 0x01 : 0) |
- (( Square1.Timer) ? 0x02 : 0) |
- ((Triangle.Timer) ? 0x04 : 0) |
- (( Noise.Timer) ? 0x08 : 0);
- return result;
-}
-
-void APU_Reset (void) {
- APU.BufPos = 0;
-
- memset(&Frame, 0, sizeof(Frame));
- memset(&Square0, 0, sizeof(Square0));
- memset(&Square1, 0, sizeof(Square1));
- memset(&Triangle, 0, sizeof(Triangle));
- memset(&Noise, 0, sizeof(Noise));
-
- Noise.CurD = 1;
- APU.Cycles = 1;
- Square0.Cycles = 1;
- Square0.EnvCtr = 1;
- Square0.BendCtr = 1;
- Square1.Cycles = 1;
- Square1.EnvCtr = 1;
- Square1.BendCtr = 1;
- Triangle.Cycles = 1;
- Noise.Cycles = 1;
- Noise.EnvCtr = 1;
- Frame.Cycles = 1;
-}
-
-int16 APU_GetSample(void) {
- int sampcycles = 0, samppos = 0;
- int NewBufPos = APU.BufPos;
- while (NewBufPos == APU.BufPos) {
- NewBufPos = APU.SampleRate * ++APU.Cycles / 1789773;
- if (APU.Cycles == 1789773) // we've generated 1 second, so we can reset our counters now
- APU.Cycles = NewBufPos = 0;
-
- Frame_Run();
- Square0_Run();
- Square1_Run();
- Triangle_Run();
- Noise_Run();
-
- samppos += Square0.Pos + Square1.Pos + Triangle.Pos + Noise.Pos;
- sampcycles++;
- }
-
- APU.BufPos = NewBufPos;
-
- return (samppos << 6) / sampcycles;
-}
-
-}
-
-Player_NES::Player_NES(ScummEngine *scumm) {
- int i;
- _vm = scumm;
- _mixer = scumm->_mixer;
- APUe::APU.SampleRate = _sample_rate = _mixer->getOutputRate();
-
- _samples_per_frame = _sample_rate / 60;
- _current_sample = 0;
-
- for (i = 0; i < NUMSLOTS; i++) {
- _slot[i].id = -1;
- _slot[i].framesleft = 0;
- _slot[i].type = 0;
- _slot[i].offset = 0;
- _slot[i].data = NULL;
- }
-
- for (i = 0; i < NUMCHANS; i++) {
- _mchan[i].command = 0;
- _mchan[i].framedelay = 0;
- _mchan[i].pitch = 0;
- _mchan[i].volume = 0;
- _mchan[i].voldelta = 0;
- _mchan[i].envflags = 0;
- _mchan[i].cmdlock = 0;
- }
- isSFXplaying = wasSFXplaying = false;
-
- auxData1 = auxData2 = NULL;
- numNotes = 0;
-
- APU_writeControl(0);
-
- APUe::APU_Reset();
-
- _mixer->setupPremix(this);
-}
-
-Player_NES::~Player_NES() {
- _mixer->setupPremix(0);
-}
-
-void Player_NES::setMusicVolume (int vol) {
- _maxvol = vol;
-}
-
-int Player_NES::readBuffer(int16 *buffer, const int numSamples) {
- for (int n = 0; n < numSamples; n++) {
- buffer[n] = APUe::APU_GetSample() * _maxvol / 255;
- _current_sample++;
-
- if (_current_sample == _samples_per_frame) {
- _current_sample = 0;
- sound_play();
- }
- }
- return numSamples;
-}
-void Player_NES::stopAllSounds() {
- for (int i = 0; i < NUMSLOTS; i++) {
- _slot[i].framesleft = 0;
- _slot[i].type = 0;
- _slot[i].id = -1;
- }
-
- isSFXplaying = 0;
- checkSilenceChannels(0);
-}
-
-void Player_NES::stopSound(int nr) {
- if (nr == -1)
- return;
-
- for (int i = 0; i < NUMSLOTS; i++) {
- if (_slot[i].id != nr)
- continue;
-
- isSFXplaying = 0;
- _slot[i].framesleft = 0;
- _slot[i].type = 0;
- _slot[i].id = -1;
- checkSilenceChannels(i);
- }
-}
-
-void Player_NES::startSound(int nr) {
- byte *data = _vm->getResourceAddress(rtSound, nr) + 2;
- assert(data);
-
- int soundType = data[1];
- int chan = data[0];
-
- if (chan == 4) {
- if (_slot[2].framesleft)
- return;
- chan = 0;
- }
-
- if (soundType < _slot[chan].type)
- return;
-
- _slot[chan].type = soundType;
- _slot[chan].id = nr;
- _slot[chan].data = data;
- _slot[chan].offset = 2;
- _slot[chan].framesleft = 1;
- checkSilenceChannels(chan);
- if (chan == 2) {
- numNotes = _slot[chan].data[2];
- auxData1 = _slot[chan].data + 3;
- auxData2 = auxData1 + numNotes;
- _slot[chan].data = auxData2 + numNotes;
- _slot[chan].offset = 0;
-
- for (int i = 0; i < NUMCHANS; i++)
- _mchan[i].cmdlock = 0;
- }
-}
-
-void Player_NES::checkSilenceChannels(int chan) {
- for (chan--; chan >= 0; chan--) {
- if (_slot[chan].framesleft)
- return;
- }
- APU_writeControl(0);
-}
-
-void Player_NES::sound_play() {
- if (_slot[0].framesleft)
- playSFX(0);
- else if (_slot[1].framesleft)
- playSFX(1);
-
- playMusic();
-}
-
-void Player_NES::playSFX (int nr) {
- if (--_slot[nr].framesleft)
- return;
-
- while (1) {
- int a = _slot[nr].data[_slot[nr].offset++];
- if (a < 16) {
- a >>= 2;
- APU_writeControl(APU_readStatus() | channelMask[a]);
- isSFXplaying = true;
- APU_writeChannel(a, 0, _slot[nr].data[_slot[nr].offset++]);
- APU_writeChannel(a, 1, _slot[nr].data[_slot[nr].offset++]);
- APU_writeChannel(a, 2, _slot[nr].data[_slot[nr].offset++]);
- APU_writeChannel(a, 3, _slot[nr].data[_slot[nr].offset++]);
- } else if (a == 0xFE) {
- _slot[nr].offset = 2;
- } else if (a == 0xFF) {
- _slot[nr].id = -1;
- _slot[nr].type = 0;
- isSFXplaying = false;
- APU_writeControl(0);
-
- if (!nr && _slot[1].framesleft) {
- _slot[1].framesleft = 1;
- isSFXplaying = true;
- }
- return;
- } else {
- _slot[nr].framesleft = _slot[nr].data[_slot[nr].offset++];
- return;
- }
- }
-}
-
-void Player_NES::playMusic() {
- if (!_slot[2].framesleft)
- return;
-
- if (wasSFXplaying && !isSFXplaying)
- for (int x = 1; x >= 0; x--)
- if (_mchan[x].cmdlock) {
- _mchan[x].command = _mchan[x].cmdlock;
- _mchan[x].framedelay = 1;
- }
-
- wasSFXplaying = isSFXplaying;
- if (!--_slot[2].framesleft) {
-top:
- int b = _slot[2].data[_slot[2].offset++];
- if (b == 0xFF) {
- _slot[2].id = -1;
- _slot[2].type = 0;
- b = 0;
- } else if (b == 0xFE) {
- _slot[2].offset = 0;
- goto top;
- } else {
- if (b < numNotes) {
- int inst = auxData1[b];
- int ch = instChannel[inst];
- _mchan[ch].pitch = auxData2[b];
- _mchan[ch].cmdlock = startCmd[inst];
- _mchan[ch].command = startCmd[inst];
- _mchan[ch].framedelay = 1;
- goto top;
- }
- b -= numNotes;
- if (b < 16) {
- int inst = b;
- int ch = instChannel[inst];
- _mchan[ch].cmdlock = 0;
- _mchan[ch].command = releaseCmd[inst];
- _mchan[ch].framedelay = 1;
- goto top;
- }
- b -= 16;
- }
- _slot[2].framesleft = b;
- }
-
- for (int x = NUMCHANS - 1; x >= 0; x--) {
- if (_slot[0].framesleft || _slot[1].framesleft) {
- _mchan[x].volume = 0;
- _mchan[x].framedelay = 0;
- continue;
- }
-
- if (_mchan[x].framedelay && !--_mchan[x].framedelay) {
- switch (_mchan[x].command) {
- case 0x00:
- case 0x13:
- _mchan[x].voldelta = -10;
- break;
-
- case 0x01:
- case 0x03:
- case 0x08:
- case 0x16:
- _mchan[x].envflags = 0x30;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = 0;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeChannel(x, 1, 0x7F);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x02:
- _mchan[x].envflags = 0xB0;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = 0;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeChannel(x, 1, 0x84);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x04:
- _mchan[x].envflags = 0x80;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = 0;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeChannel(x, 1, 0x7F);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x05:
- _mchan[x].envflags = 0xF0;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = -15;
-
- APU_writeChannel(x, 1, 0x7F);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x06:
- _mchan[x].pitch += 0x18;
- _mchan[x].envflags = 0x80;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = 0;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeChannel(x, 1, 0x7F);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x07:
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch - 0x0C] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch - 0x0C] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x09:
- _mchan[x].voldelta = -2;
-
- APU_writeChannel(x, 1, 0x7F);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x0A:
- APU_writeChannel(x, 1, 0x86);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x0B: case 0x1A:
- _mchan[x].envflags = 0x70;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = 0;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeChannel(x, 1, 0x7F);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x0C:
- _mchan[x].envflags = 0xB0;
-
- chainCommand(x);
- break;
-
- case 0x0D:
- _mchan[x].envflags = 0x30;
- _mchan[x].volume = 0x5F;
- _mchan[x].voldelta = -22;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, _mchan[x].pitch & 0xF);
- APU_writeChannel(x, 3, 0xFF);
-
- chainCommand(x);
- break;
-
- case 0x0E:
- case 0x10:
- _mchan[x].envflags = 0x30;
- _mchan[x].volume = 0x5F;
- _mchan[x].voldelta = -6;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, _mchan[x].pitch & 0xF);
- APU_writeChannel(x, 3, 0xFF);
-
- chainCommand(x);
- break;
-
- case 0x0F:
- chainCommand(x);
- break;
-
- case 0x11:
- APU_writeChannel(x, 2, _mchan[x].pitch & 0xF);
- APU_writeChannel(x, 3, 0xFF);
-
- chainCommand(x);
- break;
-
- case 0x12:
- APU_writeChannel(x, 2, (_mchan[x].pitch + 3) & 0xF);
- APU_writeChannel(x, 3, 0xFF);
-
- chainCommand(x);
- break;
-
- case 0x14:
- _mchan[x].voldelta = -12;
-
- APU_writeChannel(x, 1, 0x8C);
-
- chainCommand(x);
- break;
-
- case 0x15:
- _mchan[x].voldelta = -12;
-
- APU_writeChannel(x, 1, 0x84);
-
- chainCommand(x);
- break;
-
- case 0x17:
- _mchan[x].pitch += 0x0C;
- _mchan[x].envflags = 0x80;
- _mchan[x].volume = 0x6F;
- _mchan[x].voldelta = 0;
-
- APU_writeChannel(x, 0, 0x00);
- APU_writeChannel(x, 1, 0x7F);
- APU_writeControl(APU_readStatus() | channelMask[x]);
- APU_writeChannel(x, 2, freqTable[_mchan[x].pitch] & 0xFF);
- APU_writeChannel(x, 3, freqTable[_mchan[x].pitch] >> 8);
-
- chainCommand(x);
- break;
-
- case 0x18:
- _mchan[x].envflags = 0x70;
-
- chainCommand(x);
- break;
-
- case 0x19:
- _mchan[x].envflags = 0xB0;
-
- chainCommand(x);
- break;
-
- case 0x1B:
- _mchan[x].envflags = 0x00;
- _mchan[x].voldelta = -10;
- break;
- }
- }
-
- _mchan[x].volume += _mchan[x].voldelta;
-
- if (_mchan[x].volume < 0)
- _mchan[x].volume = 0;
- if (_mchan[x].volume > MAXVOLUME)
- _mchan[x].volume = MAXVOLUME;
-
- APU_writeChannel(x, 0, (_mchan[x].volume >> 3) | _mchan[x].envflags);
- }
-}
-
-void Player_NES::chainCommand(int c) {
- int i = _mchan[c].command;
- _mchan[c].command = nextCmd[i];
- _mchan[c].framedelay = nextDelay[i];
-}
-
-int Player_NES::getSoundStatus(int nr) const {
- for (int i = 0; i < NUMSLOTS; i++)
- if (_slot[i].id == nr)
- return 1;
- return 0;
-}
-
-void Player_NES::APU_writeChannel(int chan, int offset, byte value) {
- APUe::APU_WriteReg(0x000 + 4 * chan + offset, value);
-}
-void Player_NES::APU_writeControl(byte value) {
- APUe::APU_WriteReg(0x015, value);
-}
-byte Player_NES::APU_readStatus() {
- return APUe::APU_Read4015();
-}
-
-} // End of namespace Scumm
diff --git a/scumm/player_nes.h b/scumm/player_nes.h
deleted file mode 100644
index 17a11b2fe3..0000000000
--- a/scumm/player_nes.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PLAYER_NES_H
-#define PLAYER_NES_H
-
-#include "common/scummsys.h"
-#include "scumm/music.h"
-#include "sound/audiostream.h"
-
-namespace Audio {
- class Mixer;
-}
-
-namespace Scumm {
-
-class ScummEngine;
-
-static const int MAXVOLUME = 0x7F;
-static const int NUMSLOTS = 3;
-static const int NUMCHANS = 4;
-
-/**
- * Scumm NES sound/music driver.
- */
-class Player_NES : public AudioStream, public MusicEngine {
-public:
- Player_NES(ScummEngine *scumm);
- virtual ~Player_NES();
-
- virtual void setMusicVolume(int vol);
- virtual void startSound(int sound);
- virtual void stopSound(int sound);
- virtual void stopAllSounds();
- virtual int getSoundStatus(int sound) const;
-
- // AudioStream API
- int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return false; }
- bool endOfData() const { return false; }
- int getRate() const { return _sample_rate; }
-
-private:
-
- void sound_play();
- void playSFX(int nr);
- void playMusic();
- byte fetchSoundByte(int nr);
- void chainCommand(int chan);
- void checkSilenceChannels(int chan);
-
- void APU_writeChannel(int chan, int offset, byte value);
- void APU_writeControl(byte value);
- byte APU_readStatus();
-
- void do_mix(int16 *buf, uint len);
-
- ScummEngine *_vm;
- Audio::Mixer *_mixer;
- int _sample_rate;
- int _samples_per_frame;
- int _current_sample;
- int _maxvol;
-
- struct slot {
- int framesleft;
- int id;
- int type;
- byte *data;
- int offset;
- } _slot[NUMSLOTS];
-
- struct mchan {
- int command;
- int framedelay;
- int pitch;
- int volume;
- int voldelta;
- int envflags;
- int cmdlock;
- } _mchan[NUMCHANS];
-
- bool isSFXplaying, wasSFXplaying;
-
- byte *dataStart;
- int numNotes;
- byte *auxData1;
- byte *auxData2;
-
- byte *soundptr;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/player_v1.cpp b/scumm/player_v1.cpp
deleted file mode 100644
index 74605b20d1..0000000000
--- a/scumm/player_v1.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "base/engine.h"
-#include "scumm/player_v1.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-#define FB_WNOISE 0x12000 /* feedback for white noise */
-#define FB_PNOISE 0x08000 /* feedback for periodic noise */
-
-#define TIMER_BASE_FREQ 1193000
-#define FIXP_SHIFT 16
-
-Player_V1::Player_V1(ScummEngine *scumm, bool pcjr) : Player_V2(scumm, pcjr) {
- // Initialize channel code
- for (int i = 0; i < 4; ++i)
- clear_channel(i);
-
- _mplex_step = (_sample_rate << FIXP_SHIFT) / 1193000;
- _next_chunk = _repeat_chunk = 0;
- _forced_level = 0;
- _random_lsr = 0;
-}
-
-Player_V1::~Player_V1() {
-}
-
-void Player_V1::chainSound(int nr, byte *data) {
- uint i;
- for (i = 0; i < 4; ++i)
- clear_channel(i);
-
- _current_nr = nr;
- _current_data = data;
- _repeat_chunk = _next_chunk = data + (_pcjr ? 2 : 4);
-
- debug(4, "Chaining new sound %d", nr);
- if (_pcjr)
- parsePCjrChunk();
- else
- parseSpeakerChunk();
-}
-
-void Player_V1::startSound(int nr) {
- byte *data = _vm->getResourceAddress(rtSound, nr);
- assert(data);
-
- mutex_up();
-
- int offset = _pcjr ? READ_LE_UINT16(data+4) : 6;
- int cprio = _current_data ? *(_current_data) & 0x7f : 0;
- int prio = *(data + offset) & 0x7f;
- int restartable = *(data + offset) & 0x80;
-
- debug(4, "startSound %d: prio %d%s, cprio %d",
- nr, prio, restartable ? " restartable" : "", cprio);
-
- if (!_current_nr || cprio <= prio) {
- if (_current_data && (*(_current_data) & 0x80)) {
- _next_nr = _current_nr;
- _next_data = _current_data;
- }
-
- chainSound(nr, data + offset);
- }
- mutex_down();
-}
-
-void Player_V1::stopAllSounds() {
- mutex_up();
- for (int i = 0; i < 4; i++)
- clear_channel(i);
- _repeat_chunk = _next_chunk = 0;
- _next_nr = _current_nr = 0;
- _next_data = _current_data = 0;
- mutex_down();
-}
-
-void Player_V1::stopSound(int nr) {
- mutex_up();
- if (_next_nr == nr) {
- _next_nr = 0;
- _next_data = 0;
- }
- if (_current_nr == nr) {
- for (int i = 0; i < 4; i++) {
- clear_channel(i);
- }
- _repeat_chunk = _next_chunk = 0;
- _current_nr = 0;
- _current_data = 0;
- chainNextSound();
- }
- mutex_down();
-}
-
-void Player_V1::clear_channel(int i) {
- _channels[i].freq = 0;
- _channels[i].volume = 15;
-}
-
-int Player_V1::getMusicTimer() const {
- /* Do V1 games have a music timer? */
- return 0;
-}
-
-void Player_V1::parseSpeakerChunk() {
- set_mplex(3000);
- _forced_level = 0;
-
- parse_again:
- _chunk_type = READ_LE_UINT16(_next_chunk);
- debug(6, "parseSpeakerChunk: sound %d, offset %4x, chunk %x",
- _current_nr, _next_chunk - _current_data, _chunk_type);
-
- _next_chunk += 2;
- switch (_chunk_type) {
- case 0xffff:
- _current_nr = 0;
- _current_data = 0;
- _channels[0].freq = 0;
- _next_chunk = 0;
- chainNextSound();
- break;
- case 0xfffe:
- _repeat_chunk = _next_chunk;
- goto parse_again;
-
- case 0xfffd:
- _next_chunk = _repeat_chunk;
- goto parse_again;
-
- case 0xfffc:
- /* handle reset. We don't need this do we? */
- goto parse_again;
-
- case 0:
- _time_left = 1;
- set_mplex(READ_LE_UINT16(_next_chunk));
- _next_chunk += 2;
- break;
- case 1:
- set_mplex(READ_LE_UINT16(_next_chunk));
- _start = READ_LE_UINT16(_next_chunk + 2);
- _end = READ_LE_UINT16(_next_chunk + 4);
- _delta = (int16) READ_LE_UINT16(_next_chunk + 6);
- _repeat_ctr = READ_LE_UINT16(_next_chunk + 8);
- _channels[0].freq = _start;
- _next_chunk += 10;
- debug(6, "chunk 1: mplex %d, freq %d -> %d step %d x %d",
- _mplex, _start, _end, _delta, _repeat_ctr);
- break;
- case 2:
- _start = READ_LE_UINT16(_next_chunk);
- _end = READ_LE_UINT16(_next_chunk + 2);
- _delta = (int16) READ_LE_UINT16(_next_chunk + 4);
- _channels[0].freq = 0;
- _next_chunk += 6;
- _forced_level = -1;
- debug(6, "chunk 2: %d -> %d step %d",
- _start, _end, _delta);
- break;
- case 3:
- _start = READ_LE_UINT16(_next_chunk);
- _end = READ_LE_UINT16(_next_chunk + 2);
- _delta = (int16) READ_LE_UINT16(_next_chunk + 4);
- _channels[0].freq = 0;
- _next_chunk += 6;
- _forced_level = -1;
- debug(6, "chunk 3: %d -> %d step %d",
- _start, _end, _delta);
- break;
- }
-}
-
-void Player_V1::nextSpeakerCmd() {
- uint16 lsr;
- switch (_chunk_type) {
- case 0:
- if (--_time_left)
- return;
- _time_left = READ_LE_UINT16(_next_chunk);
- _next_chunk += 2;
- if (_time_left == 0xfffb) {
- /* handle 0xfffb?? */
- _time_left = READ_LE_UINT16(_next_chunk);
- _next_chunk += 2;
- }
- debug(7, "nextSpeakerCmd: chunk %d, offset %4x: notelen %d",
- _chunk_type, _next_chunk - 2 - _current_data, _time_left);
- if (_time_left == 0) {
- parseSpeakerChunk();
- } else {
- _channels[0].freq = READ_LE_UINT16(_next_chunk);
- _next_chunk += 2;
- debug(7, "freq_current: %d", _channels[0].freq);
- }
- break;
-
- case 1:
- _channels[0].freq = (_channels[0].freq + _delta) & 0xffff;
- if (_channels[0].freq == _end) {
- if (!--_repeat_ctr) {
- parseSpeakerChunk();
- return;
- }
- _channels[0].freq = _start;
- }
- break;
-
- case 2:
- _start = (_start + _delta) & 0xffff;
- if (_start == _end) {
- parseSpeakerChunk();
- return;
- }
- set_mplex(_start);
- _forced_level = -_forced_level;
- break;
- case 3:
- _start = (_start + _delta) & 0xffff;
- if (_start == _end) {
- parseSpeakerChunk();
- return;
- }
- lsr = _random_lsr + 0x9248;
- lsr = (lsr >> 3) | (lsr << 13);
- _random_lsr = lsr;
- set_mplex((_start & lsr) | 0x180);
- _forced_level = -_forced_level;
- break;
- }
-}
-
-void Player_V1::parsePCjrChunk() {
- uint tmp;
- uint i;
-
- set_mplex(3000);
- _forced_level = 0;
-
-parse_again:
-
- _chunk_type = READ_LE_UINT16(_next_chunk);
- debug(6, "parsePCjrChunk: sound %d, offset %4x, chunk %x",
- _current_nr, _next_chunk - _current_data, _chunk_type);
-
- _next_chunk += 2;
- switch (_chunk_type) {
- case 0xffff:
- for (i = 0; i < 4; ++i)
- clear_channel(i);
- _current_nr = 0;
- _current_data = 0;
- _repeat_chunk = _next_chunk = 0;
- chainNextSound();
- break;
-
- case 0xfffe:
- _repeat_chunk = _next_chunk;
- goto parse_again;
-
- case 0xfffd:
- _next_chunk = _repeat_chunk;
- goto parse_again;
-
- case 0xfffc:
- /* handle reset. We don't need this do we? */
- goto parse_again;
-
- case 0:
- set_mplex(READ_LE_UINT16(_next_chunk));
- _next_chunk += 2;
- for (i = 0; i < 4; i++) {
- tmp = READ_LE_UINT16(_next_chunk);
- _next_chunk += 2;
- if (tmp == 0xffff) {
- _channels[i].cmd_ptr = 0;
- continue;
- }
- _channels[i].attack = READ_LE_UINT16(_current_data + tmp);
- _channels[i].decay = READ_LE_UINT16(_current_data + tmp + 2);
- _channels[i].level = READ_LE_UINT16(_current_data + tmp + 4);
- _channels[i].sustain_1 = READ_LE_UINT16(_current_data + tmp + 6);
- _channels[i].sustain_2 = READ_LE_UINT16(_current_data + tmp + 8);
- _channels[i].notelen = 1;
- _channels[i].volume = 15;
- _channels[i].cmd_ptr = _current_data + tmp + 10;
- }
- break;
-
- case 1:
- set_mplex(READ_LE_UINT16(_next_chunk));
- tmp = READ_LE_UINT16(_next_chunk + 2);
- _channels[0].cmd_ptr = tmp != 0xffff ? _current_data + tmp : NULL;
- tmp = READ_LE_UINT16(_next_chunk + 4);
- _start = READ_LE_UINT16(_next_chunk + 6);
- _delta = (int16) READ_LE_UINT16(_next_chunk + 8);
- _time_left = READ_LE_UINT16(_next_chunk + 10);
- _next_chunk += 12;
- if (tmp >= 0xe0) {
- _channels[3].freq = tmp & 0xf;
- _value_ptr = &_channels[3].volume;
- } else {
- assert(!(tmp & 0x10));
- tmp = (tmp & 0x60) >> 5;
- _value_ptr = &_channels[tmp].freq;
- _channels[tmp].volume = 0;
- }
- *_value_ptr = _start;
- if (_channels[0].cmd_ptr) {
- tmp = READ_LE_UINT16(_channels[0].cmd_ptr);
- _start_2 = READ_LE_UINT16(_channels[0].cmd_ptr + 2);
- _delta_2 = (int16) READ_LE_UINT16(_channels[0].cmd_ptr + 4);
- _time_left_2 = READ_LE_UINT16(_channels[0].cmd_ptr + 6);
- _channels[0].cmd_ptr += 8;
- if (_value_ptr == &_channels[3].volume) {
- tmp = (tmp & 0x70) >> 4;
- if (tmp & 1)
- _value_ptr_2 = &_channels[tmp >> 1].volume;
- else
- _value_ptr_2 = &_channels[tmp >> 1].freq;
- } else {
- assert(!(tmp & 0x10));
- tmp = (tmp & 0x60) >> 5;
- _value_ptr_2 = &_channels[tmp].freq;
- _channels[tmp].volume = 0;
- }
- *_value_ptr_2 = _start_2;
- }
- debug(6, "chunk 1: %d: %d step %d for %d, %d: %d step %d for %d",
- _value_ptr - (uint*)_channels, _start, _delta, _time_left,
- _value_ptr_2 - (uint*)_channels, _start_2, _delta_2, _time_left_2);
- break;
-
- case 2:
- _start = READ_LE_UINT16(_next_chunk);
- _end = READ_LE_UINT16(_next_chunk + 2);
- _delta = (int16) READ_LE_UINT16(_next_chunk + 4);
- _channels[0].freq = 0;
- _next_chunk += 6;
- _forced_level = -1;
- debug(6, "chunk 2: %d -> %d step %d",
- _start, _end, _delta);
- break;
- case 3:
- set_mplex(READ_LE_UINT16(_next_chunk));
- tmp = READ_LE_UINT16(_next_chunk + 2);
- assert((tmp & 0xf0) == 0xe0);
- _channels[3].freq = tmp & 0xf;
- if ((tmp & 3) == 3) {
- _next_chunk += 2;
- _channels[2].freq = READ_LE_UINT16(_next_chunk + 2);
- }
- _channels[3].volume = READ_LE_UINT16(_next_chunk + 4);
- _repeat_ctr = READ_LE_UINT16(_next_chunk + 6);
- _delta = (int16) READ_LE_UINT16(_next_chunk + 8);
- _next_chunk += 10;
- break;
- }
-}
-
-void Player_V1::nextPCjrCmd() {
- uint i;
- int dummy;
- switch (_chunk_type) {
- case 0:
- for (i = 0; i < 4; i++) {
- if (!_channels[i].cmd_ptr)
- continue;
- if (!--_channels[i].notelen) {
- dummy = READ_LE_UINT16(_channels[i].cmd_ptr);
- if (dummy >= 0xfffe) {
- if (dummy == 0xfffe)
- _next_chunk = _current_data + 2;
- parsePCjrChunk();
- return;
- }
- _channels[i].notelen = 4 * dummy;
- dummy = READ_LE_UINT16(_channels[i].cmd_ptr + 2);
- if (dummy == 0) {
- _channels[i].hull_counter = 4;
- _channels[i].sustctr = _channels[i].sustain_2;
- } else {
- _channels[i].hull_counter = 1;
- _channels[i].freq = dummy;
- }
- debug(7, "chunk 0: channel %d play %d for %d",
- i, dummy, _channels[i].notelen);
- _channels[i].cmd_ptr += 4;
- }
-
-
- switch (_channels[i].hull_counter) {
- case 1:
- _channels[i].volume -= _channels[i].attack;
- if ((int) _channels[i].volume <= 0) {
- _channels[i].volume = 0;
- _channels[i].hull_counter++;
- }
- break;
- case 2:
- _channels[i].volume += _channels[i].decay;
- if (_channels[i].volume >= _channels[i].level) {
- _channels[i].volume = _channels[i].level;
- _channels[i].hull_counter++;
- }
- break;
- case 4:
- if (--_channels[i].sustctr < 0) {
- _channels[i].sustctr = _channels[i].sustain_2;
- _channels[i].volume += _channels[i].sustain_1;
- if ((int) _channels[i].volume >= 15) {
- _channels[i].volume = 15;
- _channels[i].hull_counter++;
- }
- }
- break;
- }
- }
- break;
-
- case 1:
- _start += _delta;
- *_value_ptr = _start;
- if (!--_time_left) {
- _start = READ_LE_UINT16(_next_chunk);
- _next_chunk += 2;
- if (_start == 0xffff) {
- parsePCjrChunk();
- return;
- }
- _delta = (int16) READ_LE_UINT16(_next_chunk);
- _time_left = READ_LE_UINT16(_next_chunk + 2);
- _next_chunk += 4;
- *_value_ptr = _start;
- }
-
- if (_channels[0].cmd_ptr) {
- _start_2 += _delta_2;
- *_value_ptr_2 = _start_2;
- if (!--_time_left_2) {
- _start_2 = READ_LE_UINT16(_channels[0].cmd_ptr);
- if (_start_2 == 0xffff) {
- _next_chunk = _channels[0].cmd_ptr + 2;
- parsePCjrChunk();
- return;
- }
- _delta_2 = (int16) READ_LE_UINT16(_channels[0].cmd_ptr + 2);
- _time_left_2 = READ_LE_UINT16(_channels[0].cmd_ptr + 4);
- _channels[0].cmd_ptr += 6;
- }
- }
- break;
-
- case 2:
- _start += _delta;
- if (_start == _end) {
- parsePCjrChunk();
- return;
- }
- set_mplex(_start);
- debug(7, "chunk 2: mplex %d curve %d", _start, _forced_level);
- _forced_level = -_forced_level;
- break;
- case 3:
- dummy = _channels[3].volume + _delta;
- if (dummy >= 15) {
- _channels[3].volume = 15;
- } else if (dummy <= 0) {
- _channels[3].volume = 0;
- } else {
- _channels[3].volume = dummy;
- break;
- }
-
- if (!--_repeat_ctr) {
- parsePCjrChunk();
- return;
- }
- _delta = READ_LE_UINT16(_next_chunk);
- _next_chunk += 2;
- break;
- }
-}
-
-void Player_V1::set_mplex(uint mplex) {
- if (mplex == 0)
- mplex = 65536;
- _mplex = mplex;
- _tick_len = _mplex_step * mplex;
-}
-
-void Player_V1::nextTick() {
- if (_next_chunk) {
- if (_pcjr)
- nextPCjrCmd();
- else
- nextSpeakerCmd();
- }
-}
-
-void Player_V1::generateSpkSamples(int16 *data, uint len) {
- uint i;
-
- memset(data, 0, 2 * sizeof(int16) * len);
- if (_channels[0].freq == 0) {
- if (_forced_level) {
- int sample = _forced_level * _volumetable[0];
- for (i = 0; i < len; i++)
- data[2*i] = data[2*i+1] = sample;
- debug(9, "speaker: %8x: forced one", _tick_len);
- } else if (!_level) {
- return;
- }
- } else {
- squareGenerator(0, _channels[0].freq, 0, 0, data, len);
- debug(9, "speaker: %8x: freq %d %.1f", _tick_len,
- _channels[0].freq, 1193000.0 / _channels[0].freq);
- }
- lowPassFilter(data, len);
-}
-
-void Player_V1::generatePCjrSamples(int16 *data, uint len) {
- uint i, j;
- uint freq, vol;
- bool hasdata = false;
-
- memset(data, 0, 2 * sizeof(int16) * len);
-
- if (_forced_level) {
- int sample = _forced_level * _volumetable[0];
- for (i = 0; i < len; i++)
- data[2*i] = data[2*i+1] = sample;
- hasdata = true;
- debug(9, "channel[4]: %8x: forced one", _tick_len);
- }
-
- for (i = 1; i < 3; i++) {
- freq = _channels[i].freq;
- if (freq) {
- for (j = 0; j < i; j++) {
- if (freq == _channels[j].freq) {
- /* HACK: this channel is playing at
- * the same frequency as another.
- * Synchronize it to the same phase to
- * prevent interference.
- */
- _timer_count[i] = _timer_count[j];
- _timer_output ^= (1 << i) &
- (_timer_output ^ _timer_output << (i - j));
- }
- }
- }
- }
-
- for (i = 0; i < 4; i++) {
- freq = _channels[i].freq;
- vol = _channels[i].volume;
- if (!_volumetable[_channels[i].volume]) {
- _timer_count[i] -= len << FIXP_SHIFT;
- if (_timer_count[i] < 0)
- _timer_count[i] = 0;
- } else if (i < 3) {
- hasdata = true;
- squareGenerator(i, freq, vol, 0, data, len);
- debug(9, "channel[%d]: %8x: freq %d %.1f ; volume %d",
- i, _tick_len, freq, 111860.0 / freq, vol);
- } else {
- int noiseFB = (freq & 4) ? FB_WNOISE : FB_PNOISE;
- int n = (freq & 3);
-
- freq = (n == 3) ? 2 * (_channels[2].freq) : 1 << (5 + n);
- hasdata = true;
- squareGenerator(i, freq, vol, noiseFB, data, len);
- debug(9, "channel[%d]: %x: noise freq %d %.1f ; volume %d",
- i, _tick_len, freq, 111860.0 / freq, vol);
- }
- }
-
- if (_level || hasdata)
- lowPassFilter(data, len);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/player_v1.h b/scumm/player_v1.h
deleted file mode 100644
index 60ba8ad26d..0000000000
--- a/scumm/player_v1.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PLAYER_V1_H
-#define PLAYER_V1_H
-
-#include "scumm/player_v2.h"
-
-namespace Scumm {
-
-/**
- * Scumm V1 PC-Speaker player.
- */
-class Player_V1 : public Player_V2 {
-public:
- Player_V1(ScummEngine *scumm, bool pcjr);
- ~Player_V1();
-
- virtual void startSound(int sound);
- virtual void stopSound(int sound);
- virtual void stopAllSounds();
- virtual int getMusicTimer() const;
-
-protected:
- virtual void nextTick();
- virtual void clear_channel(int i);
- virtual void chainSound(int nr, byte *data);
-
- virtual void generateSpkSamples(int16 *data, uint len);
- virtual void generatePCjrSamples(int16 *data, uint len);
-
- void restartSound();
-
- void set_mplex(uint mplex);
- void parseSpeakerChunk();
- void nextSpeakerCmd();
- void parsePCjrChunk();
- void nextPCjrCmd();
-
-private:
- struct channel_data_v1 {
- uint freq;
- uint volume;
- byte *cmd_ptr;
- uint notelen;
- uint hull_counter;
- uint attack;
- uint decay;
- uint level;
- uint sustain_1;
- uint sustain_2;
- int sustctr;
- };
-
- channel_data_v1 _channels[4];
-
- byte *_next_chunk;
- byte *_repeat_chunk;
- uint _chunk_type;
- uint _mplex_step;
- uint _mplex;
- uint _repeat_ctr;
- uint _freq_current;
- int _forced_level;
- uint16 _random_lsr;
- uint *_value_ptr;
- uint _time_left;
- uint _start;
- uint _end;
- int _delta;
- uint *_value_ptr_2;
- uint _time_left_2;
- uint _start_2;
- int _delta_2;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/player_v2.cpp b/scumm/player_v2.cpp
deleted file mode 100644
index 70aff98bb9..0000000000
--- a/scumm/player_v2.cpp
+++ /dev/null
@@ -1,1005 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "base/engine.h"
-#include "scumm/player_v2.h"
-#include "scumm/scumm.h"
-#include "sound/mididrv.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-#define FREQ_HZ 236 // Don't change!
-
-#define SPK_DECAY 0xa000 /* Depends on sample rate */
-#define PCJR_DECAY 0xa000 /* Depends on sample rate */
-
-#define FIXP_SHIFT 16
-#define MAX_OUTPUT 0x7fff
-
-#define NG_PRESET 0x0f35 /* noise generator preset */
-#define FB_WNOISE 0x12000 /* feedback for white noise */
-#define FB_PNOISE 0x08000 /* feedback for periodic noise */
-
-#ifdef PALMOS_68K
-const uint8 *note_lengths;
-static const uint16 *hull_offsets;
-static const int16 *hulls;
-static const uint16 *freqmod_lengths;
-static const uint16 *freqmod_offsets;
-static const int8 *freqmod_table;
-static const uint16 *spk_freq_table;
-static const uint16 *pcjr_freq_table;
-#else
-const uint8 note_lengths[] = {
- 0,
- 0, 0, 2,
- 0, 3, 4,
- 5, 6, 8,
- 9, 12, 16,
- 18, 24, 32,
- 36, 48, 64,
- 72, 96
-};
-
-static const uint16 hull_offsets[] = {
- 0, 12, 24, 36, 48, 60,
- 72, 88, 104, 120, 136, 256,
- 152, 164, 180
-};
-
-static const int16 hulls[] = {
- // hull 0
- 3, -1, 0, 0, 0, 0, 0, 0,
- 0, -1, 0, 0,
- // hull 1 (staccato)
- 3, -1, 0, 32, 0, -1, 0, 0,
- 0, -1, 0, 0,
- // hull 2 (legato)
- 3, -1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
- // hull 3 (staccatissimo)
- 3, -1, 0, 2, 0, -1, 0, 0,
- 0, -1, 0, 0,
- // hull 4
- 3, -1, 0, 6, 0, -1, 0, 0,
- 0, -1, 0, 0,
- // hull 5
- 3, -1, 0, 16, 0, -1, 0, 0,
- 0, -1, 0, 0,
- // hull 6
- (int16) 60000, -1, -1000, 20, 0, 0, 0, 0,
- (int16) 40000, -1, -5000, 5, 0, -1, 0, 0,
- // hull 7
- (int16) 50000, -1, 0, 8, 30000, -1, 0, 0,
- 28000, -1, -5000, 5, 0, -1, 0, 0,
- // hull 8
- (int16) 60000, -1, -2000, 16, 0, 0, 0, 0,
- 28000, -1, -6000, 5, 0, -1, 0, 0,
- // hull 9
- (int16) 55000, -1, 0, 8, (int16) 35000, -1, 0, 0,
- (int16) 40000, -1, -2000, 10, 0, -1, 0, 0,
- // hull 10
- (int16) 60000, -1, 0, 4, -2000, 8, 0, 0,
- (int16) 40000, -1, -6000, 5, 0, -1, 0, 0,
- // hull 12
- 0, -1, 150, 340, -150, 340, 0, -1,
- 0, -1, 0, 0,
- // hull 13 == 164
- 20000, -1, 4000, 7, 1000, 15, 0, 0,
- (int16) 35000, -1, -2000, 15, 0, -1, 0, 0,
-
- // hull 14 == 180
- (int16) 35000, -1, 500, 20, 0, 0, 0, 0,
- (int16) 45000, -1, -500, 60, 0, -1, 0, 0,
-
- // hull misc = 196
- (int16) 44000, -1, -4400, 10, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 53000, -1, -5300, 10, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 63000, -1, -6300, 10, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 44000, -1, -1375, 32, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 53000, -1, -1656, 32, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- // hull 11 == 256
- (int16) 63000, -1, -1968, 32, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 44000, -1, - 733, 60, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 53000, -1, - 883, 60, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 63000, -1, -1050, 60, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 44000, -1, - 488, 90, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 53000, -1, - 588, 90, 0, -1, 0, 0,
- 0, -1, 0, 0,
-
- (int16) 63000, -1, - 700, 90, 0, -1, 0, 0,
- 0, -1, 0, 0
-};
-
-static const uint16 freqmod_lengths[] = {
- 0x1000, 0x1000, 0x20, 0x2000, 0x1000
-};
-
-static const uint16 freqmod_offsets[] = {
- 0, 0x100, 0x200, 0x302, 0x202
-};
-
-static const int8 freqmod_table[0x502] = {
- 0, 3, 6, 9, 12, 15, 18, 21,
- 24, 27, 30, 33, 36, 39, 42, 45,
- 48, 51, 54, 57, 59, 62, 65, 67,
- 70, 73, 75, 78, 80, 82, 85, 87,
- 89, 91, 94, 96, 98, 100, 102, 103,
- 105, 107, 108, 110, 112, 113, 114, 116,
- 117, 118, 119, 120, 121, 122, 123, 123,
- 124, 125, 125, 126, 126, 126, 126, 126,
- 126, 126, 126, 126, 126, 126, 125, 125,
- 124, 123, 123, 122, 121, 120, 119, 118,
- 117, 116, 114, 113, 112, 110, 108, 107,
- 105, 103, 102, 100, 98, 96, 94, 91,
- 89, 87, 85, 82, 80, 78, 75, 73,
- 70, 67, 65, 62, 59, 57, 54, 51,
- 48, 45, 42, 39, 36, 33, 30, 27,
- 24, 21, 18, 15, 12, 9, 6, 3,
- 0, -3, -6, -9, -12, -15, -18, -21,
- -24, -27, -30, -33, -36, -39, -42, -45,
- -48, -51, -54, -57, -59, -62, -65, -67,
- -70, -73, -75, -78, -80, -82, -85, -87,
- -89, -91, -94, -96, -98,-100,-102,-103,
- -105,-107,-108,-110,-112,-113,-114,-116,
- -117,-118,-119,-120,-121,-122,-123,-123,
- -124,-125,-125,-126,-126,-126,-126,-126,
- -126,-126,-126,-126,-126,-126,-125,-125,
- -124,-123,-123,-122,-121,-120,-119,-118,
- -117,-116,-114,-113,-112,-110,-108,-107,
- -105,-103,-102,-100, -98, -96, -94, -91,
- -89, -87, -85, -82, -80, -78, -75, -73,
- -70, -67, -65, -62, -59, -57, -54, -51,
- -48, -45, -42, -39, -36, -33, -30, -27,
- -24, -21, -18, -15, -12, -9, -6, -3,
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127,
- -128,-127,-126,-125,-124,-123,-122,-121,
- -120,-119,-118,-117,-116,-115,-114,-113,
- -112,-111,-110,-109,-108,-107,-106,-105,
- -104,-103,-102,-101,-100, -99, -98, -97,
- -96, -95, -94, -93, -92, -91, -90, -89,
- -88, -87, -86, -85, -84, -83, -82, -81,
- -80, -79, -78, -77, -76, -75, -74, -73,
- -72, -71, -70, -69, -68, -67, -66, -65,
- -64, -63, -62, -61, -60, -59, -58, -57,
- -56, -55, -54, -53, -52, -51, -50, -49,
- -48, -47, -46, -45, -44, -43, -42, -41,
- -40, -39, -38, -37, -36, -35, -34, -33,
- -32, -31, -30, -29, -28, -27, -26, -25,
- -24, -23, -22, -21, -20, -19, -18, -17,
- -16, -15, -14, -13, -12, -11, -10, -9,
- -8, -7, -6, -5, -4, -3, -2, -1,
-
- -120, 120,
-
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- -120,-120,-120,-120,-120,-120,-120,-120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
-
- 41, 35, -66,-124, -31, 108, -42, -82,
- 82,-112, 73, -15, -15, -69, -23, -21,
- -77, -90, -37, 60,-121, 12, 62,-103,
- 36, 94, 13, 28, 6, -73, 71, -34,
- -77, 18, 77, -56, 67, -69,-117, -90,
- 31, 3, 90, 125, 9, 56, 37, 31,
- 93, -44, -53, -4,-106, -11, 69, 59,
- 19, 13,-119, 10, 28, -37, -82, 50,
- 32,-102, 80, -18, 64, 120, 54, -3,
- 18, 73, 50, -10, -98, 125, 73, -36,
- -83, 79, 20, -14, 68, 64, 102, -48,
- 107, -60, 48, -73, 50, 59, -95, 34,
- -10, 34,-111, -99, -31,-117, 31, -38,
- -80, -54,-103, 2, -71, 114, -99, 73,
- 44,-128, 126, -59,-103, -43, -23,-128,
- -78, -22, -55, -52, 83, -65, 103, -42,
- -65, 20, -42, 126, 45, -36,-114, 102,
- -125, -17, 87, 73, 97, -1, 105,-113,
- 97, -51, -47, 30, -99,-100, 22, 114,
- 114, -26, 29, -16,-124, 79, 74, 119,
- 2, -41, -24, 57, 44, 83, -53, -55,
- 18, 30, 51, 116, -98, 12, -12, -43,
- -44, -97, -44, -92, 89, 126, 53, -49,
- 50, 34, -12, -52, -49, -45,-112, 45,
- 72, -45,-113, 117, -26, -39, 29, 42,
- -27, -64, -9, 43, 120,-127,-121, 68,
- 14, 95, 80, 0, -44, 97,-115, -66,
- 123, 5, 21, 7, 59, 51,-126, 31,
- 24, 112,-110, -38, 100, 84, -50, -79,
- -123, 62, 105, 21, -8, 70, 106, 4,
- -106, 115, 14, -39, 22, 47, 103, 104,
- -44, -9, 74, 74, -48, 87, 104, 118,
- -6, 22, -69, 17, -83, -82, 36,-120,
- 121, -2, 82, -37, 37, 67, -27, 60,
- -12, 69, -45, -40, 40, -50, 11, -11,
- -59, 96, 89, 61,-105, 39,-118, 89,
- 118, 45, -48, -62, -55, -51, 104, -44,
- 73, 106, 121, 37, 8, 97, 64, 20,
- -79, 59, 106, -91, 17, 40, -63,-116,
- -42, -87, 11,-121,-105,-116, 47, -15,
- 21, 29,-102,-107, -63,-101, -31, -64,
- 126, -23, -88,-102, -89,-122, -62, -75,
- 84, -65,-102, -25, -39, 35, -47, 85,
- -112, 56, 40, -47, -39, 108, -95, 102,
- 94, 78, -31, 48,-100, -2, -39, 113,
- -97, -30, -91, -30, 12,-101, -76, 71,
- 101, 56, 42, 70,-119, -87,-126, 121,
- 122, 118, 120, -62, 99, -79, 38, -33,
- -38, 41, 109, 62, 98, -32,-106, 18,
- 52, -65, 57, -90, 63,-119, 94, -15,
- 109, 14, -29, 108, 40, -95, 30, 32,
- 29, -53, -62, 3, 63, 65, 7,-124,
- 15, 20, 5, 101, 27, 40, 97, -55,
- -59, -25, 44,-114, 70, 54, 8, -36,
- -13, -88,-115, -2, -66, -14, -21, 113,
- -1, -96, -48, 59, 117, 6,-116, 126,
- -121, 120, 115, 77, -48, -66,-126, -66,
- -37, -62, 70, 65, 43,-116, -6, 48,
- 127, 112, -16, -89, 84,-122, 50,-107,
- -86, 91, 104, 19, 11, -26, -4, -11,
- -54, -66, 125, -97,-119,-118, 65, 27,
- -3, -72, 79, 104, -10, 114, 123, 20,
- -103, -51, -45, 13, -16, 68, 58, -76,
- -90, 102, 83, 51, 11, -53, -95, 16
-};
-
-
-static const uint16 spk_freq_table[12] = {
- 36484, 34436, 32503, 30679, 28957, 27332,
- 25798, 24350, 22983, 21693, 20476, 19326
-};
-
-static const uint16 pcjr_freq_table[12] = {
- 65472, 61760, 58304, 55040, 52032, 49024,
- 46272, 43648, 41216, 38912, 36736, 34624
-};
-#endif
-
-
-Player_V2::Player_V2(ScummEngine *scumm, bool pcjr) {
- int i;
-
- _isV3Game = (scumm->_version >= 3);
- _vm = scumm;
- _mixer = scumm->_mixer;
- _sample_rate = _mixer->getOutputRate();
-
- _header_len = (scumm->_features & GF_OLD_BUNDLE) ? 4 : 6;
-
- // Initialize sound queue
- _current_nr = _next_nr = 0;
- _current_data = _next_data = 0;
-
- // Initialize channel code
- for (i = 0; i < 4; ++i)
- clear_channel(i);
-
- _next_tick = 0;
- _tick_len = (_sample_rate << FIXP_SHIFT) / FREQ_HZ;
-
- // Initialize V3 music timer
- _music_timer_ctr = _music_timer = 0;
- _ticks_per_music_timer = 65535;
-
- // Initialize square generator
- _level = 0;
-
- _RNG = NG_PRESET;
-
- set_pcjr(pcjr);
- setMusicVolume(255);
-
- _mixer->setupPremix(this);
-}
-
-Player_V2::~Player_V2() {
- mutex_up();
- // Detach the premix callback handler
- _mixer->setupPremix(0);
- mutex_down();
-}
-
-void Player_V2::set_pcjr(bool pcjr) {
- mutex_up();
- _pcjr = pcjr;
-
- if (_pcjr) {
- _decay = PCJR_DECAY;
- _update_step = (_sample_rate << FIXP_SHIFT) / (111860 * 2);
- _freqs_table = pcjr_freq_table;
- } else {
- _decay = SPK_DECAY;
- _update_step = (_sample_rate << FIXP_SHIFT) / (1193000 * 2);
- _freqs_table = spk_freq_table;
- }
-
- /* adapt _decay to sample rate. It must be squared when
- * sample rate doubles.
- */
- int i;
- for (i = 0; (_sample_rate << i) < 30000; i++)
- _decay = _decay * _decay / 65536;
-
-
- _timer_output = 0;
- for (i = 0; i < 4; i++)
- _timer_count[i] = 0;
-
- mutex_down();
-}
-
-void Player_V2::setMusicVolume (int vol) {
- if (vol > 255)
- vol = 255;
-
- /* scale to int16, FIXME: find best value */
- double out = vol * 128 / 3;
-
- /* build volume table (2dB per step) */
- for (int i = 0; i < 15; i++) {
- /* limit volume to avoid clipping */
- if (out > 0xffff)
- _volumetable[i] = 0xffff;
- else
- _volumetable[i] = (int) out;
-
- out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */
- }
- _volumetable[15] = 0;
-}
-
-void Player_V2::chainSound(int nr, byte *data) {
- int offset = _header_len + (_pcjr ? 10 : 2);
-
- _current_nr = nr;
- _current_data = data;
-
- for (int i = 0; i < 4; i++) {
- clear_channel(i);
-
- _channels[i].d.music_script_nr = nr;
- if (data) {
- _channels[i].d.next_cmd = READ_LE_UINT16(data + offset + 2 * i);
- if (_channels[i].d.next_cmd)
- _channels[i].d.time_left = 1;
- }
- }
- _music_timer = 0;
-}
-
-void Player_V2::chainNextSound() {
- if (_next_nr) {
- chainSound(_next_nr, _next_data);
- _next_nr = 0;
- _next_data = 0;
- }
-}
-
-void Player_V2::stopAllSounds() {
- mutex_up();
- for (int i = 0; i < 4; i++) {
- clear_channel(i);
- }
- _next_nr = _current_nr = 0;
- _next_data = _current_data = 0;
- mutex_down();
-}
-
-void Player_V2::stopSound(int nr) {
- mutex_up();
- if (_next_nr == nr) {
- _next_nr = 0;
- _next_data = 0;
- }
- if (_current_nr == nr) {
- for (int i = 0; i < 4; i++) {
- clear_channel(i);
- }
- _current_nr = 0;
- _current_data = 0;
- chainNextSound();
- }
- mutex_down();
-}
-
-void Player_V2::startSound(int nr) {
- byte *data = _vm->getResourceAddress(rtSound, nr);
- assert(data);
-
- mutex_up();
-
- int cprio = _current_data ? *(_current_data + _header_len) : 0;
- int prio = *(data + _header_len);
- int nprio = _next_data ? *(_next_data + _header_len) : 0;
-
- int restartable = *(data + _header_len + 1);
-
- if (!_current_nr || cprio <= prio) {
- int tnr = _current_nr;
- int tprio = cprio;
- byte *tdata = _current_data;
-
- chainSound(nr, data);
- nr = tnr;
- prio = tprio;
- data = tdata;
- restartable = data ? *(data + _header_len + 1) : 0;
- }
-
- if (!_current_nr) {
- nr = 0;
- _next_nr = 0;
- _next_data = 0;
- }
-
- if (nr != _current_nr
- && restartable
- && (!_next_nr
- || nprio <= prio)) {
-
- _next_nr = nr;
- _next_data = data;
- }
-
- mutex_down();
-}
-
-int Player_V2::getSoundStatus(int nr) const {
- return _current_nr == nr || _next_nr == nr;
-}
-
-
-void Player_V2::clear_channel(int i) {
- ChannelInfo *channel = &_channels[i];
- memset(channel, 0, sizeof(ChannelInfo));
-}
-
-int Player_V2::getMusicTimer() const {
- if (_isV3Game)
- return _music_timer;
- else
- return _channels[0].d.music_timer;
-}
-
-void Player_V2::execute_cmd(ChannelInfo *channel) {
- uint16 value;
- int16 offset;
- uint8 *script_ptr;
- ChannelInfo * current_channel;
- ChannelInfo * dest_channel;
-
- current_channel = channel;
-
- if (channel->d.next_cmd == 0)
- goto check_stopped;
- script_ptr = &_current_data[channel->d.next_cmd];
-
- for (;;) {
- uint8 opcode = *script_ptr++;
- if (opcode >= 0xf8) {
- switch (opcode) {
- case 0xf8: // set hull curve
- debug(7, "channels[%d]: hull curve %2d",
- channel - _channels, *script_ptr);
- channel->d.hull_curve = hull_offsets[*script_ptr / 2];
- script_ptr++;
- break;
-
- case 0xf9: // set freqmod curve
- debug(7, "channels[%d]: freqmod curve %2d",
- channel - _channels, *script_ptr);
- channel->d.freqmod_table = freqmod_offsets[*script_ptr / 4];
- channel->d.freqmod_modulo = freqmod_lengths[*script_ptr / 4];
- script_ptr++;
- break;
-
- case 0xfd: // clear other channel
- value = READ_LE_UINT16 (script_ptr) / sizeof (ChannelInfo);
- debug(7, "clear channel %d", value);
- script_ptr += 2;
- // In Indy3, when traveling to Venice a command is
- // issued to clear channel 4. So we introduce a 4th
- // channel, which is never used. All OOB accesses are
- // mapped to this channel.
- //
- // The original game had room for 8 channels, but only
- // channels 0-3 are read, changes to other channels
- // had no effect.
- if (value >= ARRAYSIZE (_channels))
- value = 4;
- channel = &_channels[value];
- // fall through
-
- case 0xfa: // clear current channel
- if (opcode == 0xfa)
- debug(7, "clear channel");
- channel->d.next_cmd = 0;
- channel->d.base_freq = 0;
- channel->d.freq_delta = 0;
- channel->d.freq = 0;
- channel->d.volume = 0;
- channel->d.volume_delta = 0;
- channel->d.inter_note_pause = 0;
- channel->d.transpose = 0;
- channel->d.hull_curve = 0;
- channel->d.hull_offset = 0;
- channel->d.hull_counter = 0;
- channel->d.freqmod_table = 0;
- channel->d.freqmod_offset = 0;
- channel->d.freqmod_incr = 0;
- channel->d.freqmod_multiplier = 0;
- channel->d.freqmod_modulo = 0;
- break;
-
- case 0xfb: // ret from subroutine
- debug(7, "ret from sub");
- script_ptr = _retaddr;
- break;
-
- case 0xfc: // call subroutine
- offset = READ_LE_UINT16 (script_ptr);
- debug(7, "subroutine %d", offset);
- script_ptr += 2;
- _retaddr = script_ptr;
- script_ptr = _current_data + offset;
- break;
-
- case 0xfe: // loop music
- opcode = *script_ptr++;
- offset = READ_LE_UINT16 (script_ptr);
- script_ptr += 2;
- debug(7, "loop if %d to %d", opcode, offset);
- if (!channel->array[opcode / 2] || --channel->array[opcode/2])
- script_ptr += offset;
- break;
-
- case 0xff: // set parameter
- opcode = *script_ptr++;
- value = READ_LE_UINT16 (script_ptr);
- channel->array[opcode / 2] = value;
- debug(7, "channels[%d]: set param %2d = %5d",
- channel - &_channels[0], opcode, value);
- script_ptr += 2;
- if (opcode == 14) {
- /* tempo var */
- _ticks_per_music_timer = 125;
- }
- if (opcode == 0)
- goto end;
- break;
- }
- } else { // opcode < 0xf8
- for (;;) {
- int16 note, octave;
- int is_last_note;
- dest_channel = &_channels[(opcode >> 5) & 3];
-
- if (!(opcode & 0x80)) {
-
- int tempo = channel->d.tempo;
- if (!tempo)
- tempo = 1;
- channel->d.time_left = tempo * note_lengths[opcode & 0x1f];
-
- note = *script_ptr++;
- is_last_note = note & 0x80;
- note &= 0x7f;
- if (note == 0x7f) {
- debug(8, "channels[%d]: pause %d",
- channel - _channels, channel->d.time_left);
- goto end;
- }
- } else {
-
- channel->d.time_left = ((opcode & 7) << 8) | *script_ptr++;
-
- if ((opcode & 0x10)) {
- debug(8, "channels[%d]: pause %d",
- channel - _channels, channel->d.time_left);
- goto end;
- }
-
- is_last_note = 0;
- note = (*script_ptr++) & 0x7f;
- }
-
- debug(8, "channels[%d]: @%04x note: %3d+%d len: %2d hull: %d mod: %d/%d/%d %s",
- dest_channel - channel, script_ptr ? script_ptr - _current_data - 2 : 0,
- note, (signed short) dest_channel->d.transpose, channel->d.time_left,
- dest_channel->d.hull_curve, dest_channel->d.freqmod_table,
- dest_channel->d.freqmod_incr,dest_channel->d.freqmod_multiplier,
- is_last_note ? "last":"");
-
- uint16 myfreq;
- dest_channel->d.time_left = channel->d.time_left;
- dest_channel->d.note_length =
- channel->d.time_left - dest_channel->d.inter_note_pause;
- note += dest_channel->d.transpose;
- while (note < 0)
- note += 12;
- octave = note / 12;
- note = note % 12;
- dest_channel->d.hull_offset = 0;
- dest_channel->d.hull_counter = 1;
- if (_pcjr && dest_channel == &_channels[3]) {
- dest_channel->d.hull_curve = 196 + note * 12;
- myfreq = 384 - 64 * octave;
- } else {
- myfreq = _freqs_table[note] >> octave;
- }
- dest_channel->d.freq = dest_channel->d.base_freq = myfreq;
- if (is_last_note)
- goto end;
- opcode = *script_ptr++;
- }
- }
- }
-
-end:
- channel = current_channel;
- if (channel->d.time_left) {
- channel->d.next_cmd = script_ptr - _current_data;
- return;
- }
-
- channel->d.next_cmd = 0;
-
-check_stopped:
- int i;
- for (i = 0; i < 4; i++) {
- if (_channels[i].d.time_left)
- return;
- }
-
- _current_nr = 0;
- _current_data = 0;
- chainNextSound();
- return;
-}
-
-void Player_V2::next_freqs(ChannelInfo *channel) {
- channel->d.volume += channel->d.volume_delta;
- channel->d.base_freq += channel->d.freq_delta;
-
- channel->d.freqmod_offset += channel->d.freqmod_incr;
- if (channel->d.freqmod_offset > channel->d.freqmod_modulo)
- channel->d.freqmod_offset -= channel->d.freqmod_modulo;
- channel->d.freq =
- (int) (freqmod_table[channel->d.freqmod_table + (channel->d.freqmod_offset >> 4)])
- * (int) channel->d.freqmod_multiplier / 256
- + channel->d.base_freq;
-
- debug(9, "Freq: %d/%d, %d/%d/%d*%d %d",
- channel->d.base_freq, (int16)channel->d.freq_delta,
- channel->d.freqmod_table, channel->d.freqmod_offset,
- channel->d.freqmod_incr, channel->d.freqmod_multiplier,
- channel->d.freq);
-
- if (channel->d.note_length && !--channel->d.note_length) {
- channel->d.hull_offset = 16;
- channel->d.hull_counter = 1;
- }
-
- if (!--channel->d.time_left) {
- execute_cmd(channel);
- }
-
-#if 0
- debug(9, "channels[%d]: freq %d hull %d/%d/%d",
- channel - &_channels[0], channel->d.freq,
- channel->d.hull_curve, channel->d.hull_offset,
- channel->d.hull_counter);
-#endif
-
- if (channel->d.hull_counter && !--channel->d.hull_counter) {
- for (;;) {
- const int16 *hull_ptr = hulls
- + channel->d.hull_curve + channel->d.hull_offset / 2;
- if (hull_ptr[1] == -1) {
- channel->d.volume = hull_ptr[0];
- if (hull_ptr[0] == 0)
- channel->d.volume_delta = 0;
- channel->d.hull_offset += 4;
- } else {
- channel->d.volume_delta = hull_ptr[0];
- channel->d.hull_counter = hull_ptr[1];
- channel->d.hull_offset += 4;
- break;
- }
- }
- }
-}
-
-void Player_V2::do_mix(int16 *data, uint len) {
- mutex_up();
- uint step;
-
- do {
- if (!(_next_tick >> FIXP_SHIFT)) {
- _next_tick += _tick_len;
- nextTick();
- }
-
- step = len;
- if (step > (_next_tick >> FIXP_SHIFT))
- step = (_next_tick >> FIXP_SHIFT);
- if (_pcjr)
- generatePCjrSamples(data, step);
- else
- generateSpkSamples(data, step);
- data += 2 * step;
- _next_tick -= step << FIXP_SHIFT;
- } while (len -= step);
-
- mutex_down();
-}
-
-void Player_V2::nextTick() {
- for (int i = 0; i < 4; i++) {
- if (!_channels[i].d.time_left)
- continue;
- next_freqs(&_channels[i]);
- }
- if (_music_timer_ctr++ >= _ticks_per_music_timer) {
- _music_timer_ctr = 0;
- _music_timer++;
- }
-}
-
-void Player_V2::lowPassFilter(int16 *sample, uint len) {
- for (uint i = 0; i < len; i++) {
- _level = (int) (_level * _decay
- + sample[0] * (0x10000 - _decay)) >> 16;
- sample[0] = sample[1] = _level;
- sample += 2;
- }
-}
-
-void Player_V2::squareGenerator(int channel, int freq, int vol,
- int noiseFeedback, int16 *sample, uint len) {
- int period = _update_step * freq;
- long nsample;
- if (period == 0)
- period = _update_step;
-
- for (uint i = 0; i < len; i++) {
- unsigned int duration = 0;
-
- if (_timer_output & (1 << channel))
- duration += _timer_count[channel];
-
- _timer_count[channel] -= (1 << FIXP_SHIFT);
- while (_timer_count[channel] <= 0) {
-
- if (noiseFeedback) {
- if (_RNG & 1) {
- _RNG ^= noiseFeedback;
- _timer_output ^= (1 << channel);
- }
- _RNG >>= 1;
- } else {
- _timer_output ^= (1 << channel);
- }
-
- if (_timer_output & (1 << channel))
- duration += period;
-
- _timer_count[channel] += period;
- }
-
- if (_timer_output & (1 << channel))
- duration -= _timer_count[channel];
-
- nsample = *sample +
- (((signed long) (duration - (1 << (FIXP_SHIFT - 1)))
- * (signed long) _volumetable[vol]) >> FIXP_SHIFT);
- /* overflow: clip value */
- if (nsample > 0x7fff)
- nsample = 0x7fff;
- if (nsample < -0x8000)
- nsample = -0x8000;
- *sample = nsample;
- // The following write isn't necessary, because the lowPassFilter does it for us
- //sample[1] = sample[0];
- sample += 2;
- }
-}
-
-void Player_V2::generateSpkSamples(int16 *data, uint len) {
- int winning_channel = -1;
- for (int i = 0; i < 4; i++) {
- if (winning_channel == -1
- && _channels[i].d.volume
- && _channels[i].d.time_left) {
- winning_channel = i;
- }
- }
-
- memset(data, 0, 2 * sizeof(int16) * len);
- if (winning_channel != -1) {
- squareGenerator(0, _channels[winning_channel].d.freq, 0,
- 0, data, len);
- } else if (_level == 0)
- /* shortcut: no sound is being played. */
- return;
-
- lowPassFilter(data, len);
-}
-
-void Player_V2::generatePCjrSamples(int16 *data, uint len) {
- int i, j;
- int freq, vol;
-
- memset(data, 0, 2 * sizeof(int16) * len);
- bool hasdata = false;
-
- for (i = 1; i < 3; i++) {
- freq = _channels[i].d.freq >> 6;
- if (_channels[i].d.volume && _channels[i].d.time_left) {
- for (j = 0; j < i; j++) {
- if (_channels[j].d.volume
- && _channels[j].d.time_left
- && freq == (_channels[j].d.freq >> 6)) {
- /* HACK: this channel is playing at
- * the same frequency as another.
- * Synchronize it to the same phase to
- * prevent interference.
- */
- _timer_count[i] = _timer_count[j];
- _timer_output ^= (1 << i) &
- (_timer_output ^ _timer_output << (i - j));
- }
- }
- }
- }
-
- for (i = 0; i < 4; i++) {
- freq = _channels[i].d.freq >> 6;
- vol = (65535 - _channels[i].d.volume) >> 12;
- if (!_channels[i].d.volume || !_channels[i].d.time_left) {
- _timer_count[i] -= len << FIXP_SHIFT;
- if (_timer_count[i] < 0)
- _timer_count[i] = 0;
- } else if (i < 3) {
- hasdata = true;
- squareGenerator(i, freq, vol, 0, data, len);
- } else {
- int noiseFB = (freq & 4) ? FB_WNOISE : FB_PNOISE;
- int n = (freq & 3);
-
- freq = (n == 3) ? 2 * (_channels[2].d.freq>>6) : 1 << (5 + n);
- hasdata = true;
- squareGenerator(i, freq, vol, noiseFB, data, len);
- }
-#if 0
- debug(9, "channel[%d]: freq %d %.1f ; volume %d",
- i, freq, 111860.0 / freq, vol);
-#endif
- }
-
- if (_level || hasdata)
- lowPassFilter(data, len);
-}
-
-void Player_V2::mutex_up() {
- _mutex.lock();
-}
-
-void Player_V2::mutex_down() {
- _mutex.unlock();
-}
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(PlayerV2)
-_GSETPTR(Scumm::note_lengths, GBVARS_NOTELENGTHS_INDEX, uint8, GBVARS_SCUMM)
-_GSETPTR(Scumm::hull_offsets, GBVARS_HULLOFFSETS_INDEX, uint16, GBVARS_SCUMM)
-_GSETPTR(Scumm::hulls, GBVARS_HULLS_INDEX, int16, GBVARS_SCUMM)
-_GSETPTR(Scumm::freqmod_lengths, GBVARS_FREQMODLENGTHS_INDEX, uint16, GBVARS_SCUMM)
-_GSETPTR(Scumm::freqmod_offsets, GBVARS_FREQMODOFFSETS_INDEX, uint16, GBVARS_SCUMM)
-_GSETPTR(Scumm::freqmod_table, GBVARS_FREQMODTABLE_INDEX, int8, GBVARS_SCUMM)
-_GSETPTR(Scumm::spk_freq_table, GBVARS_SPKFREQTABLE_INDEX, uint16, GBVARS_SCUMM)
-_GSETPTR(Scumm::pcjr_freq_table, GBVARS_PCJRFREQTABLE_INDEX, uint16, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(PlayerV2)
-_GRELEASEPTR(GBVARS_NOTELENGTHS_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_HULLOFFSETS_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_HULLS_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FREQMODLENGTHS_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FREQMODOFFSETS_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_FREQMODTABLE_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_SPKFREQTABLE_INDEX, GBVARS_SCUMM)
-_GRELEASEPTR(GBVARS_PCJRFREQTABLE_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/player_v2.h b/scumm/player_v2.h
deleted file mode 100644
index 160400e06a..0000000000
--- a/scumm/player_v2.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PLAYER_V2_H
-#define PLAYER_V2_H
-
-#include "common/scummsys.h"
-#include "common/mutex.h"
-#include "scumm/music.h"
-#include "sound/audiostream.h"
-
-namespace Audio {
- class Mixer;
-}
-
-namespace Scumm {
-
-class ScummEngine;
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
-struct channel_data {
- uint16 time_left; // 00
- uint16 next_cmd; // 02
- uint16 base_freq; // 04
- uint16 freq_delta; // 06
- uint16 freq; // 08
- uint16 volume; // 10
- uint16 volume_delta; // 12
- uint16 tempo; // 14
- uint16 inter_note_pause; // 16
- uint16 transpose; // 18
- uint16 note_length; // 20
- uint16 hull_curve; // 22
- uint16 hull_offset; // 24
- uint16 hull_counter; // 26
- uint16 freqmod_table; // 28
- uint16 freqmod_offset; // 30
- uint16 freqmod_incr; // 32
- uint16 freqmod_multiplier; // 34
- uint16 freqmod_modulo; // 36
- uint16 unknown[4]; // 38 - 44
- uint16 music_timer; // 46
- uint16 music_script_nr; // 48
-} GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-
-/**
- * Scumm V2 PC-Speaker MIDI driver.
- * This simulates the pc speaker sound, which is driven by the 8253 (square
- * wave generator) and a low-band filter.
- */
-class Player_V2 : public AudioStream, public MusicEngine {
-public:
- Player_V2(ScummEngine *scumm, bool pcjr);
- virtual ~Player_V2();
-
- virtual void setMusicVolume(int vol);
- virtual void startSound(int sound);
- virtual void stopSound(int sound);
- virtual void stopAllSounds();
- virtual int getMusicTimer() const;
- virtual int getSoundStatus(int sound) const;
-
- // AudioStream API
- int readBuffer(int16 *buffer, const int numSamples) {
- do_mix(buffer, numSamples / 2);
- return numSamples;
- }
- bool isStereo() const { return true; }
- bool endOfData() const { return false; }
- int getRate() const { return _sample_rate; }
-
-protected:
- bool _isV3Game;
- Audio::Mixer *_mixer;
- ScummEngine *_vm;
-
- bool _pcjr;
- int _header_len;
-
- uint32 _sample_rate;
- uint32 _next_tick;
- uint32 _tick_len;
- unsigned int _update_step;
- unsigned int _decay;
- int _level;
- unsigned int _RNG;
- unsigned int _volumetable[16];
-
- int _timer_count[4];
- int _timer_output;
-
- int _current_nr;
- byte *_current_data;
- int _next_nr;
- byte *_next_data;
- byte *_retaddr;
-
-private:
- union ChannelInfo {
- channel_data d;
- uint16 array[sizeof(channel_data)/2];
- };
-
- int _music_timer;
- int _music_timer_ctr;
- int _ticks_per_music_timer;
-
- const uint16 *_freqs_table;
-
- Common::Mutex _mutex;
- ChannelInfo _channels[5];
-
-protected:
- void mutex_up();
- void mutex_down();
-
- virtual void nextTick();
- virtual void clear_channel(int i);
- virtual void chainSound(int nr, byte *data);
- virtual void chainNextSound();
-
- virtual void generateSpkSamples(int16 *data, uint len);
- virtual void generatePCjrSamples(int16 *data, uint len);
-
- void lowPassFilter(int16 *data, uint len);
- void squareGenerator(int channel, int freq, int vol,
- int noiseFeedback, int16 *sample, uint len);
-
-private:
- void do_mix(int16 *buf, uint len);
-
- void set_pcjr(bool pcjr);
- void execute_cmd(ChannelInfo *channel);
- void next_freqs(ChannelInfo *channel);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/player_v2a.cpp b/scumm/player_v2a.cpp
deleted file mode 100644
index 36499ba527..0000000000
--- a/scumm/player_v2a.cpp
+++ /dev/null
@@ -1,1420 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "base/engine.h"
-#include "scumm/player_v2a.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-#define BASE_FREQUENCY 3579545
-
-#ifdef PALMOS_68K
-static uint32 *CRCtable = NULL;
-#else
-static uint32 CRCtable[256];
-#endif
-
-static void InitCRC (void)
-{
- const uint32 poly = 0xEDB88320;
- int i, j;
- uint32 n;
-
- for (i = 0; i < 256; i++)
- {
- n = i;
- for (j = 0; j < 8; j++)
- n = (n & 1) ? ((n >> 1) ^ poly) : (n >> 1);
- CRCtable[i] = n;
- }
-}
-
-static uint32 GetCRC (byte *data, int len)
-{
- uint32 CRC = 0xFFFFFFFF;
- int i;
- for (i = 0; i < len; i++)
- CRC = (CRC >> 8) ^ CRCtable[(CRC ^ data[i]) & 0xFF];
- return CRC ^ 0xFFFFFFFF;
-}
-
-class V2A_Sound {
-public:
- V2A_Sound() : _id(0), _mod(NULL) { }
- virtual ~V2A_Sound() {};
- virtual void start(Player_MOD *mod, int id, const byte *data) = 0;
- virtual bool update() = 0;
- virtual void stop() = 0;
-protected:
- int _id;
- Player_MOD *_mod;
-};
-
-// unsupported sound effect, print warning message to console
-class V2A_Sound_Unsupported : public V2A_Sound {
-public:
- V2A_Sound_Unsupported() { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- warning("player_v2a - sound %i not supported yet", id);
- }
- virtual bool update() { return false; }
- virtual void stop() { }
-};
-
-// template, automatically stops all channels when a sound is silenced
-template<int numChan>
-class V2A_Sound_Base : public V2A_Sound {
-public:
- V2A_Sound_Base() : _offset(0), _size(0), _data(0) { }
- V2A_Sound_Base(uint16 offset, uint16 size) : _offset(offset), _size(size), _data(0) { }
- virtual void stop() {
- assert(_id);
- for (int i = 0; i < numChan; i++)
- _mod->stopChannel(_id | (i << 8));
- _id = 0;
- free(_data);
- _data = 0;
- }
-protected:
- const uint16 _offset;
- const uint16 _size;
-
- char *_data;
-};
-
-// plays a music track
-class V2A_Sound_Music : public V2A_Sound {
-public:
- V2A_Sound_Music(uint16 instoff, uint16 voloff, uint16 chan1off, uint16 chan2off, uint16 chan3off, uint16 chan4off, uint16 sampoff, bool looped) :
- _instoff(instoff), _voloff(voloff), _chan1off(chan1off), _chan2off(chan2off), _chan3off(chan3off), _chan4off(chan4off), _sampoff(sampoff), _looped(looped) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
-
- _data = (char *)malloc(READ_LE_UINT16(data));
- memcpy(_data, data, READ_LE_UINT16(data));
-
- _chan[0].dataptr_i = _chan1off;
- _chan[1].dataptr_i = _chan2off;
- _chan[2].dataptr_i = _chan3off;
- _chan[3].dataptr_i = _chan4off;
- for (int i = 0; i < 4; i++) {
- _chan[i].dataptr = _chan[i].dataptr_i;
- _chan[i].volbase = 0;
- _chan[i].volptr = 0;
- _chan[i].chan = 0;
- _chan[i].dur = 0;
- _chan[i].ticks = 0;
- }
- update();
- }
- virtual bool update() {
- assert(_id);
- int i, j = 0;
- for (i = 0; i < 4; i++) {
- if (_chan[i].dur) {
- if (!--_chan[i].dur) {
- _mod->stopChannel(_id | (_chan[i].chan << 8));
- } else {
- _mod->setChannelVol(_id | (_chan[i].chan << 8),
- READ_BE_UINT16(_data + _chan[i].volbase + (_chan[i].volptr++ << 1)));
- if (_chan[i].volptr == 0) {
- _mod->stopChannel(_id | (_chan[i].chan << 8));
- _chan[i].dur = 0;
- }
- }
- }
- if (!_chan[i].dataptr) {
- j++;
- continue;
- }
- if (READ_BE_UINT16(_data + _chan[i].dataptr) <= _chan[i].ticks) {
- if (READ_BE_UINT16(_data + _chan[i].dataptr + 2) == 0xFFFF) {
- if (_looped) {
- _chan[i].dataptr = _chan[i].dataptr_i;
- _chan[i].ticks = 0;
- if (READ_BE_UINT16(_data + _chan[i].dataptr) > 0) {
- _chan[i].ticks++;
- continue;
- }
- } else {
- _chan[i].dataptr = 0;
- j++;
- continue;
- }
- }
- int freq = BASE_FREQUENCY / READ_BE_UINT16(_data + _chan[i].dataptr + 2);
- int inst = READ_BE_UINT16(_data + _chan[i].dataptr + 8);
- _chan[i].volbase = _voloff + (READ_BE_UINT16(_data + _instoff + (inst << 5)) << 9);
- _chan[i].volptr = 0;
- _chan[i].chan = READ_BE_UINT16(_data + _chan[i].dataptr + 6) & 0x3;
-
- if (_chan[i].dur) // if there's something playing, stop it
- _mod->stopChannel(_id | (_chan[i].chan << 8));
-
- _chan[i].dur = READ_BE_UINT16(_data + _chan[i].dataptr + 4);
-
- int vol = READ_BE_UINT16(_data + _chan[i].volbase + (_chan[i].volptr++ << 1));
-
- int pan;
- if ((_chan[i].chan == 0) || (_chan[i].chan == 3))
- pan = -127;
- else pan = 127;
- int offset = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x14);
- int len = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x18);
- int loopoffset = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x16);
- int looplen = READ_BE_UINT16(_data + _instoff + (inst << 5) + 0x10);
-
- int size = len + looplen;
- char *data = (char *)malloc(size);
- memcpy(data, _data + _sampoff + offset, len);
- memcpy(data + len, _data + _sampoff + loopoffset, looplen);
-
- _mod->startChannel(_id | (_chan[i].chan << 8), data, size, freq, vol, len, looplen + len, pan);
- _chan[i].dataptr += 16;
- }
- _chan[i].ticks++;
- }
- if (j == 4)
- return false;
- return true;
- }
- virtual void stop() {
- assert(_id);
- for (int i = 0; i < 4; i++) {
- if (_chan[i].dur)
- _mod->stopChannel(_id | (_chan[i].chan << 8));
- }
- free(_data);
- _id = 0;
- }
-private:
- const uint16 _instoff;
- const uint16 _voloff;
- const uint16 _chan1off;
- const uint16 _chan2off;
- const uint16 _chan3off;
- const uint16 _chan4off;
- const uint16 _sampoff;
- const bool _looped;
-
- char *_data;
- struct tchan {
- uint16 dataptr_i;
- uint16 dataptr;
- uint16 volbase;
- uint8 volptr;
- uint16 chan;
- uint16 dur;
- uint16 ticks;
- } _chan[4];
-};
-
-// plays a single waveform
-class V2A_Sound_Single : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Single(uint16 offset, uint16 size, uint16 freq, uint8 vol) :
- V2A_Sound_Base<1>(offset, size), _freq(freq), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- int vol = (_vol << 2) | (_vol >> 4);
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _freq, vol, 0, 0);
- _ticks = 1 + (60 * _size * _freq) / BASE_FREQUENCY;
- }
- virtual bool update() {
- assert(_id);
- _ticks--;
- if (!_ticks) {
- return false;
- }
- return true;
- }
-private:
- const uint16 _freq;
- const uint8 _vol;
-
- int _ticks;
-};
-
-// plays a single looped waveform
-class V2A_Sound_SingleLooped : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_SingleLooped(uint16 offset, uint16 size, uint16 freq, uint8 vol, uint16 loopoffset, uint16 loopsize) :
- V2A_Sound_Base<1>(offset, size), _loopoffset(loopoffset), _loopsize(loopsize), _freq(freq), _vol(vol) { }
- V2A_Sound_SingleLooped(uint16 offset, uint16 size, uint16 freq, uint8 vol) :
- V2A_Sound_Base<1>(offset, size), _loopoffset(0), _loopsize(size), _freq(freq), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- int vol = (_vol << 2) | (_vol >> 4);
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _freq, vol, _loopoffset, _loopoffset + _loopsize);
- }
- virtual bool update() {
- assert(_id);
- return true;
- }
-private:
- const uint16 _loopoffset;
- const uint16 _loopsize;
- const uint16 _freq;
- const uint8 _vol;
-};
-
-// plays two looped waveforms
-class V2A_Sound_MultiLooped : public V2A_Sound_Base<2> {
-public:
- V2A_Sound_MultiLooped(uint16 offset, uint16 size, uint16 freq1, uint8 vol1, uint16 freq2, uint8 vol2) :
- V2A_Sound_Base<2>(offset, size), _freq1(freq1), _vol1(vol1), _freq2(freq2), _vol2(vol2) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data1 = (char *)malloc(_size);
- char *tmp_data2 = (char *)malloc(_size);
- memcpy(tmp_data1, data + _offset, _size);
- memcpy(tmp_data2, data + _offset, _size);
- int vol1 = (_vol1 << 1) | (_vol1 >> 5);
- int vol2 = (_vol2 << 1) | (_vol2 >> 5);
- _mod->startChannel(_id | 0x000, tmp_data1, _size, BASE_FREQUENCY / _freq1, vol1, 0, _size, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, _size, BASE_FREQUENCY / _freq2, vol2, 0, _size, 127);
- }
- virtual bool update() {
- assert(_id);
- return true;
- }
-private:
- const uint16 _freq1;
- const uint8 _vol1;
- const uint16 _freq2;
- const uint8 _vol2;
-};
-
-// plays two looped waveforms for a fixed number of frames
-class V2A_Sound_MultiLoopedDuration : public V2A_Sound_MultiLooped {
-public:
- V2A_Sound_MultiLoopedDuration(uint16 offset, uint16 size, uint16 freq1, uint8 vol1, uint16 freq2, uint8 vol2, uint16 numframes) :
- V2A_Sound_MultiLooped(offset, size, freq1, vol1, freq2, vol2), _duration(numframes) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- V2A_Sound_MultiLooped::start(mod, id, data);
- _ticks = 0;
- }
- virtual bool update() {
- assert(_id);
- _ticks++;
- if (_ticks >= _duration)
- return false;
- return true;
- }
-private:
- const uint16 _duration;
-
- int _ticks;
-};
-
-// plays a single looped waveform which starts at one frequency and bends to another frequency, where it remains until stopped
-class V2A_Sound_SingleLoopedPitchbend : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_SingleLoopedPitchbend(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint8 vol, uint8 step) :
- V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2), _vol(vol), _step(step) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- int vol = (_vol << 2) | (_vol >> 4);
- _curfreq = _freq1;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, vol, 0, _size);
- }
- virtual bool update() {
- assert(_id);
- if (_freq1 < _freq2) {
- _curfreq += _step;
- if (_curfreq > _freq2)
- _curfreq = _freq2;
- else
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- } else {
- _curfreq -= _step;
- if (_curfreq < _freq2)
- _curfreq = _freq2;
- else
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- }
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
- const uint8 _vol;
- const uint16 _step;
-
- uint16 _curfreq;
-};
-
-// plays a single looped waveform starting at a specific frequency/volume, dropping in frequency and fading volume to zero
-// used when Maniac Mansion explodes
-class V2A_Sound_Special_ManiacNuclear : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ManiacNuclear(uint16 offset, uint16 size, uint16 freq, uint8 vol) :
- V2A_Sound_Base<1>(offset, size), _freq(freq), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curvol = (_vol << 3) | (_vol >> 3);
- _curfreq = _freq;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, _curvol >> 1, 0, _size);
- }
- virtual bool update() {
- assert(_id);
- _curfreq += 2;
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- _curvol--;
- if (_curvol == 0)
- return false;
- _mod->setChannelVol(_id, _curvol >> 1);
- return true;
- }
-private:
- const uint16 _freq;
- const uint8 _vol;
-
- uint16 _curfreq;
- uint16 _curvol;
-};
-
-// plays a single looped waveform, fading the volume from zero to maximum at one rate, then back to zero at another rate
-// used when a microwave oven goes 'Ding'
-class V2A_Sound_Special_ManiacDing : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ManiacDing(uint16 offset, uint16 size, uint16 freq, uint8 fadeinrate, uint8 fadeoutrate) :
- V2A_Sound_Base<1>(offset, size), _freq(freq), _fade1(fadeinrate), _fade2(fadeoutrate) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curvol = 1;
- _dir = 0;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _freq, _curvol, 0, _size);
- }
- virtual bool update() {
- assert(_id);
- if (_dir == 0) {
- _curvol += _fade1;
- if (_curvol > 0x3F) {
- _curvol = 0x3F;
- _dir = 1;
- }
- } else {
- _curvol -= _fade2;
- if (_curvol < 1)
- return false;
- }
- _mod->setChannelVol(_id, (_curvol << 2) | (_curvol >> 4));
- return true;
- }
-private:
- const uint16 _freq;
- const uint16 _fade1;
- const uint16 _fade2;
-
- int _curvol;
- int _dir;
-};
-
-// plays two looped waveforms, fading the volume from zero to maximum at one rate, then back to zero at another rate
-// used in Zak McKracken for several stereo 'Ding' sounds
-class V2A_Sound_Special_ZakStereoDing : public V2A_Sound_Base<2> {
-public:
- V2A_Sound_Special_ZakStereoDing(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint8 fadeinrate, uint8 fadeoutrate) :
- V2A_Sound_Base<2>(offset, size), _freq1(freq1), _freq2(freq2), _fade1(fadeinrate), _fade2(fadeoutrate) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data1 = (char *)malloc(_size);
- char *tmp_data2 = (char *)malloc(_size);
- memcpy(tmp_data1, data + _offset, _size);
- memcpy(tmp_data2, data + _offset, _size);
- _curvol = 1;
- _dir = 0;
- _mod->startChannel(_id | 0x000, tmp_data1, _size, BASE_FREQUENCY / _freq1, 1, 0, _size, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, _size, BASE_FREQUENCY / _freq2, 1, 0, _size, 127);
- }
- virtual bool update() {
- assert(_id);
- if (_dir == 0) {
- _curvol += _fade1;
- if (_curvol > 0x3F) {
- _curvol = 0x3F;
- _dir = 1;
- }
- } else {
- _curvol -= _fade2;
- if (_curvol < 1)
- return false;
- }
- _mod->setChannelVol(_id | 0x000, (_curvol << 1) | (_curvol >> 5));
- _mod->setChannelVol(_id | 0x100, (_curvol << 1) | (_curvol >> 5));
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
- const uint16 _fade1;
- const uint16 _fade2;
-
- int _curvol;
- int _dir;
-};
-
-// plays a single looped waveform, starting at one frequency and at full volume, bending down to another frequency, and then fading volume to zero
-// used in Maniac Mansion for the tentacle sounds
-class V2A_Sound_Special_ManiacTentacle : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ManiacTentacle(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint16 step) :
- V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2), _step(step) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curfreq = _freq1;
- _curvol = 0x3F;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, (_curvol << 2) | (_curvol >> 4), 0, _size);
- }
- virtual bool update() {
- assert(_id);
- if (_curfreq > _freq2)
- _curvol = 0x3F + _freq2 - _curfreq;
- if (_curvol < 1)
- return false;
- _curfreq += _step;
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- _mod->setChannelVol(_id, (_curvol << 2) | (_curvol >> 4));
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
- const uint16 _step;
-
- uint16 _curfreq;
- int _curvol;
-};
-
-// plays a single looped waveform, starting at one frequency, bending down to another frequency, and then back up to the original frequency
-// used for electronic noises
-class V2A_Sound_Special_ManiacElectric : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ManiacElectric(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint16 step, uint8 vol) :
- V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2), _step(step), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- int vol = (_vol << 2) | (_vol >> 4);
- _curfreq = _freq1;
- _dir = 2;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, vol, 0, _size);
- }
- virtual bool update() {
- assert(_id);
- if (_dir == 2) {
- _curfreq += _step;
- if (_curfreq > _freq2) {
- _curfreq = _freq2;
- _dir = 1;
- }
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- } else if (_dir == 1) {
- _curfreq -= _step;
- if (_curfreq < _freq1) {
- _curfreq = _freq1;
- _dir = 0;
- }
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- }
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
- const uint16 _step;
- const uint8 _vol;
-
- uint16 _curfreq;
- int _dir;
-};
-
-// plays a single looped waveform, simultaneously bending the frequency downward and slowly fading volume to zero
-// don't remember where this one is used
-// old name: SlowPitchbendDownAndFadeout
-class V2A_Sound_Special_Maniac61 : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_Maniac61(uint16 offset, uint16 size, uint16 freq1, uint16 freq2) :
- V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curfreq = _freq1;
- _curvol = 0x3F;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, (_curvol << 2) | (_curvol >> 4), 0, _size);
- }
- virtual bool update() {
- assert(_id);
- _curfreq++;
- if (!(_curfreq & 3))
- _curvol--;
- if ((_curfreq == _freq2) || (_curvol == 0))
- return false;
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- _mod->setChannelVol(_id, (_curvol << 2) | (_curvol >> 4));
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
-
- uint16 _curfreq;
- uint8 _curvol;
-};
-
-// intermittently plays two looped waveforms for a specific duration
-// used for ringing telephones
-class V2A_Sound_Special_ManiacPhone : public V2A_Sound_Base<2> {
-public:
- V2A_Sound_Special_ManiacPhone(uint16 offset, uint16 size, uint16 freq1, uint8 vol1, uint16 freq2, uint8 vol2, uint16 numframes, uint8 playwidth, uint8 loopwidth) :
- V2A_Sound_Base<2>(offset, size), _freq1(freq1), _vol1(vol1), _freq2(freq2), _vol2(vol2), _duration(numframes), _playwidth(playwidth), _loopwidth(loopwidth) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- _data = (char *)malloc(READ_LE_UINT16(data));
- memcpy(_data, data, READ_LE_UINT16(data));
- soundon();
- _ticks = 0;
- _loop = 0;
- }
- virtual bool update() {
- assert(_id);
- if (_loop == _playwidth) {
- _mod->stopChannel(_id | 0x000);
- _mod->stopChannel(_id | 0x100);
- }
- if (_loop == _loopwidth) {
- _loop = 0;
- soundon();
- }
- _loop++;
- _ticks++;
- if (_ticks >= _duration)
- return false;
- return true;
- }
-private:
- const uint16 _freq1;
- const uint8 _vol1;
- const uint16 _freq2;
- const uint8 _vol2;
- const uint16 _duration;
- const uint8 _playwidth;
- const uint8 _loopwidth;
-
- int _ticks;
- int _loop;
-
- void soundon() {
- char *tmp_data1 = (char *)malloc(_size);
- char *tmp_data2 = (char *)malloc(_size);
- memcpy(tmp_data1, _data + _offset, _size);
- memcpy(tmp_data2, _data + _offset, _size);
- int vol1 = (_vol1 << 1) | (_vol1 >> 5);
- int vol2 = (_vol2 << 1) | (_vol2 >> 5);
- _mod->startChannel(_id | 0x000, tmp_data1, _size, BASE_FREQUENCY / _freq1, vol1, 0, _size, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, _size, BASE_FREQUENCY / _freq2, vol2, 0, _size, 127);
- }
-};
-
-// intermittently plays a single waveform for a specified duration
-// used when applying a wrench to a pipe
-class V2A_Sound_Special_ManiacWrench : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ManiacWrench(uint16 offset, uint16 size, uint16 freq, uint8 vol, uint8 loopwidth, uint8 numloops) :
- V2A_Sound_Base<1>(offset, size), _freq(freq), _vol(vol), _loopwidth(loopwidth), _numloops(numloops) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- _data = (char *)malloc(READ_LE_UINT16(data));
- memcpy(_data, data, READ_LE_UINT16(data));
- soundon();
- _loop = 0;
- _loopctr = 0;
- }
- virtual bool update() {
- assert(_id);
- _loop++;
- if (_loop == _loopwidth) {
- _loop = 0;
- _loopctr++;
- if (_loopctr == _numloops)
- return false;
- _mod->stopChannel(_id);
- soundon();
- }
- return true;
- }
-private:
- const uint16 _freq;
- const uint8 _vol;
- const uint8 _loopwidth;
- const uint8 _numloops;
-
- int _loop;
- int _loopctr;
-
- void soundon() {
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, _data + _offset, _size);
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _freq, (_vol << 2) | (_vol >> 4), 0, 0);
- }
-};
-
-// plays a single waveform at irregular intervals for a specified number of frames, possibly looped
-// used for typewriter noises, as well as tapping on the bus in Zak McKracken
-class V2A_Sound_Special_ManiacTypewriter : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ManiacTypewriter(uint16 offset, uint16 size, uint16 freq, uint8 vol, uint8 numdurs, const uint8 *durations, bool looped) :
- V2A_Sound_Base<1>(offset, size), _freq(freq), _vol(vol), _numdurs(numdurs), _durations(durations), _looped(looped) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- _data = (char *)malloc(READ_LE_UINT16(data));
- memcpy(_data, data, READ_LE_UINT16(data));
- soundon();
- _curdur = 0;
- _ticks = _durations[_curdur++];
- }
- virtual bool update() {
- assert(_id);
- _ticks--;
- if (!_ticks) {
- if (_curdur == _numdurs) {
- if (_looped)
- _curdur = 0;
- else
- return false;
- }
- _mod->stopChannel(_id);
- soundon();
- _ticks = _durations[_curdur++];
- }
- return true;
- }
-private:
- const uint16 _freq;
- const uint8 _vol;
- const uint8 _numdurs;
- const uint8 *_durations;
- const bool _looped;
-
- int _ticks;
- int _curdur;
-
- void soundon() {
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, _data + _offset, _size);
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _freq, (_vol << 2) | (_vol >> 4), 0, 0);
- }
-};
-
-// plays two looped waveforms pitch bending up at various predefined rates
-// used for some sort of siren-like noise in Maniac Mansion
-// old name: TwinSirenMulti
-class V2A_Sound_Special_Maniac44 : public V2A_Sound_Base<2> {
-public:
- V2A_Sound_Special_Maniac44(uint16 offset1, uint16 size1, uint16 offset2, uint16 size2, uint16 freq1, uint16 freq2, uint8 vol) :
- _offset1(offset1), _size1(size1), _offset2(offset2), _size2(size2), _freq1(freq1), _freq2(freq2), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- _data = (char *)malloc(READ_LE_UINT16(data));
- memcpy(_data, data, READ_LE_UINT16(data));
-
- _loopnum = 1;
- _step = 2;
- _curfreq = _freq1;
-
- soundon(_data + _offset1, _size1);
- }
- virtual bool update() {
- assert(_id);
- _mod->setChannelFreq(_id | 0x000, BASE_FREQUENCY / _curfreq);
- _mod->setChannelFreq(_id | 0x100, BASE_FREQUENCY / (_curfreq + 3));
- _curfreq -= _step;
- if (_loopnum == 7) {
- if ((BASE_FREQUENCY / _curfreq) >= 65536)
- return false;
- else
- return true;
- }
- if (_curfreq >= _freq2)
- return true;
- const char steps[8] = {0, 2, 2, 3, 4, 8, 15, 2};
- _curfreq = _freq1;
- _step = steps[++_loopnum];
- if (_loopnum == 7) {
- _mod->stopChannel(_id | 0x000);
- _mod->stopChannel(_id | 0x100);
- soundon(_data + _offset2, _size2);
- }
- return true;
- }
-private:
- const uint16 _offset1;
- const uint16 _size1;
- const uint16 _offset2;
- const uint16 _size2;
- const uint16 _freq1;
- const uint16 _freq2;
- const uint8 _vol;
-
- int _curfreq;
- uint16 _loopnum;
- uint16 _step;
-
- void soundon(const char *data, int size) {
- char *tmp_data1 = (char *)malloc(size);
- char *tmp_data2 = (char *)malloc(size);
- memcpy(tmp_data1, data, size);
- memcpy(tmp_data2, data, size);
- int vol = (_vol << 1) | (_vol >> 5);
- _mod->startChannel(_id | 0x000, tmp_data1, size, BASE_FREQUENCY / _curfreq, vol, 0, size, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, size, BASE_FREQUENCY / (_curfreq + 3), vol, 0, size, 127);
- }
-};
-
-// plays 4 looped waveforms, each at modulating frequencies
-// used for the siren noise in Maniac Mansion
-class V2A_Sound_Special_ManiacSiren : public V2A_Sound_Base<4> {
-public:
- V2A_Sound_Special_ManiacSiren(uint16 offset1, uint16 size1, uint16 offset2, uint16 size2, uint8 vol) :
- _offset1(offset1), _size1(size1), _offset2(offset2), _size2(size2), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
-
- _freq1 = 0x02D0;
- _step1 = -0x000A;
- _freq2 = 0x0122;
- _step2 = 0x000A;
- _freq3 = 0x02BC;
- _step3 = -0x0005;
- _freq4 = 0x010E;
- _step4 = 0x0007;
-
- char *tmp_data1 = (char *)malloc(_size1);
- char *tmp_data2 = (char *)malloc(_size2);
- char *tmp_data3 = (char *)malloc(_size1);
- char *tmp_data4 = (char *)malloc(_size2);
- memcpy(tmp_data1, data + _offset1, _size1);
- memcpy(tmp_data2, data + _offset2, _size2);
- memcpy(tmp_data3, data + _offset1, _size1);
- memcpy(tmp_data4, data + _offset2, _size2);
- _mod->startChannel(_id | 0x000, tmp_data1, _size1, BASE_FREQUENCY / _freq1, _vol, 0, _size1, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, _size2, BASE_FREQUENCY / _freq2, _vol, 0, _size2, 127);
- _mod->startChannel(_id | 0x200, tmp_data3, _size1, BASE_FREQUENCY / _freq3, _vol, 0, _size1, 127);
- _mod->startChannel(_id | 0x300, tmp_data4, _size2, BASE_FREQUENCY / _freq4, _vol, 0, _size2, -127);
- }
- virtual bool update() {
- assert(_id);
- updatefreq(_freq1, _step1, 0x00AA, 0x00FA);
- updatefreq(_freq2, _step2, 0x019A, 0x03B6);
- updatefreq(_freq3, _step3, 0x00AA, 0x00FA);
- updatefreq(_freq4, _step4, 0x019A, 0x03B6);
- _mod->setChannelFreq(_id | 0x000, BASE_FREQUENCY / _freq1);
- _mod->setChannelFreq(_id | 0x100, BASE_FREQUENCY / _freq2);
- _mod->setChannelFreq(_id | 0x200, BASE_FREQUENCY / _freq3);
- _mod->setChannelFreq(_id | 0x300, BASE_FREQUENCY / _freq4);
- return true;
- }
-private:
- const uint16 _offset1;
- const uint16 _size1;
- const uint16 _offset2;
- const uint16 _size2;
- const uint8 _vol;
-
- uint16 _freq1;
- int16 _step1;
- uint16 _freq2;
- int16 _step2;
- uint16 _freq3;
- int16 _step3;
- uint16 _freq4;
- int16 _step4;
-
- void updatefreq (uint16 &freq, int16 &step, uint16 min, uint16 max) {
- freq += step;
- if (freq <= min) {
- freq = min;
- step = -step;
- }
- if (freq >= max) {
- freq = max;
- step = -step;
- }
- }
-};
-
-// plays 4 looped waveforms
-// some sort of laserbeam-like sound effect in Zak
-// old name: QuadFreqLooped
-class V2A_Sound_Special_Zak70 : public V2A_Sound_Base<4> {
-public:
- V2A_Sound_Special_Zak70(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint16 freq3, uint16 freq4, uint8 vol) :
- V2A_Sound_Base<4>(offset, size), _freq1(freq1), _freq2(freq2), _freq3(freq3), _freq4(freq4), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
-
- char *tmp_data1 = (char *)malloc(_size);
- char *tmp_data2 = (char *)malloc(_size);
- char *tmp_data3 = (char *)malloc(_size);
- char *tmp_data4 = (char *)malloc(_size);
- memcpy(tmp_data1, data + _offset, _size);
- memcpy(tmp_data2, data + _offset, _size);
- memcpy(tmp_data3, data + _offset, _size);
- memcpy(tmp_data4, data + _offset, _size);
- _mod->startChannel(_id | 0x000, tmp_data1, _size, BASE_FREQUENCY / _freq1, _vol, 0, _size, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, _size, BASE_FREQUENCY / _freq2, _vol, 0, _size, 127);
- _mod->startChannel(_id | 0x200, tmp_data3, _size, BASE_FREQUENCY / _freq3, _vol, 0, _size, 127);
- _mod->startChannel(_id | 0x300, tmp_data4, _size, BASE_FREQUENCY / _freq4, _vol, 0, _size, -127);
- }
- virtual bool update() {
- assert(_id);
- return true;
- }
-protected:
- const uint16 _freq1;
- const uint16 _freq2;
- const uint16 _freq3;
- const uint16 _freq4;
- const uint8 _vol;
-};
-
-// plays 4 looped waveforms and fades volume to zero after a specific delay
-// some whooshing-type sound in Zak
-// old name: QuadFreqFadeout
-class V2A_Sound_Special_Zak101 : public V2A_Sound_Special_Zak70 {
-public:
- V2A_Sound_Special_Zak101(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint16 freq3, uint16 freq4, uint8 vol, uint16 dur) :
- V2A_Sound_Special_Zak70(offset, size, freq1, freq2, freq3, freq4, vol), _dur(dur) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- V2A_Sound_Special_Zak70::start(mod, id, data);
- _ticks = _dur;
- }
- virtual bool update() {
- assert(_id);
- if (!--_ticks)
- return false;
- if (_ticks < _vol) {
- _mod->setChannelVol(_id | 0x000, _ticks);
- _mod->setChannelVol(_id | 0x100, _ticks);
- _mod->setChannelVol(_id | 0x200, _ticks);
- _mod->setChannelVol(_id | 0x300, _ticks);
- }
- return true;
- }
-private:
- const uint16 _dur;
-
- int _ticks;
-};
-
-// plays a single looped waveform and slowly fades volume to zero
-// another whooshing-type noise in Zak
-// old name: SingleFadeout
-class V2A_Sound_Special_Zak37 : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_Zak37(uint16 offset, uint16 size, uint16 freq, uint8 vol) :
- V2A_Sound_Base<1>(offset, size), _freq(freq), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curvol = _vol << 2;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _freq, _curvol, 0, _size);
- }
- virtual bool update() {
- assert(_id);
- if (!--_curvol)
- return false;
- _mod->setChannelVol(_id, _curvol);
- return true;
- }
-private:
- const uint16 _freq;
- const uint8 _vol;
-
- int _curvol;
-};
-
-// plays a single looped waveform, slowly bending from one frequency to another and then slowly fading volume from max to zero
-// used in Zak for airplane taking off and landing
-class V2A_Sound_Special_ZakAirplane : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ZakAirplane(uint16 offset, uint16 size, uint16 freq1, uint16 freq2) :
- V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curfreq = _freq1;
- _curvol = 0x3F;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, (_curvol << 2) | (_curvol >> 4), 0, _size);
- _ticks = 0;
- }
- virtual bool update() {
- assert(_id);
- _ticks++;
- if (_ticks < 4)
- return true;
- _ticks = 0;
- if (_curfreq == _freq2) {
- _curvol--;
- if (_curvol == 0)
- return false;
- _mod->setChannelVol(_id, (_curvol << 2) | (_curvol >> 4));
- }
- else {
- if (_freq1 < _freq2)
- _curfreq++;
- else
- _curfreq--;
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- }
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
-
- uint16 _curfreq;
- int _curvol;
- int _ticks;
-};
-
-// plays 4 looped waveforms, starting at specific frequencies and bending at different rates while fading volume to zero
-// used for some weird sound effect
-class V2A_Sound_Special_Zak71 : public V2A_Sound_Base<4> {
-public:
- V2A_Sound_Special_Zak71(uint16 offset, uint16 size) :
- _offset(offset), _size(size) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
-
- _freq1 = 0x00C8;
- _freq2 = 0x0190;
- _freq3 = 0x0320;
- _freq4 = 0x0640;
- _vol = 0x78;
-
- char *tmp_data1 = (char *)malloc(_size);
- char *tmp_data2 = (char *)malloc(_size);
- char *tmp_data3 = (char *)malloc(_size);
- char *tmp_data4 = (char *)malloc(_size);
- memcpy(tmp_data1, data + _offset, _size);
- memcpy(tmp_data2, data + _offset, _size);
- memcpy(tmp_data3, data + _offset, _size);
- memcpy(tmp_data4, data + _offset, _size);
- _mod->startChannel(_id | 0x000, tmp_data1, _size, BASE_FREQUENCY / _freq1, MIN((_vol >> 1) + 3,0x32), 0, _size, -127);
- _mod->startChannel(_id | 0x100, tmp_data2, _size, BASE_FREQUENCY / _freq2, MIN((_vol >> 1) + 3,0x32), 0, _size, 127);
- _mod->startChannel(_id | 0x200, tmp_data3, _size, BASE_FREQUENCY / _freq3, MIN((_vol >> 1) + 3,0x32), 0, _size, 127);
- _mod->startChannel(_id | 0x300, tmp_data4, _size, BASE_FREQUENCY / _freq4, MIN((_vol >> 1) + 3,0x32), 0, _size, -127);
- }
- virtual bool update() {
- assert(_id);
- _freq1 += 0x14;
- _freq2 += 0x1E;
- _freq3 += 0x32;
- _freq4 += 0x50;
- _mod->setChannelFreq(_id | 0x000, BASE_FREQUENCY / _freq1);
- _mod->setChannelFreq(_id | 0x100, BASE_FREQUENCY / _freq2);
- _mod->setChannelFreq(_id | 0x200, BASE_FREQUENCY / _freq3);
- _mod->setChannelFreq(_id | 0x300, BASE_FREQUENCY / _freq4);
- _vol--;
- if (_vol == 0)
- return false;
- _mod->setChannelVol(_id | 0x000, MIN((_vol >> 1) + 3,0x32));
- _mod->setChannelVol(_id | 0x100, MIN((_vol >> 1) + 3,0x32));
- _mod->setChannelVol(_id | 0x200, MIN((_vol >> 1) + 3,0x32));
- _mod->setChannelVol(_id | 0x300, MIN((_vol >> 1) + 3,0x32));
- return true;
- }
-private:
- const uint16 _offset;
- const uint16 _size;
-
- uint16 _freq1;
- uint16 _freq2;
- uint16 _freq3;
- uint16 _freq4;
- uint8 _vol;
-};
-
-// plays a single looped waveform, bending the frequency upward at a varying rate
-// used in Zak for the tram on Mars (?)
-class V2A_Sound_Special_ZakTram : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_ZakTram(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint8 vol) :
- V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2), _vol(vol) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- char *tmp_data = (char *)malloc(_size);
- memcpy(tmp_data, data + _offset, _size);
- _curfreq = _freq1;
- _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, (_vol << 2) | (_vol >> 4), 0, _size);
- _bendrate = 8;
- _bendctr = 100;
- _holdctr = 30;
- }
- virtual bool update() {
- assert(_id);
- if (_curfreq >= _freq2)
- {
- _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq);
- _curfreq -= _bendrate;
- if (--_bendctr)
- return true;
- _bendrate--;
- if (_bendrate < 2)
- _bendrate = 2;
- }
- else
- {
- if (!--_holdctr)
- return false;
- }
- return true;
- }
-private:
- const uint16 _freq1;
- const uint16 _freq2;
- const uint16 _vol;
-
- uint16 _curfreq;
- uint16 _bendrate;
- uint16 _bendctr;
- uint16 _holdctr;
-};
-
-// plays one waveform, then switches to a different looped waveform and slowly fades volume to zero
-// used for some odd sound effect
-class V2A_Sound_Special_Zak54 : public V2A_Sound_Base<1> {
-public:
- V2A_Sound_Special_Zak54(uint16 offset1, uint16 size1, uint16 offset2, uint16 size2, uint16 freq) :
- _offset1(offset1), _size1(size1), _offset2(offset2), _size2(size2), _freq(freq) { }
- virtual void start(Player_MOD *mod, int id, const byte *data) {
- _mod = mod;
- _id = id;
- _data = (char *)malloc(READ_LE_UINT16(data));
- memcpy(_data, data, READ_LE_UINT16(data));
- char *tmp_data = (char *)malloc(_size1);
- memcpy(tmp_data, data + _offset1, _size1);
- _vol = 0xFC;
- _mod->startChannel(_id, tmp_data, _size1, BASE_FREQUENCY / _freq, _vol, 0, _size1);
- _loop = _size1 * _freq * 60 / BASE_FREQUENCY;
- }
- virtual bool update() {
- assert(_id);
- if (!_loop)
- {
- _vol--;
- if (_vol)
- _mod->setChannelVol(_id, _vol);
- else return false;
- }
- else if (!--_loop)
- {
- _mod->stopChannel(_id);
- char *tmp_data = (char *)malloc(_size2);
- memcpy(tmp_data, _data + _offset2, _size2);
- _mod->startChannel(_id, tmp_data, _size2, BASE_FREQUENCY / _freq, _vol, 0, _size2);
- }
- return true;
- }
-
-private:
- const uint16 _offset1;
- const uint16 _offset2;
- const uint16 _size1;
- const uint16 _size2;
- const uint16 _freq;
-
- int _vol;
- int _loop;
-};
-
-#define CRCToSound(CRC, SOUND) \
- if (crc == CRC) \
- return new SOUND
-
-static V2A_Sound *findSound (unsigned long crc) {
- CRCToSound(0x8FAB08C4, V2A_Sound_SingleLooped(0x006C,0x2B58,0x016E,0x3F)); // Maniac 17
- CRCToSound(0xB673160A, V2A_Sound_SingleLooped(0x006C,0x1E78,0x01C2,0x1E)); // Maniac 38
- CRCToSound(0x4DB1D0B2, V2A_Sound_MultiLooped(0x0072,0x1BC8,0x023D,0x3F,0x0224,0x3F)); // Maniac 20
- CRCToSound(0x754D75EF, V2A_Sound_Single(0x0076,0x0738,0x01FC,0x3F)); // Maniac 10
- CRCToSound(0x6E3454AF, V2A_Sound_Single(0x0076,0x050A,0x017C,0x3F)); // Maniac 12
- CRCToSound(0x92F0BBB6, V2A_Sound_Single(0x0076,0x3288,0x012E,0x3F)); // Maniac 41
- CRCToSound(0xE1B13982, V2A_Sound_MultiLoopedDuration(0x0078,0x0040,0x007C,0x3F,0x007B,0x3F,0x001E)); // Maniac 21
- CRCToSound(0x288B16CF, V2A_Sound_MultiLoopedDuration(0x007A,0x0040,0x007C,0x3F,0x007B,0x3F,0x000A)); // Maniac 11
- CRCToSound(0xA7565268, V2A_Sound_MultiLoopedDuration(0x007A,0x0040,0x00F8,0x3F,0x00F7,0x3F,0x000A)); // Maniac 19
- CRCToSound(0x7D419BFC, V2A_Sound_MultiLoopedDuration(0x007E,0x0040,0x012C,0x3F,0x0149,0x3F,0x001E)); // Maniac 22
- CRCToSound(0x1B52280C, V2A_Sound_Single(0x0098,0x0A58,0x007F,0x32)); // Maniac 6
- CRCToSound(0x38D4A810, V2A_Sound_Single(0x0098,0x2F3C,0x0258,0x32)); // Maniac 7
- CRCToSound(0x09F98FC2, V2A_Sound_Single(0x0098,0x0A56,0x012C,0x32)); // Maniac 16
- CRCToSound(0x90440A65, V2A_Sound_Single(0x0098,0x0208,0x0078,0x28)); // Maniac 28
- CRCToSound(0x985C76EF, V2A_Sound_Single(0x0098,0x0D6E,0x00C8,0x32)); // Maniac 30
- CRCToSound(0x76156137, V2A_Sound_Single(0x0098,0x2610,0x017C,0x39)); // Maniac 39
- CRCToSound(0x5D95F88C, V2A_Sound_Single(0x0098,0x0A58,0x007F,0x1E)); // Maniac 65
- CRCToSound(0x92D704EA, V2A_Sound_SingleLooped(0x009C,0x29BC,0x012C,0x3F,0x1BD4,0x0DE8)); // Maniac 15
- CRCToSound(0x92F5513C, V2A_Sound_Single(0x009E,0x0DD4,0x01F4,0x3F)); // Maniac 13
- CRCToSound(0xCC2F3B5A, V2A_Sound_Single(0x009E,0x00DE,0x01AC,0x3F)); // Maniac 43
- CRCToSound(0x153207D3, V2A_Sound_Single(0x009E,0x0E06,0x02A8,0x3F)); // Maniac 67
- CRCToSound(0xC4F370CE, V2A_Sound_Single(0x00AE,0x0330,0x01AC,0x3F)); // Maniac 8
- CRCToSound(0x928C4BAC, V2A_Sound_Single(0x00AE,0x08D6,0x01AC,0x3F)); // Maniac 9
- CRCToSound(0x62D5B11F, V2A_Sound_Single(0x00AE,0x165C,0x01CB,0x3F)); // Maniac 27
- CRCToSound(0x3AB22CB5, V2A_Sound_Single(0x00AE,0x294E,0x012A,0x3F)); // Maniac 62
- CRCToSound(0x2D70BBE9, V2A_Sound_SingleLoopedPitchbend(0x00B4,0x1702,0x03E8,0x0190,0x3F,5)); // Maniac 64
- CRCToSound(0xFA4C1B1C, V2A_Sound_Special_ManiacNuclear(0x00B2,0x1702,0x0190,0x3F)); // Maniac 69
- CRCToSound(0x19D50D67, V2A_Sound_Special_ManiacDing(0x00B6,0x0020,0x00C8,16,2)); // Maniac 14
- CRCToSound(0x3E6FBE15, V2A_Sound_Special_ManiacTentacle(0x00B2,0x0010,0x007C,0x016D,1)); // Maniac 25
- CRCToSound(0x5305753C, V2A_Sound_Special_ManiacTentacle(0x00B2,0x0010,0x007C,0x016D,7)); // Maniac 36
- CRCToSound(0x28895106, V2A_Sound_Special_ManiacElectric(0x00C0,0x00FE,0x00E9,0x0111,4,0x0A)); // Maniac 59
- CRCToSound(0xB641ACF6, V2A_Sound_Special_Maniac61(0x00C8,0x0100,0x00C8,0x01C2)); // Maniac 61
- CRCToSound(0xE1A91583, V2A_Sound_Special_ManiacPhone(0x00D0,0x0040,0x007C,0x3F,0x007B,0x3F,0x3C,5,6)); // Maniac 23
- CRCToSound(0x64816ED5, V2A_Sound_Special_ManiacPhone(0x00D0,0x0040,0x00BE,0x37,0x00BD,0x37,0x3C,5,6)); // Maniac 24
- CRCToSound(0x639D72C2, V2A_Sound_Special_ManiacWrench(0x00D0,0x10A4,0x0080,0x3F,0x28,3)); // Maniac 46
- CRCToSound(0xE8826D92, V2A_Sound_Special_ManiacTypewriter(0x00EC,0x025A,0x023C,0x3F,8,(const uint8 *)"\x20\x41\x04\x21\x08\x10\x13\x07", true)); // Maniac 45
- CRCToSound(0xEDFF3D41, V2A_Sound_Single(0x00F8,0x2ADE,0x01F8,0x3F)); // Maniac 42 (this should echo, but it's barely noticeable and I don't feel like doing it)
- CRCToSound(0x15606D06, V2A_Sound_Special_ManiacSiren(0x0148,0x0020,0x0168,0x0020,0x3F)); // Maniac 32
- CRCToSound(0x753EAFE3, V2A_Sound_Special_Maniac44(0x017C,0x0010,0x018C,0x0020,0x00C8,0x0080,0x3F)); // Maniac 44
- CRCToSound(0xB1AB065C, V2A_Sound_Music(0x0032,0x00B2,0x08B2,0x1222,0x1A52,0x23C2,0x3074,false)); // Maniac 50
- CRCToSound(0x091F5D9C, V2A_Sound_Music(0x0032,0x0132,0x0932,0x1802,0x23D2,0x3EA2,0x4F04,false)); // Maniac 58
-
- CRCToSound(0x8E2C8AB3, V2A_Sound_SingleLooped(0x005C,0x0F26,0x0168,0x3C)); // Zak 41
- CRCToSound(0x3792071F, V2A_Sound_SingleLooped(0x0060,0x1A18,0x06A4,0x3F)); // Zak 88
- CRCToSound(0xF192EDE9, V2A_Sound_SingleLooped(0x0062,0x0054,0x01FC,0x1E)); // Zak 68
- CRCToSound(0xC43B0245, V2A_Sound_Special_Zak70(0x006C,0x166E,0x00C8,0x0190,0x0320,0x0640,0x32)); // Zak 70
- CRCToSound(0xCEB51670, V2A_Sound_SingleLooped(0x00AC,0x26DC,0x012C,0x3F)); // Zak 42
- CRCToSound(0x10347B51, V2A_Sound_SingleLooped(0x006C,0x00E0,0x0594,0x3F)); // Zak 18
- CRCToSound(0x9D2FADC0, V2A_Sound_MultiLooped(0x0072,0x1FC8,0x016A,0x3F,0x01CE,0x3F)); // Zak 80
- CRCToSound(0xFAD2C676, V2A_Sound_MultiLooped(0x0076,0x0010,0x0080,0x3F,0x0090,0x3B)); // Zak 40
- CRCToSound(0x01508B48, V2A_Sound_Single(0x0076,0x0D8C,0x017C,0x3F)); // Zak 90
- CRCToSound(0x9C18DC46, V2A_Sound_Single(0x0076,0x0D8C,0x015E,0x3F)); // Zak 91
- CRCToSound(0xF98F7EAC, V2A_Sound_Single(0x0076,0x0D8C,0x0140,0x3F)); // Zak 92
- CRCToSound(0xC925FBEF, V2A_Sound_MultiLoopedDuration(0x0080,0x0010,0x0080,0x3F,0x0090,0x3B,0x0168)); // Zak 53
- CRCToSound(0xCAB35257, V2A_Sound_Special_Zak101(0x00DA,0x425C,0x023C,0x08F0,0x0640,0x0478,0x3F,0x012C)); // Zak 101
- CRCToSound(0xA31FE4FD, V2A_Sound_Single(0x0094,0x036A,0x00E1,0x3F)); // Zak 97
- CRCToSound(0x0A1AE0F5, V2A_Sound_Single(0x009E,0x0876,0x0168,0x3F)); // Zak 5
- CRCToSound(0xD01A66CB, V2A_Sound_Single(0x009E,0x04A8,0x0168,0x3F)); // Zak 47
- CRCToSound(0x5497B912, V2A_Sound_Single(0x009E,0x0198,0x01F4,0x3F)); // Zak 39
- CRCToSound(0x2B50362F, V2A_Sound_Single(0x009E,0x09B6,0x023D,0x3F)); // Zak 67
- CRCToSound(0x7BFB6E72, V2A_Sound_Single(0x009E,0x0D14,0x0078,0x3F)); // Zak 69
- CRCToSound(0xB803A792, V2A_Sound_Single(0x009E,0x2302,0x02BC,0x3F)); // Zak 78
- CRCToSound(0x7AB82E39, V2A_Sound_SingleLooped(0x00A0,0x2A3C,0x016E,0x3F,0x1018,0x1A24)); // Zak 100
- CRCToSound(0x28057CEC, V2A_Sound_Single(0x0098,0x0FEC,0x0140,0x32)); // Zak 63
- CRCToSound(0x1180A2FC, V2A_Sound_Single(0x0098,0x0F06,0x0190,0x32)); // Zak 64
- CRCToSound(0x12616755, V2A_Sound_Single(0x0098,0x14C8,0x023C,0x14)); // Zak 9
- CRCToSound(0x642723AA, V2A_Sound_Special_Zak37(0x00A2,0x1702,0x01F4,0x3F)); // Zak 37
- CRCToSound(0xDEE56848, V2A_Sound_Single(0x009A,0x0F86,0x0100,0x3F)); // Zak 93
- CRCToSound(0xF9BE27B8, V2A_Sound_Special_Zak37(0x011C,0x1704,0x0228,0x3F)); // Zak 113
- CRCToSound(0xC73487B2, V2A_Sound_Single(0x00B0,0x18BA,0x0478,0x3F)); // Zak 81
- CRCToSound(0x32D8F925, V2A_Sound_Single(0x00B0,0x2E46,0x00F0,0x3F)); // Zak 94
- CRCToSound(0x988C83A5, V2A_Sound_Single(0x00B0,0x0DE0,0x025B,0x3F)); // Zak 106
- CRCToSound(0x8F1E3B3D, V2A_Sound_Single(0x00B0,0x05FE,0x04E2,0x3F)); // Zak 107
- CRCToSound(0x0A2A7646, V2A_Sound_Single(0x00B0,0x36FE,0x016E,0x3F)); // Zak 43
- CRCToSound(0x6F1FC435, V2A_Sound_Single(0x00B0,0x2808,0x044C,0x3F)); // Zak 108
- CRCToSound(0x870EFC29, V2A_Sound_SingleLoopedPitchbend(0x00BA,0x0100,0x03E8,0x00C8,0x3F,3)); // Zak 55
- CRCToSound(0xED773699, V2A_Sound_Special_ManiacDing(0x00B4,0x0020,0x012C,8,4)); // Zak 3
- CRCToSound(0x0BF59774, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00F8,0x00F7,8,1)); // Zak 72
- CRCToSound(0x656FFEDE, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00C4,0x00C3,8,1)); // Zak 73
- CRCToSound(0xFC4D41E5, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x00A5,0x00A4,8,1)); // Zak 74
- CRCToSound(0xC0DD2089, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x009C,0x009B,8,1)); // Zak 75
- CRCToSound(0x627DFD92, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x008B,0x008A,8,1)); // Zak 76
- CRCToSound(0x703E05C1, V2A_Sound_Special_ZakStereoDing(0x00BE,0x0020,0x007C,0x007B,8,1)); // Zak 77
- CRCToSound(0xB0F77006, V2A_Sound_Unsupported()); // Zak 52
- CRCToSound(0x5AE9D6A7, V2A_Sound_Special_ZakAirplane(0x00CA,0x22A4,0x0113,0x0227)); // Zak 109
- CRCToSound(0xABE0D3B0, V2A_Sound_Special_ZakAirplane(0x00CE,0x22A4,0x0227,0x0113)); // Zak 105
- CRCToSound(0x788CC749, V2A_Sound_Special_Zak71(0x00C8,0x0B37)); // Zak 71
- CRCToSound(0x2E2AB1FA, V2A_Sound_Special_ZakTram(0x00D4,0x04F0,0x0FE3,0x0080,0x3F)); // Zak 99
- CRCToSound(0x1304CF20, V2A_Sound_Special_ManiacTypewriter(0x00DC,0x0624,0x023C,0x3C,2,(const uint8 *)"\x14\x11",false)); // Zak 79
- CRCToSound(0xAE68ED91, V2A_Sound_Special_Zak54(0x00D4,0x1A25,0x1E1E,0x0B80,0x01F4)); // Zak 54
- CRCToSound(0xA4F40F97, V2A_Sound_Unsupported()); // Zak 61
- CRCToSound(0x348F85CE, V2A_Sound_Unsupported()); // Zak 62
- CRCToSound(0xD473AB86, V2A_Sound_Special_ManiacTypewriter(0x0122,0x03E8,0x00BE,0x3F,7,(const uint8 *)"\x0F\x0B\x04\x0F\x1E\x0F\x66",false)); // Zak 46
- CRCToSound(0x84A0BA90, V2A_Sound_Unsupported()); // Zak 110
- CRCToSound(0x92680D9F, V2A_Sound_Unsupported()); // Zak 32
- CRCToSound(0xABFFDB02, V2A_Sound_Unsupported()); // Zak 86
- CRCToSound(0x41045447, V2A_Sound_Unsupported()); // Zak 98
- CRCToSound(0xC8EEBD34, V2A_Sound_Unsupported()); // Zak 82
- CRCToSound(0x42F9469F, V2A_Sound_Music(0x05F6,0x0636,0x0456,0x0516,0x05D6,0x05E6,0x0A36,true)); // Zak 96
- CRCToSound(0x038BBD78, V2A_Sound_Music(0x054E,0x05CE,0x044E,0x04BE,0x052E,0x053E,0x0BCE,true)); // Zak 85
- CRCToSound(0x06FFADC5, V2A_Sound_Music(0x0626,0x0686,0x0446,0x04F6,0x0606,0x0616,0x0C86,true)); // Zak 87
- CRCToSound(0xCE20ECF0, V2A_Sound_Music(0x0636,0x0696,0x0446,0x0576,0x0616,0x0626,0x0E96,true)); // Zak 114
- CRCToSound(0xBDA01BB6, V2A_Sound_Music(0x0678,0x06B8,0x0458,0x0648,0x0658,0x0668,0x0EB8,false)); // Zak 33
- CRCToSound(0x59976529, V2A_Sound_Music(0x088E,0x092E,0x048E,0x05EE,0x074E,0x07EE,0x112E,true)); // Zak 49
- CRCToSound(0xED1EED02, V2A_Sound_Music(0x08D0,0x0950,0x0440,0x07E0,0x08B0,0x08C0,0x1350,false)); // Zak 112
- CRCToSound(0x5A16C037, V2A_Sound_Music(0x634A,0x64CA,0x049A,0x18FA,0x398A,0x511A,0x6CCA,false)); // Zak 95
- return NULL;
-}
-
-Player_V2A::Player_V2A(ScummEngine *scumm) {
- int i;
- _vm = scumm;
-
-#ifdef PALMOS_68K
- if (!CRCtable) CRCtable = (uint32 *)calloc(256, sizeof(uint32));
-#endif
- InitCRC();
-
- for (i = 0; i < V2A_MAXSLOTS; i++) {
- _slot[i].id = 0;
- _slot[i].sound = NULL;
- }
-
- _mod = new Player_MOD(scumm);
- _mod->setUpdateProc(update_proc, this, 60);
-}
-
-Player_V2A::~Player_V2A() {
- delete _mod;
-#ifdef PALMOS_68K
- free(CRCtable);
-#endif
-}
-
-void Player_V2A::setMusicVolume (int vol) {
- _mod->setMusicVolume(vol);
-}
-
-int Player_V2A::getSoundSlot (int id) const {
- int i;
- for (i = 0; i < V2A_MAXSLOTS; i++) {
- if (_slot[i].id == id)
- break;
- }
- if (i == V2A_MAXSLOTS) {
- if (id == 0)
- warning("player_v2a - out of sound slots");
- return -1;
- }
- return i;
-}
-
-void Player_V2A::stopAllSounds() {
- for (int i = 0; i < V2A_MAXSLOTS; i++) {
- if (!_slot[i].id)
- continue;
- _slot[i].sound->stop();
- delete _slot[i].sound;
- _slot[i].sound = NULL;
- _slot[i].id = 0;
- }
-}
-
-void Player_V2A::stopSound(int nr) {
- int i;
- if (nr == 0)
- return;
- i = getSoundSlot(nr);
- if (i == -1)
- return;
- _slot[i].sound->stop();
- delete _slot[i].sound;
- _slot[i].sound = NULL;
- _slot[i].id = 0;
-}
-
-void Player_V2A::startSound(int nr) {
- assert(_vm);
- byte *data = _vm->getResourceAddress(rtSound, nr);
- assert(data);
- uint32 crc = GetCRC(data + 0x0A, READ_BE_UINT16(data + 0x08));
- V2A_Sound *snd = findSound(crc);
- if (snd == NULL) {
- warning("player_v2a - sound %i not recognized yet (crc %08X)",nr,crc);
- return;
- }
- stopSound(nr);
- int i = getSoundSlot();
- if (i == -1)
- return;
- _slot[i].id = nr;
- _slot[i].sound = snd;
- _slot[i].sound->start(_mod,nr,data);
-}
-
-void Player_V2A::update_proc(void *param) {
- ((Player_V2A *)param)->updateSound();
-}
-
-void Player_V2A::updateSound() {
- int i;
- for (i = 0; i < V2A_MAXSLOTS; i++) {
- if ((_slot[i].id) && (!_slot[i].sound->update())) {
- _slot[i].sound->stop();
- delete _slot[i].sound;
- _slot[i].sound = NULL;
- _slot[i].id = 0;
- }
- }
-}
-
-int Player_V2A::getMusicTimer() const {
- return 0; // FIXME - need to keep track of playing music resources
-}
-
-int Player_V2A::getSoundStatus(int nr) const {
- for (int i = 0; i < V2A_MAXSLOTS; i++) {
- if (_slot[i].id == nr)
- return 1;
- }
- return 0;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/player_v2a.h b/scumm/player_v2a.h
deleted file mode 100644
index b2d25d67d5..0000000000
--- a/scumm/player_v2a.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PLAYER_V2A_H
-#define PLAYER_V2A_H
-
-#include "common/scummsys.h"
-#include "scumm/music.h"
-#include "scumm/player_mod.h"
-
-class Mixer;
-
-namespace Scumm {
-
-class ScummEngine;
-class V2A_Sound;
-
-/**
- * Scumm V2 Amiga sound/music driver.
- */
-class Player_V2A : public MusicEngine {
-public:
- Player_V2A(ScummEngine *scumm);
- virtual ~Player_V2A();
-
- virtual void setMusicVolume(int vol);
- virtual void startSound(int sound);
- virtual void stopSound(int sound);
- virtual void stopAllSounds();
- virtual int getMusicTimer() const;
- virtual int getSoundStatus(int sound) const;
-
-private:
- enum {
- V2A_MAXSLOTS = 8
- };
-
- struct soundSlot {
- int id;
- V2A_Sound *sound;
- };
-
- ScummEngine *_vm;
- Player_MOD *_mod;
- soundSlot _slot[V2A_MAXSLOTS];
-
- int getSoundSlot (int id = 0) const;
- static void update_proc(void *param);
- void updateSound();
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/player_v3a.cpp b/scumm/player_v3a.cpp
deleted file mode 100644
index 32ab9754af..0000000000
--- a/scumm/player_v3a.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "base/engine.h"
-#include "scumm/player_v3a.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-static const uint16 note_freqs[4][12] = {
- {0x06B0, 0x0650, 0x05F4, 0x05A0, 0x054C, 0x0500, 0x04B8, 0x0474, 0x0434, 0x03F8, 0x03C0, 0x0388},
- {0x0358, 0x0328, 0x02FA, 0x02D0, 0x02A6, 0x0280, 0x025C, 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C4},
- {0x01AC, 0x0194, 0x017D, 0x0168, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D, 0x00FE, 0x00F0, 0x00E2},
- {0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00A9, 0x00A0, 0x0097, 0x008E, 0x0086, 0x007F, 0x00F0, 0x00E2}
-};
-
-Player_V3A::Player_V3A(ScummEngine *scumm) {
- int i;
- _vm = scumm;
- for (i = 0; i < V3A_MAXMUS; i++) {
- _mus[i].id = 0;
- _mus[i].dur = 0;
- }
- for (i = 0; i < V3A_MAXSFX; i++) {
- _sfx[i].id = 0;
- _sfx[i].dur = 0;
- }
-
- _curSong = 0;
- _songData = NULL;
- _songPtr = 0;
- _songDelay = 0;
-
- _music_timer = 0;
-
- _isinit = false;
-
- _mod = new Player_MOD(scumm);
- _mod->setUpdateProc(update_proc, this, 60);
-}
-
-Player_V3A::~Player_V3A() {
- int i;
- delete _mod;
- if (_isinit) {
- for (i = 0; _wavetable[i] != NULL; i++) {
- for (int j = 0; j < 6; j++) {
- free(_wavetable[i]->_idat[j]);
- free(_wavetable[i]->_ldat[j]);
- }
- free(_wavetable[i]);
- }
- free(_wavetable);
- }
-}
-
-void Player_V3A::setMusicVolume (int vol) {
- _mod->setMusicVolume(vol);
-}
-
-int Player_V3A::getMusChan (int id) const {
- int i;
- for (i = 0; i < V3A_MAXMUS; i++) {
- if (_mus[i].id == id)
- break;
- }
- if (i == V3A_MAXMUS) {
- if (id == 0)
- warning("player_v3a - out of music channels");
- return -1;
- }
- return i;
-}
-int Player_V3A::getSfxChan (int id) const {
- int i;
- for (i = 0; i < V3A_MAXSFX; i++) {
- if (_sfx[i].id == id)
- break;
- }
- if (i == V3A_MAXSFX) {
- if (id == 0)
- warning("player_v3a - out of sfx channels");
- return -1;
- }
- return i;
-}
-
-void Player_V3A::stopAllSounds() {
- int i;
- for (i = 0; i < V3A_MAXMUS; i++) {
- if (_mus[i].id)
- _mod->stopChannel(_mus[i].id);
- _mus[i].id = 0;
- _mus[i].dur = 0;
- }
- _curSong = 0;
- _songPtr = 0;
- _songDelay = 0;
- _songData = NULL;
- for (i = 0; i < V3A_MAXSFX; i++) {
- if (_sfx[i].id)
- _mod->stopChannel(_sfx[i].id | 0x100);
- _sfx[i].id = 0;
- _sfx[i].dur = 0;
- }
-}
-
-void Player_V3A::stopSound(int nr) {
- int i;
- if (nr == 0) { // Amiga Loom does this near the end, when Chaos casts SILENCE on Hetchel
- stopAllSounds();
- return;
- }
- if (nr == _curSong) {
- for (i = 0; i < V3A_MAXMUS; i++) {
- if (_mus[i].id)
- _mod->stopChannel(_mus[i].id);
- _mus[i].id = 0;
- _mus[i].dur = 0;
- }
- _curSong = 0;
- _songPtr = 0;
- _songDelay = 0;
- _songData = NULL;
- } else {
- i = getSfxChan(nr);
- if (i != -1) {
- _mod->stopChannel(nr | 0x100);
- _sfx[i].id = 0;
- _sfx[i].dur = 0;
- }
- }
-}
-
-void Player_V3A::startSound(int nr) {
- assert(_vm);
- byte *data = _vm->getResourceAddress(rtSound, nr);
- assert(data);
-
- if ((_vm->_gameId != GID_INDY3) && (_vm->_gameId != GID_LOOM))
- error("player_v3a - unknown game!");
-
- if (!_isinit) {
- int i;
- unsigned char *ptr;
- int offset = 4;
- int numInstruments;
-
- if (_vm->_gameId == GID_INDY3) {
- ptr = _vm->getResourceAddress(rtSound, 83);
- numInstruments = 12;
- } else {
- ptr = _vm->getResourceAddress(rtSound, 79);
- numInstruments = 9;
- }
- assert(ptr);
- _wavetable = (instData **)malloc((numInstruments + 1) * sizeof(void *));
- for (i = 0; i < numInstruments; i++) {
- _wavetable[i] = (instData *)malloc(sizeof(instData));
- for (int j = 0; j < 6; j++) {
- int off, len;
- off = READ_BE_UINT16(ptr + offset + 0);
- _wavetable[i]->_ilen[j] = len = READ_BE_UINT16(ptr + offset + 2);
- if (len) {
- _wavetable[i]->_idat[j] = (char *)malloc(len);
- memcpy(_wavetable[i]->_idat[j],ptr + off,len);
- } else _wavetable[i]->_idat[j] = NULL;
- off = READ_BE_UINT16(ptr + offset + 4);
- _wavetable[i]->_llen[j] = len = READ_BE_UINT16(ptr + offset + 6);
- if (len) {
- _wavetable[i]->_ldat[j] = (char *)malloc(len);
- memcpy(_wavetable[i]->_ldat[j],ptr + off,len);
- } else _wavetable[i]->_ldat[j] = NULL;
- _wavetable[i]->_oct[j] = READ_BE_UINT16(ptr + offset + 8);
- offset += 10;
- }
- if (_vm->_gameId == GID_INDY3) {
- _wavetable[i]->_pitadjust = 0;
- offset += 2;
- } else {
- _wavetable[i]->_pitadjust = READ_BE_UINT16(ptr + offset + 2);
- offset += 4;
- }
- }
- _wavetable[i] = NULL;
- _isinit = true;
- }
-
- if (getSoundStatus(nr))
- stopSound(nr); // if a sound is playing, restart it
-
- if (data[26]) {
- if (_curSong)
- stopSound(_curSong);
- _curSong = nr;
- _songData = data;
- _songPtr = 0x1C;
- _songDelay = 1;
- _music_timer = 0;
- } else {
- int size = READ_BE_UINT16(data + 12);
- int rate = 3579545 / READ_BE_UINT16(data + 20);
- char *sound = (char *)malloc(size);
- int vol = (data[24] << 1) | (data[24] >> 5); // if I boost this to 0-255, it gets too loud and starts to clip
- memcpy(sound,data + READ_BE_UINT16(data + 8),size);
- int loopStart = 0, loopEnd = 0;
- bool looped = false;
- if ((READ_BE_UINT16(data + 16) || READ_BE_UINT16(data + 6))) {
- loopStart = READ_BE_UINT16(data + 10) - READ_BE_UINT16(data + 8);
- loopEnd = READ_BE_UINT16(data + 14);
- looped = true;
- }
- int i = getSfxChan();
- if (i == -1)
- {
- free(sound);
- return;
- }
- _sfx[i].id = nr;
- _sfx[i].dur = looped ? -1 : (1 + 60 * size / rate);
- if ((_vm->_gameId == GID_INDY3) && (nr == 60))
- _sfx[i].dur = 240;
- _mod->startChannel(nr | 0x100, sound, size, rate, vol, loopStart, loopEnd);
- }
-}
-
-void Player_V3A::update_proc(void *param) {
- ((Player_V3A *)param)->playMusic();
-}
-
-void Player_V3A::playMusic() {
- int i;
- for (i = 0; i < V3A_MAXMUS; i++) {
- if (_mus[i].id) {
- _mus[i].dur--;
- if (_mus[i].dur)
- continue;
- _mod->stopChannel(_mus[i].id);
- _mus[i].id = 0;
- }
- }
- for (i = 0; i < V3A_MAXSFX; i++) {
- if (_sfx[i].id) {
- _sfx[i].dur--;
- if (_sfx[i].dur)
- continue;
- _mod->stopChannel(_sfx[i].id | 0x100);
- _sfx[i].id = 0;
- }
- }
-
- _music_timer++;
- if (!_curSong)
- return;
- if (_songDelay && --_songDelay)
- return;
- if (_songPtr == 0) {
- // at the end of the song, and it wasn't looped - kill it
- _curSong = 0;
- return;
- }
- while (1) {
- int inst, pit, vol, dur, oct;
- inst = _songData[_songPtr++];
- if ((inst & 0xF0) != 0x80) {
- // tune is at the end - figure out what's still playing
- // and see how long we have to wait until we stop/restart
- for (i = 0; i < V3A_MAXMUS; i++) {
- if (_songDelay < _mus[i].dur)
- _songDelay = _mus[i].dur;
- }
- if (inst == 0xFB) // it's a looped song, restart it afterwards
- _songPtr = 0x1C;
- else _songPtr = 0; // otherwise, terminate it
- break;
- }
- inst &= 0xF;
- pit = _songData[_songPtr++];
- vol = _songData[_songPtr++] & 0x7F; // if I boost this to 0-255, it gets too loud and starts to clip
- dur = _songData[_songPtr++];
- if (pit == 0) {
- _songDelay = dur;
- break;
- }
- pit += _wavetable[inst]->_pitadjust;
- oct = (pit / 12) - 2;
- pit = pit % 12;
- if (oct < 0)
- oct = 0;
- if (oct > 5)
- oct = 5;
- int rate = 3579545 / note_freqs[_wavetable[inst]->_oct[oct]][pit];
- if (!_wavetable[inst]->_llen[oct])
- dur = _wavetable[inst]->_ilen[oct] * 60 / rate;
- char *data = (char *)malloc(_wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct]);
- if (_wavetable[inst]->_idat[oct])
- memcpy(data, _wavetable[inst]->_idat[oct], _wavetable[inst]->_ilen[oct]);
- if (_wavetable[inst]->_ldat[oct])
- memcpy(data + _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ldat[oct], _wavetable[inst]->_llen[oct]);
-
- i = getMusChan();
- if (i == -1)
- {
- free(data);
- return;
- }
- _mus[i].id = i + 1;
- _mus[i].dur = dur + 1;
- _mod->startChannel(_mus[i].id, data, _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct], rate, vol,
- _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct]);
- }
-}
-
-int Player_V3A::getMusicTimer() const {
- return _music_timer / 30;
-}
-
-int Player_V3A::getSoundStatus(int nr) const {
- if (nr == _curSong)
- return 1;
- if (getSfxChan(nr) != -1)
- return 1;
- return 0;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/player_v3a.h b/scumm/player_v3a.h
deleted file mode 100644
index 351d8ece60..0000000000
--- a/scumm/player_v3a.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef PLAYER_V3A_H
-#define PLAYER_V3A_H
-
-#include "common/scummsys.h"
-#include "scumm/music.h"
-#include "scumm/player_mod.h"
-
-class Mixer;
-
-namespace Scumm {
-
-class ScummEngine;
-
-/**
- * Scumm V3 Amiga sound/music driver.
- */
-class Player_V3A : public MusicEngine {
-public:
- Player_V3A(ScummEngine *scumm);
- virtual ~Player_V3A();
-
- virtual void setMusicVolume(int vol);
- virtual void startSound(int sound);
- virtual void stopSound(int sound);
- virtual void stopAllSounds();
- virtual int getMusicTimer() const;
- virtual int getSoundStatus(int sound) const;
-
-private:
- enum {
- V3A_MAXMUS = 24,
- V3A_MAXSFX = 16
- };
-
- struct musChan {
- int id;
- int dur;
- };
-
- struct sfxChan {
- int id;
- int dur;
- // SFX will eventually have pitch bends
- };
-
- struct instData {
- char *_idat[6];
- uint16 _ilen[6];
- char *_ldat[6];
- uint16 _llen[6];
- uint16 _oct[6];
- int16 _pitadjust;
- };
-
- ScummEngine *_vm;
- Player_MOD *_mod;
-
- musChan _mus[V3A_MAXMUS];
- sfxChan _sfx[V3A_MAXSFX];
-
- int _curSong;
- uint8 *_songData;
- uint16 _songPtr;
- uint16 _songDelay;
- int _music_timer;
- bool _isinit;
-
- instData **_wavetable;
-
- int getMusChan (int id = 0) const;
- int getSfxChan (int id = 0) const;
- static void update_proc(void *param);
- void playMusic();
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
deleted file mode 100644
index e1601ca991..0000000000
--- a/scumm/resource.cpp
+++ /dev/null
@@ -1,1616 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/str.h"
-
-#include "scumm/charset.h"
-#include "scumm/dialogs.h"
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-enum {
- RF_LOCK = 0x80,
- RF_USAGE = 0x7F,
- RF_USAGE_MAX = RF_USAGE,
-
- RS_MODIFIED = 0x10
-};
-
-
-
-extern const char *resTypeFromId(int id);
-
-static uint16 newTag2Old(uint32 newTag);
-static const byte *findResourceSmall(uint32 tag, const byte *searchin);
-
-#ifndef DISABLE_HE
-static bool checkTryMedia(BaseScummFile *handle);
-#endif
-
-
-/* Open a room */
-void ScummEngine::openRoom(const int room) {
- int room_offs;
- bool result;
- char buf[128];
- char buf2[128] = "";
- byte encByte = 0;
-
- debugC(DEBUG_GENERAL, "openRoom(%d)", room);
- assert(room >= 0);
-
- /* Don't load the same room again */
- if (_lastLoadedRoom == room)
- return;
- _lastLoadedRoom = room;
-
- /* Room -1 means close file */
- if (room == -1) {
- deleteRoomOffsets();
- _fileHandle->close();
- return;
- }
-
- const int diskNumber = (room == 0 ? 0 : res.roomno[rtRoom][room]);
-
- /* Either xxx.lfl or monkey.xxx file name */
- while (1) {
- room_offs = room ? res.roomoffs[rtRoom][room] : 0;
-
- if (room_offs == -1)
- break;
-
- if (room_offs != 0 && room != 0 && _heversion < 98) {
- _fileOffset = res.roomoffs[rtRoom][room];
- return;
- }
- if (_version <= 3) {
- sprintf(buf, "%.2d.lfl", room);
- // Maniac Mansion demo has .man instead of .lfl
- if (_gameId == GID_MANIAC)
- sprintf(buf2, "%.2d.man", room);
- encByte = (_features & GF_USE_KEY) ? 0xFF : 0;
- } else if (_features & GF_SMALL_HEADER) {
- if (room == 0 || room >= 900) {
- sprintf(buf, "%.3d.lfl", room);
- encByte = 0;
- if (openResourceFile(buf, encByte)) {
- return;
- }
- askForDisk(buf, diskNumber);
-
- } else {
- sprintf(buf, "disk%.2d.lec", diskNumber);
- encByte = 0x69;
- }
- } else {
-
- if (_heversion >= 70) { // Windows titles
- if (_heversion >= 98) {
- int disk = 0;
- if (_heV7DiskOffsets)
- disk = _heV7DiskOffsets[room];
-
- switch(disk) {
- case 2:
- sprintf(buf, "%s.%s", _baseName.c_str(), "(b)");
- break;
- case 1:
- sprintf(buf, "%s.%s", _baseName.c_str(), "(a)");
- break;
- default:
- sprintf(buf, "%s.%s", _baseName.c_str(), "he0");
- }
- } else
- sprintf(buf, "%s.he%.1d", _baseName.c_str(), room == 0 ? 0 : 1);
- } else if (_version >= 7) {
- if (room > 0 && (_version == 8))
- VAR(VAR_CURRENTDISK) = diskNumber;
- sprintf(buf, "%s.la%d", _baseName.c_str(), diskNumber);
-
- sprintf(buf2, "%s.%.3d", _baseName.c_str(), diskNumber);
- } else if (_heversion >= 60) {
- sprintf(buf, "%s.he%.1d", _baseName.c_str(), diskNumber);
- } else {
- sprintf(buf, "%s.%.3d", _baseName.c_str(), diskNumber);
- if (_gameId == GID_SAMNMAX)
- sprintf(buf2, "%s.sm%.1d", _baseName.c_str(), diskNumber);
- }
-
- encByte = (_features & GF_USE_KEY) ? 0x69 : 0;
- }
-
- // If we have substitute
- if (_substResFileNameIndex > 0 && !(_platform == Common::kPlatformNES || _platform == Common::kPlatformC64)) {
- char tmpBuf[128];
- generateSubstResFileName(buf, tmpBuf, sizeof(tmpBuf));
- strcpy(buf, tmpBuf);
- if (buf2[0]) {
- generateSubstResFileName(buf2, tmpBuf, sizeof(tmpBuf));
- strcpy(buf2, tmpBuf);
- }
- }
-
- result = openResourceFile(buf, encByte);
- if ((result == false) && (buf2[0])) {
- result = openResourceFile(buf2, encByte);
- // We have .man files so set demo mode
- if (_gameId == GID_MANIAC)
- _demoMode = true;
- }
-
- if (result) {
- if (room == 0)
- return;
- deleteRoomOffsets();
- readRoomsOffsets();
- _fileOffset = res.roomoffs[rtRoom][room];
-
- if (_fileOffset != 8)
- return;
-
- error("Room %d not in %s", room, buf);
- return;
- }
- askForDisk(buf, diskNumber);
- }
-
- do {
- sprintf(buf, "%.3d.lfl", room);
- encByte = 0;
- if (openResourceFile(buf, encByte))
- break;
- askForDisk(buf, diskNumber);
- } while (1);
-
- deleteRoomOffsets();
- _fileOffset = 0; // start of file
-}
-
-void ScummEngine::closeRoom() {
- if (_lastLoadedRoom != -1) {
- _lastLoadedRoom = -1;
- deleteRoomOffsets();
- _fileHandle->close();
- }
-}
-
-/** Delete the currently loaded room offsets. */
-void ScummEngine::deleteRoomOffsets() {
- for (int i = 0; i < _numRooms; i++) {
- if (res.roomoffs[rtRoom][i] != 0xFFFFFFFF)
- res.roomoffs[rtRoom][i] = 0;
- }
-}
-
-/** Read room offsets */
-void ScummEngine::readRoomsOffsets() {
- int num, room;
-
- debug(9, "readRoomOffsets()");
-
- if (_features & GF_SMALL_HEADER) {
- _fileHandle->seek(12, SEEK_SET); // Directly searching for the room offset block would be more generic...
- } else {
- _fileHandle->seek(16, SEEK_SET);
- }
-
- num = _fileHandle->readByte();
- while (num--) {
- room = _fileHandle->readByte();
- if (res.roomoffs[rtRoom][room] != 0xFFFFFFFF) {
- res.roomoffs[rtRoom][room] = _fileHandle->readUint32LE();
- } else {
- _fileHandle->readUint32LE();
- }
- }
-}
-
-bool ScummEngine::openFile(BaseScummFile &file, const char *filename, bool resourceFile) {
- bool result = false;
-
- if (!_containerFile.isEmpty()) {
- char name[128];
-
- file.close();
- file.open(_containerFile.c_str());
- assert(file.isOpen());
-
- strncpy(name, filename, 128);
-
- // Some Mac demos (i.e. DOTT) have bundled file names different
- // from target name. dottdemo.000 vs tentacle.000. So we should
- // substitute those names too
- if (resourceFile == true) {
- if (_substResFileNameIndexBundle == 0) {
- int substLastIndex = 0;
-
- while (substLastIndex != -1) {
- if (file.openSubFile(name))
- break;
-
- substLastIndex = generateSubstResFileName(filename, name, sizeof(name), substLastIndex + 1);
- }
-
- if (substLastIndex == 0)
- substLastIndex = -1;
-
- _substResFileNameIndexBundle = substLastIndex;
-
- if (substLastIndex != -1)
- debug(5, "Generated substitute in Mac bundle: [%s -> %s]", filename, name);
- }
-
- if (_substResFileNameIndexBundle != -1)
- generateSubstResFileName(filename, name, sizeof(name), _substResFileNameIndexBundle);
- }
-
- result = file.openSubFile(name);
- }
-
- if (!result) {
- file.close();
- result = file.open(filename);
- }
-
- return result;
-}
-
-bool ScummEngine::openResourceFile(const char *filename, byte encByte) {
- debugC(DEBUG_GENERAL, "openResourceFile(%s)", filename);
-
- if (openFile(*_fileHandle, filename, true)) {
- _fileHandle->setEnc(encByte);
- return true;
- }
- return false;
-}
-
-void ScummEngine::askForDisk(const char *filename, int disknum) {
- char buf[128];
-
- if (_version == 8) {
-#ifndef DISABLE_SCUMM_7_8
- char result;
-
- _imuseDigital->stopAllSounds();
-
-#ifdef MACOSX
- sprintf(buf, "Cannot find file: '%s'\nPlease insert disc %d.\nPress OK to retry, Quit to exit", filename, disknum);
-#else
- sprintf(buf, "Cannot find file: '%s'\nInsert disc %d into drive %s\nPress OK to retry, Quit to exit", filename, disknum, _gameDataPath.c_str());
-#endif
-
- result = displayMessage("Quit", buf);
- if (!result) {
- error("Cannot find file: '%s'", filename);
- }
-#endif
- } else {
- sprintf(buf, "Cannot find file: '%s'", filename);
- InfoDialog dialog(this, (char*)buf);
- runDialog(dialog);
- error("Cannot find file: '%s'", filename);
- }
-}
-
-void ScummEngine::readIndexFile() {
- uint32 blocktype, itemsize;
- int numblock = 0;
-
- debugC(DEBUG_GENERAL, "readIndexFile()");
-
- closeRoom();
- openRoom(0);
-
- if (_version <= 5) {
- // Figure out the sizes of various resources
- while (!_fileHandle->eof()) {
- blocktype = fileReadDword();
- itemsize = _fileHandle->readUint32BE();
- if (_fileHandle->ioFailed())
- break;
- switch (blocktype) {
- case MKID('DOBJ'):
- _numGlobalObjects = _fileHandle->readUint16LE();
- itemsize -= 2;
- break;
- case MKID('DROO'):
- _numRooms = _fileHandle->readUint16LE();
- itemsize -= 2;
- break;
-
- case MKID('DSCR'):
- _numScripts = _fileHandle->readUint16LE();
- itemsize -= 2;
- break;
-
- case MKID('DCOS'):
- _numCostumes = _fileHandle->readUint16LE();
- itemsize -= 2;
- break;
-
- case MKID('DSOU'):
- _numSounds = _fileHandle->readUint16LE();
- itemsize -= 2;
- break;
- }
- _fileHandle->seek(itemsize - 8, SEEK_CUR);
- }
- _fileHandle->clearIOFailed();
- _fileHandle->seek(0, SEEK_SET);
- }
-
-#ifndef DISABLE_HE
- if (checkTryMedia(_fileHandle)) {
- displayMessage(NULL, "You're trying to run game encrypted by ActiveMark. This is not supported.");
- _quit = true;
-
- return;
- }
-#endif
-
- while (true) {
- blocktype = fileReadDword();
- itemsize = _fileHandle->readUint32BE();
-
- if (_fileHandle->ioFailed())
- break;
-
- numblock++;
- readIndexBlock(blocktype, itemsize);
- }
-
-// if (numblock!=9)
-// error("Not enough blocks read from directory");
-
- closeRoom();
-}
-
-
-#ifndef DISABLE_HE
-
-#define TRYMEDIA_MARK_LEN 6
-
-bool checkTryMedia(BaseScummFile *handle) {
- byte buf[TRYMEDIA_MARK_LEN];
- bool matched = true;
- const byte magic[2][TRYMEDIA_MARK_LEN] =
- {{ 0x00, 'T', 'M', 'S', 'A', 'M' },
- { 'i', '=', '$', ':', '(', '$' }}; // Same but 0x69 xored
-
- handle->read(buf, TRYMEDIA_MARK_LEN);
-
- for (int i = 0; i < 2; i++) {
- matched = true;
- for (int j = 0; j < TRYMEDIA_MARK_LEN; j++)
- if (buf[j] != magic[i][j]) {
- matched = false;
- break;
- }
-
- if (matched)
- break;
- }
-
- if (matched)
- return true;
-
- handle->seek(0, SEEK_SET);
-
- return false;
-}
-#endif
-
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) {
- int num;
- char *ptr;
- switch (blocktype) {
- case MKID('ANAM'): // Used by: The Dig, FT
- debug(9, "found ANAM block, reading audio names");
- num = _fileHandle->readUint16LE();
- ptr = (char*)malloc(num * 9);
- _fileHandle->read(ptr, num * 9);
- _imuseDigital->setAudioNames(num, ptr);
- break;
-
- case MKID('DRSC'): // Used by: COMI
- readResTypeList(rtRoomScripts, MKID('RMSC'), "room script");
- break;
-
- default:
- ScummEngine::readIndexBlock(blocktype, itemsize);
- }
-}
-#endif
-
-#ifndef DISABLE_HE
-void ScummEngine_v70he::readIndexBlock(uint32 blocktype, uint32 itemsize) {
- int i;
- switch (blocktype) {
- case MKID('DIRI'):
- readResTypeList(rtRoomImage, MKID('RMIM'), "room image");
- break;
-
- case MKID('DIRM'):
- readResTypeList(rtImage, MKID('AWIZ'), "images");
- break;
-
- case MKID('DIRT'):
- readResTypeList(rtTalkie, MKID('TLKE'), "talkie");
- break;
-
- case MKID('DLFL'):
- i = _fileHandle->readUint16LE();
- _fileHandle->seek(-2, SEEK_CUR);
- _heV7RoomOffsets = (byte *)calloc(2 + (i * 4), 1);
- _fileHandle->read(_heV7RoomOffsets, (2 + (i * 4)) );
- break;
-
- case MKID('DISK'):
- i = _fileHandle->readUint16LE();
- _heV7DiskOffsets = (byte *)calloc(i, 1);
- _fileHandle->read(_heV7DiskOffsets, i);
- break;
-
- case MKID('SVER'):
- // Index version number
- _fileHandle->seek(itemsize - 8, SEEK_CUR);
- break;
-
- case MKID('INIB'):
- _fileHandle->seek(itemsize - 8, SEEK_CUR);
- debug(2, "INIB index block not yet handled, skipping");
- break;
-
- default:
- ScummEngine::readIndexBlock(blocktype, itemsize);
- }
-}
-#endif
-
-void ScummEngine::readIndexBlock(uint32 blocktype, uint32 itemsize) {
- int i;
- switch (blocktype) {
- case MKID('DCHR'):
- case MKID('DIRF'):
- readResTypeList(rtCharset, MKID('CHAR'), "charset");
- break;
-
- case MKID('DOBJ'):
- debug(9, "found DOBJ block, reading object table");
- readGlobalObjects();
- break;
-
- case MKID('RNAM'):
- // Names of rooms. Maybe we should put them into a table, for use by the debugger?
- if (_heversion >= 80) {
- for (int room; (room = _fileHandle->readUint16LE()); ) {
- char buf[100];
- i = 0;
- for (byte s; (s = _fileHandle->readByte()) && i < ARRAYSIZE(buf) - 1; ) {
- buf[i++] = s;
- }
- buf[i] = 0;
- debug(5, "Room %d: '%s'", room, buf);
- }
- } else {
- for (int room; (room = _fileHandle->readByte()); ) {
- char buf[10];
- _fileHandle->read(buf, 9);
- buf[9] = 0;
- for (i = 0; i < 9; i++)
- buf[i] ^= 0xFF;
- debug(5, "Room %d: '%s'", room, buf);
- }
- }
- break;
-
- case MKID('DROO'):
- case MKID('DIRR'):
- readResTypeList(rtRoom, MKID('ROOM'), "room");
- break;
-
- case MKID('DSCR'):
- case MKID('DIRS'):
- readResTypeList(rtScript, MKID('SCRP'), "script");
- break;
-
- case MKID('DCOS'):
- case MKID('DIRC'):
- readResTypeList(rtCostume, MKID('COST'), "costume");
- break;
-
- case MKID('MAXS'):
- readMAXS(itemsize);
- allocateArrays();
- break;
-
- case MKID('DIRN'):
- case MKID('DSOU'):
- readResTypeList(rtSound, MKID('SOUN'), "sound");
- break;
-
- case MKID('AARY'):
- readArrayFromIndexFile();
- break;
-
- default:
- error("Bad ID %04X('%s') found in index file directory!", blocktype,
- tag2str(blocktype));
- }
-}
-
-void ScummEngine::readArrayFromIndexFile() {
- error("readArrayFromIndexFile() not supported in pre-V6 games");
-}
-
-void ScummEngine::readResTypeList(int id, uint32 tag, const char *name) {
- int num;
- int i;
-
- debug(9, "readResTypeList(%s,%s,%s)", resTypeFromId(id), tag2str(TO_BE_32(tag)), name);
-
- if (_version == 8)
- num = _fileHandle->readUint32LE();
- else
- num = _fileHandle->readUint16LE();
-
- if (num != res.num[id]) {
- error("Invalid number of %ss (%d) in directory", name, num);
- }
-
- if (_features & GF_SMALL_HEADER) {
- for (i = 0; i < num; i++) {
- res.roomno[id][i] = _fileHandle->readByte();
- res.roomoffs[id][i] = _fileHandle->readUint32LE();
- }
- } else {
- for (i = 0; i < num; i++) {
- res.roomno[id][i] = _fileHandle->readByte();
- }
- for (i = 0; i < num; i++) {
- res.roomoffs[id][i] = _fileHandle->readUint32LE();
-
- if (id == rtRoom && _heversion >= 70)
- _heV7RoomIntOffsets[i] = res.roomoffs[id][i];
- }
-
- if (_heversion >= 70) {
- for (i = 0; i < num; i++) {
- res.globsize[id][i] = _fileHandle->readUint32LE();
- }
- }
- }
-}
-
-void ScummEngine::allocResTypeData(int id, uint32 tag, int num, const char *name, int mode) {
- debug(9, "allocResTypeData(%s/%s,%s,%d,%d)", resTypeFromId(id), name, tag2str(TO_BE_32(tag)), num, mode);
- assert(id >= 0 && id < (int)(ARRAYSIZE(res.mode)));
-
- if (num >= 8000)
- error("Too many %ss (%d) in directory", name, num);
-
- res.mode[id] = mode;
- res.num[id] = num;
- res.tags[id] = tag;
- res.name[id] = name;
- res.address[id] = (byte **)calloc(num, sizeof(void *));
- res.flags[id] = (byte *)calloc(num, sizeof(byte));
- res.status[id] = (byte *)calloc(num, sizeof(byte));
-
- if (mode) {
- res.roomno[id] = (byte *)calloc(num, sizeof(byte));
- res.roomoffs[id] = (uint32 *)calloc(num, sizeof(uint32));
- }
-
- if (_heversion >= 70) {
- res.globsize[id] = (uint32 *)calloc(num, sizeof(uint32));
-
- if (id == rtRoom)
- _heV7RoomIntOffsets = (uint32 *)calloc(num, sizeof(uint32));
- }
-}
-
-void ScummEngine::loadCharset(int no) {
- int i;
- byte *ptr;
-
- debugC(DEBUG_GENERAL, "loadCharset(%d)", no);
-
- /* FIXME - hack around crash in Indy4 (occurs if you try to load after dieing) */
- if (_gameId == GID_INDY4 && no == 0)
- no = 1;
-
- /* for Humongous catalogs */
- if (_heversion >= 70 && _numCharsets == 1) {
- debug(0, "Not loading charset as it doesn't seem to exist?");
- return;
- }
-
- assert(no < (int)sizeof(_charsetData) / 16);
- checkRange(_numCharsets - 1, 1, no, "Loading illegal charset %d");
-
- ptr = getResourceAddress(rtCharset, no);
-
- for (i = 0; i < 15; i++) {
- _charsetData[no][i + 1] = ptr[i + 14];
- }
-}
-
-void ScummEngine::nukeCharset(int i) {
- checkRange(_numCharsets - 1, 1, i, "Nuking illegal charset %d");
- res.nukeResource(rtCharset, i);
-}
-
-void ScummEngine::ensureResourceLoaded(int type, int i) {
- void *addr = NULL;
-
- debugC(DEBUG_RESOURCE, "ensureResourceLoaded(%s,%d)", resTypeFromId(type), i);
-
- if ((type == rtRoom) && i > 0x7F && _version < 7 && _heversion <= 71) {
- i = _resourceMapper[i & 0x7F];
- }
-
- // FIXME - TODO: This check used to be "i==0". However, that causes
- // problems when using this function to ensure charset 0 is loaded.
- // This is done for many games, e.g. Zak256 or Indy3 (EGA and VGA).
- // For now we restrict the check to anything which is not a charset.
- // Question: Why was this check like that in the first place?
- // Answer: costumes with an index of zero in the newer games at least.
- // TODO: determine why the heck anything would try to load a costume
- // with id 0. Is that "normal", or is it caused by yet another bug in
- // our code base? After all we also have to add special cases for many
- // of our script opcodes that check for the (invalid) actor 0... so
- // maybe both issues are related...
- if (type != rtCharset && i == 0)
- return;
-
- if (i <= res.num[type])
- addr = res.address[type][i];
-
- if (addr)
- return;
-
- loadResource(type, i);
-
- if (_version == 5 && type == rtRoom && i == _roomResource)
- VAR(VAR_ROOM_FLAG) = 1;
-}
-
-int ScummEngine::loadResource(int type, int idx) {
- int roomNr;
- uint32 fileOffs;
- uint32 size, tag;
-
- debugC(DEBUG_RESOURCE, "loadResource(%s,%d)", resTypeFromId(type),idx);
-
- if (type == rtCharset && (_features & GF_SMALL_HEADER)) {
- loadCharset(idx);
- return (1);
- }
-
- roomNr = getResourceRoomNr(type, idx);
-
- if (idx >= res.num[type])
- error("%s %d undefined %d %d", res.name[type], idx, res.num[type], roomNr);
-
- if (roomNr == 0)
- roomNr = _roomResource;
-
- if (type == rtRoom) {
- if (_version == 8)
- fileOffs = 8;
- else if (_heversion >= 70)
- fileOffs = _heV7RoomIntOffsets[idx];
- else
- fileOffs = 0;
- } else {
- fileOffs = res.roomoffs[type][idx];
- if (fileOffs == 0xFFFFFFFF)
- return 0;
- }
-
- openRoom(roomNr);
-
- _fileHandle->seek(fileOffs + _fileOffset, SEEK_SET);
-
- if (_features & GF_OLD_BUNDLE) {
- if ((_version == 3) && !(_platform == Common::kPlatformAmiga) && (type == rtSound)) {
- return readSoundResourceSmallHeader(type, idx);
- } else {
- size = _fileHandle->readUint16LE();
- _fileHandle->seek(-2, SEEK_CUR);
- }
- } else if (_features & GF_SMALL_HEADER) {
- if (_version == 4)
- _fileHandle->seek(8, SEEK_CUR);
- size = _fileHandle->readUint32LE();
- tag = _fileHandle->readUint16LE();
- _fileHandle->seek(-6, SEEK_CUR);
- if ((type == rtSound) && !(_platform == Common::kPlatformAmiga) && !(_platform == Common::kPlatformFMTowns)) {
- return readSoundResourceSmallHeader(type, idx);
- }
- } else {
- if (type == rtSound) {
- return readSoundResource(type, idx);
- }
-
- tag = fileReadDword();
-
- if (tag != res.tags[type] && _heversion < 70) {
- error("%s %d not in room %d at %d+%d in file %s",
- res.name[type], idx, roomNr,
- _fileOffset, fileOffs, _fileHandle->name());
- }
-
- size = _fileHandle->readUint32BE();
- _fileHandle->seek(-8, SEEK_CUR);
- }
- _fileHandle->read(res.createResource(type, idx, size), size);
-
- // dump the resource if requested
- if (_dumpScripts && type == rtScript) {
- dumpResource("script-", idx, getResourceAddress(rtScript, idx));
- }
-
- if (!_fileHandle->ioFailed()) {
- return 1;
- }
-
- res.nukeResource(type, idx);
-
- error("Cannot read resource");
-}
-
-int ScummEngine::getResourceRoomNr(int type, int idx) {
- if (type == rtRoom && _heversion < 70)
- return idx;
- return res.roomno[type][idx];
-}
-
-int ScummEngine::getResourceSize(int type, int idx) {
- byte *ptr = getResourceAddress(type, idx);
- MemBlkHeader *hdr = (MemBlkHeader *)(ptr - sizeof(MemBlkHeader));
-
- return hdr->size;
-}
-
-byte *ScummEngine::getResourceAddress(int type, int idx) {
- byte *ptr;
-
- CHECK_HEAP
-
- if (_heversion >= 80 && type == rtString)
- idx &= ~0x33539000;
-
- if (!res.validateResource("getResourceAddress", type, idx))
- return NULL;
-
- if (!res.address[type]) {
- debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d), res.address[type] == NULL", resTypeFromId(type), idx);
- return NULL;
- }
-
- if (res.mode[type] && !res.address[type][idx]) {
- ensureResourceLoaded(type, idx);
- }
-
- if (!(ptr = (byte *)res.address[type][idx])) {
- debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx);
- return NULL;
- }
-
- res.setResourceCounter(type, idx, 1);
-
- debugC(DEBUG_RESOURCE, "getResourceAddress(%s,%d) == %p", resTypeFromId(type), idx, ptr + sizeof(MemBlkHeader));
- return ptr + sizeof(MemBlkHeader);
-}
-
-byte *ScummEngine::getStringAddress(int i) {
- byte *addr = getResourceAddress(rtString, i);
- return addr;
-}
-
-byte *ScummEngine_v6::getStringAddress(int i) {
- byte *addr = getResourceAddress(rtString, i);
- if (addr == NULL)
- return NULL;
- return ((ScummEngine_v6::ArrayHeader *)addr)->data;
-}
-
-byte *ScummEngine::getStringAddressVar(int i) {
- return getStringAddress(_scummVars[i]);
-}
-
-void ResourceManager::increaseResourceCounter() {
- int i, j;
- byte counter;
-
- for (i = rtFirst; i <= rtLast; i++) {
- for (j = num[i]; --j >= 0;) {
- counter = flags[i][j] & RF_USAGE;
- if (counter && counter < RF_USAGE_MAX) {
- setResourceCounter(i, j, counter + 1);
- }
- }
- }
-}
-
-void ResourceManager::setResourceCounter(int type, int idx, byte flag) {
- flags[type][idx] &= ~RF_USAGE;
- flags[type][idx] |= flag;
-}
-
-/* 2 bytes safety area to make "precaching" of bytes in the gdi drawer easier */
-#define SAFETY_AREA 2
-
-byte *ResourceManager::createResource(int type, int idx, uint32 size) {
- byte *ptr;
-
- CHECK_HEAP
- debugC(DEBUG_RESOURCE, "res.createResource(%s,%d,%d)", resTypeFromId(type), idx, size);
-
- if (!validateResource("allocating", type, idx))
- return NULL;
-
- if (_vm->_version <= 2) {
- // Nuking and reloading a resource can be harmful in some
- // cases. For instance, Zak tries to reload the intro music
- // while it's playing. See bug #1253171.
-
- if (address[type][idx] && (type == rtSound || type == rtScript || type == rtCostume))
- return address[type][idx] + sizeof(MemBlkHeader);
- }
-
- nukeResource(type, idx);
-
- expireResources(size);
-
- CHECK_HEAP
- ptr = (byte *)calloc(size + sizeof(MemBlkHeader) + SAFETY_AREA, 1);
- if (ptr == NULL) {
- error("Out of memory while allocating %d", size);
- }
-
- _allocatedSize += size;
-
- address[type][idx] = ptr;
- ((MemBlkHeader *)ptr)->size = size;
- setResourceCounter(type, idx, 1);
- return ptr + sizeof(MemBlkHeader); /* skip header */
-}
-
-ResourceManager::ResourceManager(ScummEngine *vm) {
- memset(this, 0, sizeof(ResourceManager));
- _vm = vm;
-// _allocatedSize = 0;
-}
-
-bool ResourceManager::validateResource(const char *str, int type, int idx) const {
- if (type < rtFirst || type > rtLast || (uint) idx >= (uint)num[type]) {
- error("%s Illegal Glob type %s (%d) num %d", str, resTypeFromId(type), type, idx);
- return false;
- }
- return true;
-}
-
-void ResourceManager::nukeResource(int type, int idx) {
- byte *ptr;
-
- CHECK_HEAP
- if (!address[type])
- return;
-
- assert(idx >= 0 && idx < num[type]);
-
- ptr = address[type][idx];
- if (ptr != NULL) {
- debugC(DEBUG_RESOURCE, "nukeResource(%s,%d)", resTypeFromId(type), idx);
- address[type][idx] = 0;
- flags[type][idx] = 0;
- status[type][idx] &= ~RS_MODIFIED;
- _allocatedSize -= ((MemBlkHeader *)ptr)->size;
- free(ptr);
- }
-}
-
-const byte *ScummEngine::findResourceData(uint32 tag, const byte *ptr) {
- if (_features & GF_OLD_BUNDLE)
- error("findResourceData must not be used in GF_OLD_BUNDLE games");
- else if (_features & GF_SMALL_HEADER)
- ptr = findResourceSmall(tag, ptr);
- else
- ptr = findResource(tag, ptr);
-
- if (ptr == NULL)
- return NULL;
- return ptr + _resourceHeaderSize;
-}
-
-int ScummEngine::getResourceDataSize(const byte *ptr) const {
- if (ptr == NULL)
- return 0;
-
- if (_features & GF_OLD_BUNDLE)
- return READ_LE_UINT16(ptr) - _resourceHeaderSize;
- else if (_features & GF_SMALL_HEADER)
- return READ_LE_UINT32(ptr) - _resourceHeaderSize;
- else
- return READ_BE_UINT32(ptr - 4) - _resourceHeaderSize;
-}
-
-void ResourceManager::lock(int type, int i) {
- if (!validateResource("Locking", type, i))
- return;
- flags[type][i] |= RF_LOCK;
-}
-
-void ResourceManager::unlock(int type, int i) {
- if (!validateResource("Unlocking", type, i))
- return;
- flags[type][i] &= ~RF_LOCK;
-}
-
-bool ResourceManager::isLocked(int type, int i) const {
- if (!validateResource("isLocked", type, i))
- return false;
- return (flags[type][i] & RF_LOCK) != 0;
-}
-
-bool ScummEngine::isResourceInUse(int type, int i) const {
- if (!res.validateResource("isResourceInUse", type, i))
- return false;
- switch (type) {
- case rtRoom:
- return _roomResource == (byte)i;
- case rtRoomImage:
- return _roomResource == (byte)i;
- case rtRoomScripts:
- return _roomResource == (byte)i;
- case rtScript:
- return isScriptInUse(i);
- case rtCostume:
- return isCostumeInUse(i);
- case rtSound:
- return _sound->isSoundInUse(i);
- case rtCharset:
- return _charset->getCurID() == i;
- case rtImage:
- return res.isModified(type, i) != 0;
- case rtSpoolBuffer:
- return _sound->isSoundRunning(10000 + i) != 0;
- default:
- return false;
- }
-}
-
-void ResourceManager::setModified(int type, int i) {
- if (!validateResource("Modified", type, i))
- return;
- status[type][i] |= RS_MODIFIED;
-}
-
-bool ResourceManager::isModified(int type, int i) const {
- if (!validateResource("isModified", type, i))
- return false;
- return (status[type][i] & RS_MODIFIED) != 0;
-}
-
-void ResourceManager::expireResources(uint32 size) {
- int i, j;
- byte flag;
- byte best_counter;
- int best_type, best_res = 0;
- uint32 oldAllocatedSize;
-
- if (_expireCounter != 0xFF) {
- _expireCounter = 0xFF;
- increaseResourceCounter();
- }
-
- if (size + _allocatedSize < _maxHeapThreshold)
- return;
-
- oldAllocatedSize = _allocatedSize;
-
- do {
- best_type = 0;
- best_counter = 2;
-
- for (i = rtFirst; i <= rtLast; i++)
- if (mode[i]) {
- for (j = num[i]; --j >= 0;) {
- flag = flags[i][j];
- if (!(flag & RF_LOCK) && flag >= best_counter && address[i][j] && !_vm->isResourceInUse(i, j)) {
- best_counter = flag;
- best_type = i;
- best_res = j;
- }
- }
- }
-
- if (!best_type)
- break;
- nukeResource(best_type, best_res);
- } while (size + _allocatedSize > _minHeapThreshold);
-
- increaseResourceCounter();
-
- debugC(DEBUG_RESOURCE, "Expired resources, mem %d -> %d", oldAllocatedSize, _allocatedSize);
-}
-
-void ResourceManager::freeResources() {
- int i, j;
- for (i = rtFirst; i <= rtLast; i++) {
- for (j = num[i]; --j >= 0;) {
- if (isResourceLoaded(i, j))
- nukeResource(i, j);
- }
- free(address[i]);
- free(flags[i]);
- free(status[i]);
- free(roomno[i]);
- free(roomoffs[i]);
-
- free(globsize[i]);
- }
-}
-
-void ScummEngine::loadPtrToResource(int type, int resindex, const byte *source) {
- byte *alloced;
- int i, len;
-
- res.nukeResource(type, resindex);
-
- len = resStrLen(source) + 1;
-
- if (len <= 0)
- return;
-
- alloced = res.createResource(type, resindex, len);
-
- if (!source) {
- alloced[0] = fetchScriptByte();
- for (i = 1; i < len; i++)
- alloced[i] = *_scriptPointer++;
- } else {
- for (i = 0; i < len; i++)
- alloced[i] = source[i];
- }
-}
-
-bool ResourceManager::isResourceLoaded(int type, int idx) const {
- if (!validateResource("isResourceLoaded", type, idx))
- return false;
- return address[type][idx] != NULL;
-}
-
-void ResourceManager::resourceStats() {
- int i, j;
- uint32 lockedSize = 0, lockedNum = 0;
- byte flag;
-
- for (i = rtFirst; i <= rtLast; i++)
- for (j = num[i]; --j >= 0;) {
- flag = flags[i][j];
- if (flag & RF_LOCK && address[i][j]) {
- lockedSize += ((MemBlkHeader *)address[i][j])->size;
- lockedNum++;
- }
- }
-
- debug(1, "Total allocated size=%d, locked=%d(%d)", _allocatedSize, lockedSize, lockedNum);
-}
-
-void ScummEngine_v5::readMAXS(int blockSize) {
- debug(9, "ScummEngine_v5 readMAXS: MAXS has blocksize %d", blockSize);
-
- _numVariables = _fileHandle->readUint16LE(); // 800
- _fileHandle->readUint16LE(); // 16
- _numBitVariables = _fileHandle->readUint16LE(); // 2048
- _numLocalObjects = _fileHandle->readUint16LE(); // 200
- _numArray = 50;
- _numVerbs = 100;
- // Used to be 50, which wasn't enough for MI2 and FOA. See bugs
- // #933610, #936323 and #941275.
- _numNewNames = 150;
- _objectRoomTable = NULL;
-
- _fileHandle->readUint16LE(); // 50
- _numCharsets = _fileHandle->readUint16LE(); // 9
- _fileHandle->readUint16LE(); // 100
- _fileHandle->readUint16LE(); // 50
- _numInventory = _fileHandle->readUint16LE(); // 80
- _numGlobalScripts = 200;
-
- _shadowPaletteSize = 256;
-
- _numFlObject = 50;
-
- if (_shadowPaletteSize)
- _shadowPalette = (byte *)calloc(_shadowPaletteSize, 1);
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v8::readMAXS(int blockSize) {
- debug(9, "ScummEngine_v8 readMAXS: MAXS has blocksize %d", blockSize);
-
- _fileHandle->seek(50, SEEK_CUR); // Skip over SCUMM engine version
- _fileHandle->seek(50, SEEK_CUR); // Skip over data file version
- _numVariables = _fileHandle->readUint32LE(); // 1500
- _numBitVariables = _fileHandle->readUint32LE(); // 2048
- _fileHandle->readUint32LE(); // 40
- _numScripts = _fileHandle->readUint32LE(); // 458
- _numSounds = _fileHandle->readUint32LE(); // 789
- _numCharsets = _fileHandle->readUint32LE(); // 1
- _numCostumes = _fileHandle->readUint32LE(); // 446
- _numRooms = _fileHandle->readUint32LE(); // 95
- _fileHandle->readUint32LE(); // 80
- _numGlobalObjects = _fileHandle->readUint32LE(); // 1401
- _fileHandle->readUint32LE(); // 60
- _numLocalObjects = _fileHandle->readUint32LE(); // 200
- _numNewNames = _fileHandle->readUint32LE(); // 100
- _numFlObject = _fileHandle->readUint32LE(); // 128
- _numInventory = _fileHandle->readUint32LE(); // 80
- _numArray = _fileHandle->readUint32LE(); // 200
- _numVerbs = _fileHandle->readUint32LE(); // 50
-
- _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
- _numGlobalScripts = 2000;
-
- _shadowPaletteSize = NUM_SHADOW_PALETTE * 256;
- _shadowPalette = (byte *)calloc(_shadowPaletteSize, 1);
-}
-
-void ScummEngine_v7::readMAXS(int blockSize) {
- debug(9, "ScummEngine_v7 readMAXS: MAXS has blocksize %d", blockSize);
-
- _fileHandle->seek(50, SEEK_CUR); // Skip over SCUMM engine version
- _fileHandle->seek(50, SEEK_CUR); // Skip over data file version
- _numVariables = _fileHandle->readUint16LE();
- _numBitVariables = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numGlobalObjects = _fileHandle->readUint16LE();
- _numLocalObjects = _fileHandle->readUint16LE();
- _numNewNames = _fileHandle->readUint16LE();
- _numVerbs = _fileHandle->readUint16LE();
- _numFlObject = _fileHandle->readUint16LE();
- _numInventory = _fileHandle->readUint16LE();
- _numArray = _fileHandle->readUint16LE();
- _numRooms = _fileHandle->readUint16LE();
- _numScripts = _fileHandle->readUint16LE();
- _numSounds = _fileHandle->readUint16LE();
- _numCharsets = _fileHandle->readUint16LE();
- _numCostumes = _fileHandle->readUint16LE();
-
- _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
-
- if ((_gameId == GID_FT) && (_features & GF_DEMO) &&
- (_platform == Common::kPlatformPC))
- _numGlobalScripts = 300;
- else
- _numGlobalScripts = 2000;
-
- _shadowPaletteSize = NUM_SHADOW_PALETTE * 256;
- _shadowPalette = (byte *)calloc(_shadowPaletteSize, 1);
-}
-#endif
-
-void ScummEngine_v6::readMAXS(int blockSize) {
- debug(0, "ScummEngine_v6 readMAXS: MAXS has blocksize %d", blockSize);
-
- _numVariables = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numBitVariables = _fileHandle->readUint16LE();
- _numLocalObjects = _fileHandle->readUint16LE();
- _numArray = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numVerbs = _fileHandle->readUint16LE();
- _numFlObject = _fileHandle->readUint16LE();
- _numInventory = _fileHandle->readUint16LE();
- _numRooms = _fileHandle->readUint16LE();
- _numScripts = _fileHandle->readUint16LE();
- _numSounds = _fileHandle->readUint16LE();
- _numCharsets = _fileHandle->readUint16LE();
- _numCostumes = _fileHandle->readUint16LE();
- _numGlobalObjects = _fileHandle->readUint16LE();
- _numNewNames = 50;
-
- _objectRoomTable = NULL;
- _numGlobalScripts = 200;
-
- if (_heversion >= 70) {
- _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
- }
-
- if (_heversion <= 70) {
- _shadowPaletteSize = 256;
- _shadowPalette = (byte *)calloc(_shadowPaletteSize, 1);
- }
-}
-
-void ScummEngine::readGlobalObjects() {
- int i;
- int num = _fileHandle->readUint16LE();
- assert(num == _numGlobalObjects);
-
- _fileHandle->read(_objectOwnerTable, num);
- for (i = 0; i < num; i++) {
- _objectStateTable[i] = _objectOwnerTable[i] >> OF_STATE_SHL;
- _objectOwnerTable[i] &= OF_OWNER_MASK;
- }
-
- _fileHandle->read(_classData, num * sizeof(uint32));
-
-#if defined(SCUMM_BIG_ENDIAN)
- // Correct the endianess if necessary
- for (i = 0; i != num; i++)
- _classData[i] = FROM_LE_32(_classData[i]);
-#endif
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v8::readGlobalObjects() {
- int i;
- int num = _fileHandle->readUint32LE();
- assert(num == _numGlobalObjects);
-
- _objectIDMap = new ObjectNameId[num];
- _objectIDMapSize = num;
- for (i = 0; i < num; i++) {
- // Add to object name-to-id map
- _fileHandle->read(_objectIDMap[i].name, 40);
- _objectIDMap[i].id = i;
-
- _objectStateTable[i] = _fileHandle->readByte();
- _objectRoomTable[i] = _fileHandle->readByte();
- _classData[i] = _fileHandle->readUint32LE();
- }
- memset(_objectOwnerTable, 0xFF, num);
-
- // Finally, sort the object name->ID map, so we can later use
- // bsearch on it. For this we (ab)use strcmp, which works fine
- // since the table entries start with a string.
- qsort(_objectIDMap, _objectIDMapSize, sizeof(ObjectNameId),
- (int (*)(const void*, const void*))strcmp);
-}
-
-void ScummEngine_v7::readGlobalObjects() {
- int num = _fileHandle->readUint16LE();
- assert(num == _numGlobalObjects);
-
- _fileHandle->read(_objectStateTable, num);
- _fileHandle->read(_objectRoomTable, num);
- memset(_objectOwnerTable, 0xFF, num);
-
- _fileHandle->read(_classData, num * sizeof(uint32));
-
-#if defined(SCUMM_BIG_ENDIAN)
- // Correct the endianess if necessary
- for (int i = 0; i != num; i++)
- _classData[i] = FROM_LE_32(_classData[i]);
-#endif
-}
-#endif
-
-void ScummEngine::allocateArrays() {
- // Note: Buffers are now allocated in scummMain to allow for
- // early GUI init.
-
- _objectOwnerTable = (byte *)calloc(_numGlobalObjects, 1);
- _objectStateTable = (byte *)calloc(_numGlobalObjects, 1);
- _classData = (uint32 *)calloc(_numGlobalObjects, sizeof(uint32));
- _newNames = (uint16 *)calloc(_numNewNames, sizeof(uint16));
-
- _inventory = (uint16 *)calloc(_numInventory, sizeof(uint16));
- _verbs = (VerbSlot *)calloc(_numVerbs, sizeof(VerbSlot));
- _objs = (ObjectData *)calloc(_numLocalObjects, sizeof(ObjectData));
- _roomVars = (int32 *)calloc(_numRoomVariables, sizeof(int32));
- _scummVars = (int32 *)calloc(_numVariables, sizeof(int32));
- _bitVars = (byte *)calloc(_numBitVariables >> 3, 1);
- if (_heversion >= 60) {
- _arraySlot = (byte *)calloc(_numArray, 1);
- }
- if (_heversion >= 70) {
- _storedFlObjects = (ObjectData *)calloc(100, sizeof(ObjectData));
- }
-
- allocResTypeData(rtCostume, (_features & GF_NEW_COSTUMES) ? MKID('AKOS') : MKID('COST'),
- _numCostumes, "costume", 1);
- allocResTypeData(rtRoom, MKID('ROOM'), _numRooms, "room", 1);
- allocResTypeData(rtRoomImage, MKID('RMIM'), _numRooms, "room image", 1);
- allocResTypeData(rtRoomScripts, MKID('RMSC'), _numRooms, "room script", 1);
- allocResTypeData(rtSound, MKID('SOUN'), _numSounds, "sound", 2);
- allocResTypeData(rtScript, MKID('SCRP'), _numScripts, "script", 1);
- allocResTypeData(rtCharset, MKID('CHAR'), _numCharsets, "charset", 1);
- allocResTypeData(rtObjectName, MKID('NONE'), _numNewNames, "new name", 0);
- allocResTypeData(rtInventory, MKID('NONE'), _numInventory, "inventory", 0);
- allocResTypeData(rtTemp, MKID('NONE'), 10, "temp", 0);
- allocResTypeData(rtScaleTable, MKID('NONE'), 5, "scale table", 0);
- allocResTypeData(rtActorName, MKID('NONE'), _numActors, "actor name", 0);
- allocResTypeData(rtVerb, MKID('NONE'), _numVerbs, "verb", 0);
- allocResTypeData(rtString, MKID('NONE'), _numArray, "array", 0);
- allocResTypeData(rtFlObject, MKID('NONE'), _numFlObject, "flobject", 0);
- allocResTypeData(rtMatrix, MKID('NONE'), 10, "boxes", 0);
- allocResTypeData(rtImage, MKID('AWIZ'), _numImages, "images", 1);
- allocResTypeData(rtTalkie, MKID('TLKE'), _numTalkies, "talkie", 1);
-
- if (_heversion >= 70) {
- allocResTypeData(rtSpoolBuffer, MKID('NONE'), 9, "spool buffer", 0);
- }
-}
-
-void ScummEngine::dumpResource(const char *tag, int idx, const byte *ptr, int length) {
- char buf[256];
- Common::File out;
-
- uint32 size;
- if (length >= 0)
- size = length;
- else if (_features & GF_OLD_BUNDLE)
- size = READ_LE_UINT16(ptr);
- else if (_features & GF_SMALL_HEADER)
- size = READ_LE_UINT32(ptr);
- else
- size = READ_BE_UINT32(ptr + 4);
-
-#if defined(MACOS_CARBON)
- sprintf(buf, ":dumps:%s%d.dmp", tag, idx);
-#else
- sprintf(buf, "dumps/%s%d.dmp", tag, idx);
-#endif
-
- out.open(buf, Common::File::kFileWriteMode);
- if (out.isOpen() == false)
- return;
- out.write(ptr, size);
- out.close();
-}
-
-ResourceIterator::ResourceIterator(const byte *searchin, bool smallHeader)
- : _ptr(searchin), _smallHeader(smallHeader) {
- assert(searchin);
- if (_smallHeader) {
- _size = READ_LE_UINT32(searchin);
- _pos = 6;
- _ptr = searchin + 6;
- } else {
- _size = READ_BE_UINT32(searchin + 4);
- _pos = 8;
- _ptr = searchin + 8;
- }
-
-}
-
-const byte *ResourceIterator::findNext(uint32 tag) {
- uint32 size = 0;
- const byte *result = 0;
-
- if (_smallHeader) {
- uint16 smallTag = newTag2Old(tag);
- do {
- if (_pos >= _size)
- return 0;
-
- result = _ptr;
- size = READ_LE_UINT32(result);
- if ((int32)size <= 0)
- return 0; // Avoid endless loop
-
- _pos += size;
- _ptr += size;
- } while (READ_LE_UINT16(result + 4) != smallTag);
- } else {
- do {
- if (_pos >= _size)
- return 0;
-
- result = _ptr;
- size = READ_BE_UINT32(result + 4);
- if ((int32)size <= 0)
- return 0; // Avoid endless loop
-
- _pos += size;
- _ptr += size;
- } while (READ_UINT32(result) != tag);
- }
-
- return result;
-}
-
-const byte *ScummEngine::findResource(uint32 tag, const byte *searchin) {
- uint32 curpos, totalsize, size;
-
- debugC(DEBUG_RESOURCE, "findResource(%s, %lx)", tag2str(tag), searchin);
-
- if (!searchin) {
- if (_heversion >= 70) {
- searchin = _resourceLastSearchBuf;
- totalsize = _resourceLastSearchSize;
- curpos = 0;
- } else {
- assert(searchin);
- return NULL;
- }
- } else {
- searchin += 4;
- _resourceLastSearchSize = totalsize = READ_BE_UINT32(searchin);
- curpos = 8;
- searchin += 4;
- }
-
- while (curpos < totalsize) {
- if (READ_UINT32(searchin) == tag) {
- _resourceLastSearchBuf = searchin;
- return searchin;
- }
-
- size = READ_BE_UINT32(searchin + 4);
- if ((int32)size <= 0) {
- error("(%s) Not found in %d... illegal block len %d", tag2str(tag), 0, size);
- return NULL;
- }
-
- curpos += size;
- searchin += size;
- }
-
- return NULL;
-}
-
-const byte *findResourceSmall(uint32 tag, const byte *searchin) {
- uint32 curpos, totalsize, size;
- uint16 smallTag;
-
- smallTag = newTag2Old(tag);
- if (smallTag == 0)
- return NULL;
-
- assert(searchin);
-
- totalsize = READ_LE_UINT32(searchin);
- searchin += 6;
- curpos = 6;
-
- while (curpos < totalsize) {
- size = READ_LE_UINT32(searchin);
-
- if (READ_LE_UINT16(searchin + 4) == smallTag)
- return searchin;
-
- if ((int32)size <= 0) {
- error("(%s) Not found in %d... illegal block len %d", tag2str(tag), 0, size);
- return NULL;
- }
-
- curpos += size;
- searchin += size;
- }
-
- return NULL;
-}
-
-uint16 newTag2Old(uint32 newTag) {
- switch (newTag) {
- case (MKID('RMHD')):
- return (0x4448); // HD
- case (MKID('IM00')):
- return (0x4D42); // BM
- case (MKID('EXCD')):
- return (0x5845); // EX
- case (MKID('ENCD')):
- return (0x4E45); // EN
- case (MKID('SCAL')):
- return (0x4153); // SA
- case (MKID('LSCR')):
- return (0x534C); // LS
- case (MKID('OBCD')):
- return (0x434F); // OC
- case (MKID('OBIM')):
- return (0x494F); // OI
- case (MKID('SMAP')):
- return (0x4D42); // BM
- case (MKID('CLUT')):
- return (0x4150); // PA
- case (MKID('BOXD')):
- return (0x5842); // BX
- case (MKID('CYCL')):
- return (0x4343); // CC
- case (MKID('EPAL')):
- return (0x5053); // SP
- default:
- return (0);
- }
-}
-
-const char *resTypeFromId(int id) {
- static char buf[100];
-
- switch (id) {
- case rtRoom:
- return "Room";
- case rtScript:
- return "Script";
- case rtCostume:
- return "Costume";
- case rtSound:
- return "Sound";
- case rtInventory:
- return "Inventory";
- case rtCharset:
- return "Charset";
- case rtString:
- return "String";
- case rtVerb:
- return "Verb";
- case rtActorName:
- return "ActorName";
- case rtBuffer:
- return "Buffer";
- case rtScaleTable:
- return "ScaleTable";
- case rtTemp:
- return "Temp";
- case rtFlObject:
- return "FlObject";
- case rtMatrix:
- return "Matrix";
- case rtBox:
- return "Box";
- case rtObjectName:
- return "ObjectName";
- case rtRoomScripts:
- return "RoomScripts";
- case rtRoomImage:
- return "RoomImage";
- case rtImage:
- return "Image";
- case rtTalkie:
- return "Talkie";
- case rtSpoolBuffer:
- return "SpoolBuffer";
- case rtNumTypes:
- return "NumTypes";
- default:
- sprintf(buf, "%d", id);
- return buf;
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/resource.h b/scumm/resource.h
deleted file mode 100644
index 318582b5cb..0000000000
--- a/scumm/resource.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef RESOURCE_H
-#define RESOURCE_H
-
-namespace Scumm {
-
-enum {
- OF_OWNER_MASK = 0x0F,
- OF_STATE_MASK = 0xF0,
-
- OF_STATE_SHL = 4
-};
-
-class ResourceIterator {
- uint32 _size;
- uint32 _pos;
- const byte *_ptr;
- bool _smallHeader;
-public:
- ResourceIterator(const byte *searchin, bool smallHeader);
- const byte *findNext(uint32 tag);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/resource_v2.cpp b/scumm/resource_v2.cpp
deleted file mode 100644
index 26e96ec9ef..0000000000
--- a/scumm/resource_v2.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/scumm.h"
-#include "scumm/intern.h"
-#include "scumm/resource.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-void ScummEngine_v2::readClassicIndexFile() {
- int i;
-
- if (_gameId == GID_MANIAC) {
- if (_platform == Common::kPlatformC64) {
- _numGlobalObjects = 256;
- _numRooms = 55;
- _numCostumes = 25;
- _numScripts = 160;
- _numSounds = 70;
- } else if (_platform == Common::kPlatformNES) {
- _numGlobalObjects = 775;
- _numRooms = 55;
-
- // costumes 25-36 are special. see v1MMNEScostTables[] in costume.cpp
- // costumes 37-76 are room graphics resources
- // costume 77 is a character set translation table
- // costume 78 is a preposition list
- // costume 79 is unused but allocated, so the total is a nice even number :)
- _numCostumes = 80;
- _numScripts = 200;
- _numSounds = 100;
- } else {
- _numGlobalObjects = 800;
- _numRooms = 55;
- _numCostumes = 35;
- _numScripts = 200;
- _numSounds = 100;
- }
- } else if (_gameId == GID_ZAK) {
- if (_platform == Common::kPlatformC64) {
- _numGlobalObjects = 775;
- _numRooms = 59;
- _numCostumes = 38;
- _numScripts = 155;
- _numSounds = 127;
- } else {
- _numGlobalObjects = 775;
- _numRooms = 61;
- _numCostumes = 37;
- _numScripts = 155;
- _numSounds = 120;
- }
- }
-
- _fileHandle->seek(0, SEEK_SET);
-
- readMAXS(0);
- allocateArrays();
-
- _fileHandle->readUint16LE(); /* version magic number */
- for (i = 0; i != _numGlobalObjects; i++) {
- byte tmp = _fileHandle->readByte();
- _objectOwnerTable[i] = tmp & OF_OWNER_MASK;
- _objectStateTable[i] = tmp >> OF_STATE_SHL;
- }
-
- for (i = 0; i < _numRooms; i++) {
- res.roomno[rtRoom][i] = i;
- }
- _fileHandle->seek(_numRooms, SEEK_CUR);
- for (i = 0; i < _numRooms; i++) {
- res.roomoffs[rtRoom][i] = _fileHandle->readUint16LE();
- if (res.roomoffs[rtRoom][i] == 0xFFFF)
- res.roomoffs[rtRoom][i] = 0xFFFFFFFF;
- }
-
- for (i = 0; i < _numCostumes; i++) {
- res.roomno[rtCostume][i] = _fileHandle->readByte();
- }
- for (i = 0; i < _numCostumes; i++) {
- res.roomoffs[rtCostume][i] = _fileHandle->readUint16LE();
- if (res.roomoffs[rtCostume][i] == 0xFFFF)
- res.roomoffs[rtCostume][i] = 0xFFFFFFFF;
- }
-
- for (i = 0; i < _numScripts; i++) {
- res.roomno[rtScript][i] = _fileHandle->readByte();
- }
- for (i = 0; i < _numScripts; i++) {
- res.roomoffs[rtScript][i] = _fileHandle->readUint16LE();
- if (res.roomoffs[rtScript][i] == 0xFFFF)
- res.roomoffs[rtScript][i] = 0xFFFFFFFF;
- }
-
- for (i = 0; i < _numSounds; i++) {
- res.roomno[rtSound][i] = _fileHandle->readByte();
- }
- for (i = 0; i < _numSounds; i++) {
- res.roomoffs[rtSound][i] = _fileHandle->readUint16LE();
- if (res.roomoffs[rtSound][i] == 0xFFFF)
- res.roomoffs[rtSound][i] = 0xFFFFFFFF;
- }
-}
-
-void ScummEngine_v2::readEnhancedIndexFile() {
-
- _numGlobalObjects = _fileHandle->readUint16LE();
- _fileHandle->seek(_numGlobalObjects, SEEK_CUR);
- _numRooms = _fileHandle->readByte();
- _fileHandle->seek(_numRooms * 3, SEEK_CUR);
- _numCostumes = _fileHandle->readByte();
- _fileHandle->seek(_numCostumes * 3, SEEK_CUR);
- _numScripts = _fileHandle->readByte();
- _fileHandle->seek(_numScripts * 3, SEEK_CUR);
- _numSounds = _fileHandle->readByte();
-
- _fileHandle->clearIOFailed();
- _fileHandle->seek(0, SEEK_SET);
-
- readMAXS(0);
- allocateArrays();
-
- _fileHandle->readUint16LE(); /* version magic number */
- readGlobalObjects();
- readResTypeList(rtRoom, MKID('ROOM'), "room");
- readResTypeList(rtCostume, MKID('COST'), "costume");
- readResTypeList(rtScript, MKID('SCRP'), "script");
- readResTypeList(rtSound, MKID('SOUN'), "sound");
-}
-
-void ScummEngine_v2::readGlobalObjects() {
- int i;
- int num = _fileHandle->readUint16LE();
- assert(num == _numGlobalObjects);
-
- for (i = 0; i != num; i++) {
- byte tmp = _fileHandle->readByte();
- _objectOwnerTable[i] = tmp & OF_OWNER_MASK;
- _objectStateTable[i] = tmp >> OF_STATE_SHL;
- }
-}
-
-void ScummEngine_v2::readIndexFile() {
- int magic = 0;
- debug(9, "readIndexFile()");
-
- closeRoom();
- openRoom(0);
-
- magic = _fileHandle->readUint16LE();
-
- switch (magic) {
- case 0x0100:
- printf("Enhanced V2 game detected\n");
- readEnhancedIndexFile();
- break;
- case 0x0A31:
- printf("Classic V1 game detected\n");
- _version = 1;
- readClassicIndexFile();
- break;
- case 0x4643:
- if (!(_platform == Common::kPlatformNES))
- error("Use maniac target");
- printf("NES V1 game detected\n");
- _version = 1;
- readClassicIndexFile();
- break;
- case 0x132:
- printf("C64 V1 game detected\n");
- _version = 1;
- readClassicIndexFile();
- break;
- default:
- error("Unknown magic id (0x%X) - this version is unsupported", magic);
- break;
- }
-
- closeRoom();
-}
-
-void ScummEngine_v2::loadCharset(int num) {
- // Stub, V2 font resources are hardcoded into the engine.
-}
-
-} // End of namespace Scumm
diff --git a/scumm/resource_v3.cpp b/scumm/resource_v3.cpp
deleted file mode 100644
index 510f106550..0000000000
--- a/scumm/resource_v3.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/intern.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-extern const char *resTypeFromId(int id);
-
-void ScummEngine_v3old::readResTypeList(int id, uint32 tag, const char *name) {
- int num;
- int i;
-
- debug(9, "readResTypeList(%s,%s,%s)", resTypeFromId(id), tag2str(TO_BE_32(tag)), name);
-
- num = _fileHandle->readByte();
-
- if (num >= 0xFF) {
- error("Too many %ss (%d) in directory", name, num);
- }
-
- if (id == rtRoom) {
- for (i = 0; i < num; i++)
- res.roomno[id][i] = i;
- _fileHandle->seek(num, SEEK_CUR);
- } else {
- for (i = 0; i < num; i++)
- res.roomno[id][i] = _fileHandle->readByte();
- }
- for (i = 0; i < num; i++) {
- res.roomoffs[id][i] = _fileHandle->readUint16LE();
- if (res.roomoffs[id][i] == 0xFFFF)
- res.roomoffs[id][i] = 0xFFFFFFFF;
- }
-}
-
-void ScummEngine_v3old::readIndexFile() {
- int magic = 0;
- debug(9, "readIndexFile()");
-
- closeRoom();
- openRoom(0);
-
- magic = _fileHandle->readUint16LE();
- if (magic != 0x0100)
- error("The magic id doesn't match (0x%X)", magic);
-
- _numGlobalObjects = _fileHandle->readUint16LE();
- _fileHandle->seek(_numGlobalObjects * 4, SEEK_CUR);
- _numRooms = _fileHandle->readByte();
- _fileHandle->seek(_numRooms * 3, SEEK_CUR);
- _numCostumes = _fileHandle->readByte();
- _fileHandle->seek(_numCostumes * 3, SEEK_CUR);
- _numScripts = _fileHandle->readByte();
- _fileHandle->seek(_numScripts * 3, SEEK_CUR);
- _numSounds = _fileHandle->readByte();
-
- _fileHandle->clearIOFailed();
- _fileHandle->seek(0, SEEK_SET);
-
- readMAXS(0);
- allocateArrays();
-
- _fileHandle->readUint16LE(); /* version magic number */
- readGlobalObjects();
- readResTypeList(rtRoom, MKID('ROOM'), "room");
- readResTypeList(rtCostume, MKID('COST'), "costume");
- readResTypeList(rtScript, MKID('SCRP'), "script");
- readResTypeList(rtSound, MKID('SOUN'), "sound");
-
- closeRoom();
-}
-
-void ScummEngine_v3::readRoomsOffsets() {
-}
-
-void ScummEngine_v3::loadCharset(int no) {
- uint32 size;
- memset(_charsetData, 0, sizeof(_charsetData));
-
- checkRange(2, 0, no, "Loading illegal charset %d");
- closeRoom();
-
- Common::File file;
- char buf[20];
-
- sprintf(buf, "%02d.LFL", 99 - no);
- file.open(buf);
-
- if (file.isOpen() == false) {
- error("loadCharset(%d): Missing file charset: %s", no, buf);
- }
-
- size = file.readUint16LE();
- file.read(res.createResource(rtCharset, no, size), size);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/resource_v4.cpp b/scumm/resource_v4.cpp
deleted file mode 100644
index 0f8530af2d..0000000000
--- a/scumm/resource_v4.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/intern.h"
-#include "scumm/resource.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-void ScummEngine_v4::readIndexFile() {
- uint16 blocktype;
- uint32 itemsize;
- int numblock = 0;
-
- debug(9, "readIndexFile()");
-
- closeRoom();
- openRoom(0);
-
- while (!_fileHandle->eof()) {
- // Figure out the sizes of various resources
- itemsize = _fileHandle->readUint32LE();
- blocktype = _fileHandle->readUint16LE();
- if (_fileHandle->ioFailed())
- break;
-
- switch (blocktype) {
- case 0x4E52: // 'NR'
- _fileHandle->readUint16LE();
- break;
- case 0x5230: // 'R0'
- _numRooms = _fileHandle->readUint16LE();
- break;
- case 0x5330: // 'S0'
- _numScripts = _fileHandle->readUint16LE();
- break;
- case 0x4E30: // 'N0'
- _numSounds = _fileHandle->readUint16LE();
- break;
- case 0x4330: // 'C0'
- _numCostumes = _fileHandle->readUint16LE();
- break;
- case 0x4F30: // 'O0'
- _numGlobalObjects = _fileHandle->readUint16LE();
- break;
- }
- _fileHandle->seek(itemsize - 8, SEEK_CUR);
- }
-
- _fileHandle->clearIOFailed();
- _fileHandle->seek(0, SEEK_SET);
-
- readMAXS(0);
- allocateArrays();
-
- while (1) {
- itemsize = _fileHandle->readUint32LE();
-
- if (_fileHandle->ioFailed())
- break;
-
- blocktype = _fileHandle->readUint16LE();
-
- numblock++;
-
- switch (blocktype) {
-
- case 0x4E52: // 'NR'
- // Names of rooms. Maybe we should put them into a table, for use by the debugger?
- for (int room; (room = _fileHandle->readByte()); ) {
- char buf[10];
- _fileHandle->read(buf, 9);
- buf[9] = 0;
- for (int i = 0; i < 9; i++)
- buf[i] ^= 0xFF;
- debug(5, "Room %d: '%s'", room, buf);
- }
- break;
-
- case 0x5230: // 'R0'
- readResTypeList(rtRoom, MKID('ROOM'), "room");
- break;
-
- case 0x5330: // 'S0'
- readResTypeList(rtScript, MKID('SCRP'), "script");
- break;
-
- case 0x4E30: // 'N0'
- readResTypeList(rtSound, MKID('SOUN'), "sound");
- break;
-
- case 0x4330: // 'C0'
- readResTypeList(rtCostume, MKID('COST'), "costume");
- break;
-
- case 0x4F30: // 'O0'
- readGlobalObjects();
- break;
-
- default:
- // FIXME: this is a little hack because Indy3 FM-TOWNS has
- // 32 extra bytes of unknown meaning appended to 00.LFL
- if (!(_gameId == GID_INDY3 && _platform == Common::kPlatformFMTowns))
- error("Bad ID %c%c found in directory!", blocktype & 0xFF, blocktype >> 8);
- return;
- }
- }
- closeRoom();
-}
-
-void ScummEngine_v4::loadCharset(int no) {
- uint32 size;
- memset(_charsetData, 0, sizeof(_charsetData));
-
- checkRange(4, 0, no, "Loading illegal charset %d");
- closeRoom();
-
- Common::File file;
- char buf[20];
-
- sprintf(buf, "%03d.LFL", 900 + no);
- file.open(buf);
-
- if (file.isOpen() == false) {
- error("loadCharset(%d): Missing file charset: %s", no, buf);
- }
-
- size = file.readUint32LE() + 11;
- file.read(res.createResource(rtCharset, no, size), size);
-}
-
-void ScummEngine_v4::readMAXS(int blockSize) {
- // FIXME - I'm not sure for those values yet, they will have to be rechecked
-
- _numVariables = 800; // 800
- _numBitVariables = 4096; // 2048
- _numLocalObjects = 200; // 200
- _numArray = 50;
- _numVerbs = 100;
- _numNewNames = 50;
- _objectRoomTable = NULL;
- _numCharsets = 9; // 9
- _numInventory = 80; // 80
- _numGlobalScripts = 200;
- _numFlObject = 50;
-
- _shadowPaletteSize = 256;
-
- _shadowPalette = (byte *) calloc(_shadowPaletteSize, 1); // FIXME - needs to be removed later
-}
-
-void ScummEngine_v4::readGlobalObjects() {
- int i;
- int num = _fileHandle->readUint16LE();
- assert(num == _numGlobalObjects);
-
- uint32 bits;
- byte tmp;
- for (i = 0; i != num; i++) {
- bits = _fileHandle->readByte();
- bits |= _fileHandle->readByte() << 8;
- bits |= _fileHandle->readByte() << 16;
- _classData[i] = bits;
- tmp = _fileHandle->readByte();
- _objectOwnerTable[i] = tmp & OF_OWNER_MASK;
- _objectStateTable[i] = tmp >> OF_STATE_SHL;
- }
-}
-
-
-} // End of namespace Scumm
diff --git a/scumm/resource_v7he.cpp b/scumm/resource_v7he.cpp
deleted file mode 100644
index 6ce8446a9a..0000000000
--- a/scumm/resource_v7he.cpp
+++ /dev/null
@@ -1,1912 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2006 The ScummVM project
- *
- * Parts of code heavily based on:
- * icoutils - A set of programs dealing with MS Windows icons and cursors.
- * Copyright (C) 1998-2001 Oskar Liljeblad
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/intern_he.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "sound/wave.h"
-
-#include "common/stream.h"
-#include "common/system.h"
-
-namespace Scumm {
-
-ResExtractor::ResExtractor(ScummEngine_v70he *scumm)
- : _vm(scumm) {
-
- _fileName[0] = 0;
- memset(_cursorCache, 0, sizeof(_cursorCache));
-}
-
-ResExtractor::~ResExtractor() {
- for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
- CachedCursor *cc = &_cursorCache[i];
- if (cc->valid) {
- free(cc->bitmap);
- free(cc->palette);
- }
- }
- memset(_cursorCache, 0, sizeof(_cursorCache));
-}
-
-ResExtractor::CachedCursor *ResExtractor::findCachedCursor(int id) {
- for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
- CachedCursor *cc = &_cursorCache[i];
- if (cc->valid && cc->id == id) {
- return cc;
- }
- }
- return NULL;
-}
-
-ResExtractor::CachedCursor *ResExtractor::getCachedCursorSlot() {
- uint32 min_last_used = 0;
- CachedCursor *r = NULL;
- for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
- CachedCursor *cc = &_cursorCache[i];
- if (!cc->valid) {
- return cc;
- } else {
- if (min_last_used == 0 || cc->last_used < min_last_used) {
- min_last_used = cc->last_used;
- r = cc;
- }
- }
- }
- assert(r);
- free(r->bitmap);
- free(r->palette);
- memset(r, 0, sizeof(CachedCursor));
- return r;
-}
-
-void ResExtractor::setCursor(int id) {
- byte *cursorRes = 0;
- int cursorsize;
- int keycolor = 0;
- CachedCursor *cc = findCachedCursor(id);
- if (cc != NULL) {
- debug(7, "Found cursor %d in cache slot %d", id, cc - _cursorCache);
- } else {
- cc = getCachedCursorSlot();
- assert(cc && !cc->valid);
- cursorsize = extractResource(id, &cursorRes);
- convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor, &cc->palette, &cc->palSize);
- debug(7, "Adding cursor %d to cache slot %d", id, cc - _cursorCache);
- free(cursorRes);
- cc->valid = true;
- cc->id = id;
- cc->last_used = g_system->getMillis();
- }
-
- if (_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette) && cc->palette)
- _vm->_system->setCursorPalette(cc->palette, 0, cc->palSize);
-
- _vm->setCursorHotspot(cc->hotspot_x, cc->hotspot_y);
- _vm->setCursorFromBuffer(cc->bitmap, cc->w, cc->h, cc->w);
-}
-
-
-/*
- * Static variables
- */
-const char *res_types[] = {
- /* 0x01: */
- "cursor", "bitmap", "icon", "menu", "dialog", "string",
- "fontdir", "font", "accelerator", "rcdata", "messagelist",
- "group_cursor", NULL, "group_icon", NULL,
- /* the following are not defined in winbase.h, but found in wrc. */
- /* 0x10: */
- "version", "dlginclude", NULL, "plugplay", "vxd",
- "anicursor", "aniicon"
-};
-#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *))
-
-Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
-}
-
-int Win32ResExtractor::extractResource(int resId, byte **data) {
- char buf[20];
-
- snprintf(buf, sizeof(buf), "%d", resId);
-
- return extractResource_("group_cursor", buf, data);
-}
-
-int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) {
- char *arg_language = NULL;
- const char *arg_type = resType;
- char *arg_name = resName;
- int arg_action = ACTION_LIST;
- int ressize = 0;
-
- _arg_raw = false;
-
- /* translate --type option from resource type string to integer */
- arg_type = res_type_string_to_id(arg_type);
-
- WinLibrary fi;
-
- /* initiate stuff */
- fi.memory = NULL;
- fi.file = new Common::File;
-
- if (!_fileName[0]) { // We are running for the first time
- snprintf(_fileName, 256, "%s.he3", _vm->getBaseName());
-
- if (_vm->_substResFileNameIndex > 0) {
- char buf1[128];
-
- _vm->generateSubstResFileName(_fileName, buf1, sizeof(buf1));
- strcpy(_fileName, buf1);
- }
- }
-
-
- /* get file size */
- fi.file->open(_fileName);
- if (!fi.file->isOpen()) {
- error("Cannot open file %s", _fileName);
- }
-
- fi.total_size = fi.file->size();
- if (fi.total_size == -1) {
- error("Cannot get size of file %s", fi.file->name());
- goto cleanup;
- }
- if (fi.total_size == 0) {
- error("%s: file has a size of 0", fi.file->name());
- goto cleanup;
- }
-
- /* read all of file */
- fi.memory = (byte *)malloc(fi.total_size);
- if (fi.file->read(fi.memory, fi.total_size) == 0) {
- error("Cannot read from file %s", fi.file->name());
- goto cleanup;
- }
-
- /* identify file and find resource table */
- if (!read_library(&fi)) {
- /* error reported by read_library */
- goto cleanup;
- }
-
- // verbose_printf("file is a %s\n",
- // fi.is_PE_binary ? "Windows NT `PE' binary" : "Windows 3.1 `NE' binary");
-
- /* errors will be printed by the callback */
- ressize = do_resources(&fi, arg_type, arg_name, arg_language, arg_action, data);
-
- /* free stuff and close file */
- cleanup:
- if (fi.file != NULL)
- fi.file->close();
- if (fi.memory != NULL)
- free(fi.memory);
-
- return ressize;
-}
-
-
-/* res_type_id_to_string:
- * Translate a numeric resource type to it's corresponding string type.
- * (For informative-ness.)
- */
-const char *Win32ResExtractor::res_type_id_to_string(int id) {
- if (id == 241)
- return "toolbar";
- if (id > 0 && id <= (int)RES_TYPE_COUNT)
- return res_types[id-1];
- return NULL;
-}
-
-/* res_type_string_to_id:
- * Translate a resource type string to integer.
- * (Used to convert the --type option.)
- */
-const char *Win32ResExtractor::res_type_string_to_id(const char *type) {
- static const char *res_type_ids[] = {
- "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-10",
- "-11", "-12", NULL, "-14", NULL, "-16", "-17", NULL, "-19",
- "-20", "-21", "-22"
- };
- int c;
-
- if (type == NULL)
- return NULL;
-
- for (c = 0 ; c < (int)RES_TYPE_COUNT ; c++) {
- if (res_types[c] != NULL && !scumm_stricmp(type, res_types[c]))
- return res_type_ids[c];
- }
-
- return type;
-}
-
-int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr,
- WinResource *type_wr, WinResource *name_wr,
- WinResource *lang_wr, byte **data) {
- int size;
- bool free_it;
- const char *type;
- int32 id;
-
- if (*data) {
- error("Win32ResExtractor::extract_resources() more than one cursor");
- return 0;
- }
-
- *data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw);
-
- if (data == NULL) {
- error("Win32ResExtractor::extract_resources() problem with resource extraction");
- return 0;
- }
-
- /* get named resource type if possible */
- type = NULL;
- if ((id = strtol(type_wr->id, 0, 10)) != 0)
- type = res_type_id_to_string(id);
-
- debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s%s%s [size=%d]",
- get_resource_id_quoted(name_wr),
- (lang_wr->id[0] != '\0' ? " language: " : ""),
- get_resource_id_quoted(lang_wr), size);
-
- return size;
-}
-
-/* extract_resource:
- * Extract a resource, returning pointer to data.
- */
-byte *Win32ResExtractor::extract_resource(WinLibrary *fi, WinResource *wr, int *size,
- bool *free_it, char *type, char *lang, bool raw) {
- char *str;
- int32 intval;
-
- /* just return pointer to data if raw */
- if (raw) {
- *free_it = false;
- /* get_resource_entry will print possible error */
- return get_resource_entry(fi, wr, size);
- }
-
- /* find out how to extract */
- str = type;
- if (str != NULL && (intval = strtol(STRIP_RES_ID_FORMAT(str), 0, 10))) {
- if (intval == (int)RT_GROUP_ICON) {
- *free_it = true;
- return extract_group_icon_cursor_resource(fi, wr, lang, size, true);
- }
- if (intval == (int)RT_GROUP_CURSOR) {
- *free_it = true;
- return extract_group_icon_cursor_resource(fi, wr, lang, size, false);
- }
- }
-
- return NULL;
-}
-
-/* extract_group_icon_resource:
- * Create a complete RT_GROUP_ICON resource, that can be written to
- * an `.ico' file without modifications. Returns an allocated
- * memory block that should be freed with free() once used.
- *
- * `root' is the offset in file that specifies the resource.
- * `base' is the offset that string pointers are calculated from.
- * `ressize' should point to an integer variable where the size of
- * the returned memory block will be placed.
- * `is_icon' indicates whether resource to be extracted is icon
- * or cursor group.
- */
-byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinResource *wr, char *lang,
- int *ressize, bool is_icon) {
- Win32CursorIconDir *icondir;
- Win32CursorIconFileDir *fileicondir;
- byte *memory;
- int c, offset, skipped;
- int size;
-
- /* get resource data and size */
- icondir = (Win32CursorIconDir *)get_resource_entry(fi, wr, &size);
- if (icondir == NULL) {
- /* get_resource_entry will print error */
- return NULL;
- }
-
- /* calculate total size of output file */
- RETURN_IF_BAD_POINTER(NULL, icondir->count);
- skipped = 0;
- for (c = 0 ; c < icondir->count ; c++) {
- int level;
- int iconsize;
- char name[14];
- WinResource *fwr;
-
- RETURN_IF_BAD_POINTER(NULL, icondir->entries[c]);
- /*printf("%d. bytes_in_res=%d width=%d height=%d planes=%d bit_count=%d\n", c,
- icondir->entries[c].bytes_in_res,
- (is_icon ? icondir->entries[c].res_info.icon.width : icondir->entries[c].res_info.cursor.width),
- (is_icon ? icondir->entries[c].res_info.icon.height : icondir->entries[c].res_info.cursor.height),
- icondir->entries[c].plane_count,
- icondir->entries[c].bit_count);*/
-
- /* find the corresponding icon resource */
- snprintf(name, sizeof(name)/sizeof(char), "-%d", icondir->entries[c].res_id);
- fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
- if (fwr == NULL) {
- error("%s: could not find `%s' in `%s' resource.",
- fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
- return NULL;
- }
-
- if (get_resource_entry(fi, fwr, &iconsize) != NULL) {
- if (iconsize == 0) {
- debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", fi->file->name(), name);
- skipped++;
- continue;
- }
- if ((uint32)iconsize != icondir->entries[c].bytes_in_res) {
- debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)",
- fi->file->name(), name, iconsize, icondir->entries[c].bytes_in_res);
- }
- size += iconsize; /* size += icondir->entries[c].bytes_in_res; */
-
- /* cursor resources have two additional WORDs that contain
- * hotspot info */
- if (!is_icon)
- size -= sizeof(uint16)*2;
- }
- }
- offset = sizeof(Win32CursorIconFileDir) + (icondir->count-skipped) * sizeof(Win32CursorIconFileDirEntry);
- size += offset;
- *ressize = size;
-
- /* allocate that much memory */
- memory = (byte *)malloc(size);
- fileicondir = (Win32CursorIconFileDir *)memory;
-
- /* transfer Win32CursorIconDir structure members */
- fileicondir->reserved = icondir->reserved;
- fileicondir->type = icondir->type;
- fileicondir->count = icondir->count - skipped;
-
- /* transfer each cursor/icon: Win32CursorIconDirEntry and data */
- skipped = 0;
- for (c = 0 ; c < icondir->count ; c++) {
- int level;
- char name[14];
- WinResource *fwr;
- byte *data;
-
- /* find the corresponding icon resource */
- snprintf(name, sizeof(name)/sizeof(char), "-%d", icondir->entries[c].res_id);
- fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
- if (fwr == NULL) {
- error("%s: could not find `%s' in `%s' resource.",
- fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
- return NULL;
- }
-
- /* get data and size of that resource */
- data = (byte *)get_resource_entry(fi, fwr, &size);
- if (data == NULL) {
- /* get_resource_entry has printed error */
- return NULL;
- }
- if (size == 0) {
- skipped++;
- continue;
- }
-
- /* copy ICONDIRENTRY (not including last dwImageOffset) */
- memcpy(&fileicondir->entries[c-skipped], &icondir->entries[c],
- sizeof(Win32CursorIconFileDirEntry)-sizeof(uint32));
-
- /* special treatment for cursors */
- if (!is_icon) {
- fileicondir->entries[c-skipped].width = icondir->entries[c].res_info.cursor.width;
- fileicondir->entries[c-skipped].height = icondir->entries[c].res_info.cursor.height / 2;
- fileicondir->entries[c-skipped].color_count = 0;
- fileicondir->entries[c-skipped].reserved = 0;
- }
-
- /* set image offset and increase it */
- fileicondir->entries[c-skipped].dib_offset = offset;
-
- /* transfer resource into file memory */
- if (is_icon) {
- memcpy(&memory[offset], data, icondir->entries[c].bytes_in_res);
- } else {
- fileicondir->entries[c-skipped].hotspot_x = ((uint16 *) data)[0];
- fileicondir->entries[c-skipped].hotspot_y = ((uint16 *) data)[1];
- memcpy(&memory[offset], data+sizeof(uint16)*2,
- icondir->entries[c].bytes_in_res-sizeof(uint16)*2);
- offset -= sizeof(uint16)*2;
- }
-
- /* increase the offset pointer */
- offset += icondir->entries[c].bytes_in_res;
- }
-
- return memory;
-}
-
-/* check_offset:
- * Check if a chunk of data (determined by offset and size)
- * is within the bounds of the WinLibrary file.
- * Usually not called directly.
- */
-bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *name, void *offset, int size) {
- int need_size = (int)((byte *)offset - memory + size);
-
- debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x",
- need_size, total_size, (byte *)offset - memory, size);
-
- if (need_size < 0 || need_size > total_size) {
- error("%s: premature end", name);
- return false;
- }
-
- return true;
-}
-
-
-/* do_resources:
- * Do something for each resource matching type, name and lang.
- */
-int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, int action, byte **data) {
- WinResource *type_wr;
- WinResource *name_wr;
- WinResource *lang_wr;
- int size;
-
- type_wr = (WinResource *)calloc(sizeof(WinResource)*3, 1);
- name_wr = type_wr + 1;
- lang_wr = type_wr + 2;
-
- size = do_resources_recurs(fi, NULL, type_wr, name_wr, lang_wr, type, name, lang, action, data);
-
- free(type_wr);
-
- return size;
-}
-
-/* what is each entry in this directory level for? type, name or language? */
-#define WINRESOURCE_BY_LEVEL(x) ((x)==0 ? type_wr : ((x)==1 ? name_wr : lang_wr))
-
-/* does the id of this entry match the specified id? */
-#define LEVEL_MATCHES(x) (x == NULL || x ## _wr->id[0] == '\0' || compare_resource_id(x ## _wr, x))
-
-int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base,
- WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr,
- const char *type, char *name, char *lang, int action, byte **data) {
- int c, rescnt;
- WinResource *wr;
- uint32 size = 0;
-
- /* get a list of all resources at this level */
- wr = list_resources(fi, base, &rescnt);
- if (wr == NULL)
- if (size != 0)
- return size;
- else
- return 0;
-
- /* process each resource listed */
- for (c = 0 ; c < rescnt ; c++) {
- /* (over)write the corresponding WinResource holder with the current */
- memcpy(WINRESOURCE_BY_LEVEL(wr[c].level), wr+c, sizeof(WinResource));
-
- /* go deeper unless there is something that does NOT match */
- if (LEVEL_MATCHES(type) && LEVEL_MATCHES(name) && LEVEL_MATCHES(lang)) {
- if (wr->is_directory)
- size = do_resources_recurs(fi, wr+c, type_wr, name_wr, lang_wr, type, name, lang, action, data);
- else
- size = extract_resources(fi, wr+c, type_wr, name_wr, lang_wr, data);
- }
- }
-
- /* since we're moving back one level after this, unset the
- * WinResource holder used on this level */
- memset(WINRESOURCE_BY_LEVEL(wr[0].level), 0, sizeof(WinResource));
-
- return size;
-}
-
-/* return the resource id quoted if it's a string, otherwise just return it */
-char *Win32ResExtractor::get_resource_id_quoted(WinResource *wr) {
- static char tmp[WINRES_ID_MAXLEN+2];
-
- if (wr->numeric_id || wr->id[0] == '\0')
- return wr->id;
-
- sprintf(tmp, "'%s'", wr->id);
- return tmp;
-}
-
-bool Win32ResExtractor::compare_resource_id(WinResource *wr, const char *id) {
- if (wr->numeric_id) {
- int32 cmp1, cmp2;
- if (id[0] == '+')
- return false;
- if (id[0] == '-')
- id++;
- if (!(cmp1 = strtol(wr->id, 0, 10)) || !(cmp2 = strtol(id, 0, 10)) || cmp1 != cmp2)
- return false;
- } else {
- if (id[0] == '-')
- return false;
- if (id[0] == '+')
- id++;
- if (strcmp(wr->id, id))
- return false;
- }
-
- return true;
-}
-
-bool Win32ResExtractor::decode_pe_resource_id(WinLibrary *fi, WinResource *wr, uint32 value) {
- if (value & IMAGE_RESOURCE_NAME_IS_STRING) { /* numeric id */
- int c, len;
- uint16 *mem = (uint16 *)
- (fi->first_resource + (value & ~IMAGE_RESOURCE_NAME_IS_STRING));
-
- /* copy each char of the string, and terminate it */
- RETURN_IF_BAD_POINTER(false, *mem);
- len = mem[0];
- RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(uint16) * len);
-
- len = MIN(mem[0], (uint16)WINRES_ID_MAXLEN);
- for (c = 0 ; c < len ; c++)
- wr->id[c] = mem[c+1] & 0x00FF;
- wr->id[len] = '\0';
- } else { /* Unicode string id */
- /* translate id into a string */
- snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value);
- }
-
- wr->numeric_id = (value & IMAGE_RESOURCE_NAME_IS_STRING ? false:true);
- return true;
-}
-
-byte *Win32ResExtractor::get_resource_entry(WinLibrary *fi, WinResource *wr, int *size) {
- if (fi->is_PE_binary) {
- Win32ImageResourceDataEntry *dataent;
-
- dataent = (Win32ImageResourceDataEntry *) wr->children;
- RETURN_IF_BAD_POINTER(NULL, *dataent);
- *size = dataent->size;
- RETURN_IF_BAD_OFFSET(NULL, fi->memory + dataent->offset_to_data, *size);
-
- return fi->memory + dataent->offset_to_data;
- } else {
- Win16NENameInfo *nameinfo;
- int sizeshift;
-
- nameinfo = (Win16NENameInfo *) wr->children;
- sizeshift = *((uint16 *) fi->first_resource - 1);
- *size = nameinfo->length << sizeshift;
- RETURN_IF_BAD_OFFSET(NULL, fi->memory + (nameinfo->offset << sizeshift), *size);
-
- return fi->memory + (nameinfo->offset << sizeshift);
- }
-}
-
-bool Win32ResExtractor::decode_ne_resource_id(WinLibrary *fi, WinResource *wr, uint16 value) {
- if (value & NE_RESOURCE_NAME_IS_NUMERIC) { /* numeric id */
- /* translate id into a string */
- snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value & ~NE_RESOURCE_NAME_IS_NUMERIC);
- } else { /* ASCII string id */
- int len;
- char *mem = (char *)NE_HEADER(fi->memory)
- + NE_HEADER(fi->memory)->rsrctab
- + value;
-
- /* copy each char of the string, and terminate it */
- RETURN_IF_BAD_POINTER(false, *mem);
- len = mem[0];
- RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(char) * len);
- memcpy(wr->id, &mem[1], len);
- wr->id[len] = '\0';
- }
-
- wr->numeric_id = (value & NE_RESOURCE_NAME_IS_NUMERIC ? true:false);
- return true;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_pe_resources(WinLibrary *fi, Win32ImageResourceDirectory *pe_res, int level, int *count) {
- WinResource *wr;
- int c, rescnt;
- Win32ImageResourceDirectoryEntry *dirent
- = (Win32ImageResourceDirectoryEntry *)(pe_res + 1);
-
- /* count number of `type' resources */
- RETURN_IF_BAD_POINTER(NULL, *dirent);
- rescnt = pe_res->number_of_named_entries + pe_res->number_of_id_entries;
- *count = rescnt;
-
- /* allocate WinResource's */
- wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
- /* fill in the WinResource's */
- for (c = 0 ; c < rescnt ; c++) {
- RETURN_IF_BAD_POINTER(NULL, dirent[c]);
- wr[c].this_ = pe_res;
- wr[c].level = level;
- wr[c].is_directory = (dirent[c].u2.s.data_is_directory);
- wr[c].children = fi->first_resource + dirent[c].u2.s.offset_to_directory;
-
- /* fill in wr->id, wr->numeric_id */
- if (!decode_pe_resource_id (fi, wr + c, dirent[c].u1.name))
- return NULL;
- }
-
- return wr;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_ne_name_resources(WinLibrary *fi, WinResource *typeres, int *count) {
- int c, rescnt;
- WinResource *wr;
- Win16NETypeInfo *typeinfo = (Win16NETypeInfo *) typeres->this_;
- Win16NENameInfo *nameinfo = (Win16NENameInfo *) typeres->children;
-
- /* count number of `type' resources */
- RETURN_IF_BAD_POINTER(NULL, typeinfo->count);
- *count = rescnt = typeinfo->count;
-
- /* allocate WinResource's */
- wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
- /* fill in the WinResource's */
- for (c = 0 ; c < rescnt ; c++) {
- RETURN_IF_BAD_POINTER(NULL, nameinfo[c]);
- wr[c].this_ = nameinfo+c;
- wr[c].is_directory = false;
- wr[c].children = nameinfo+c;
- wr[c].level = 1;
-
- /* fill in wr->id, wr->numeric_id */
- if (!decode_ne_resource_id(fi, wr + c, (nameinfo+c)->id))
- return NULL;
- }
-
- return wr;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_ne_type_resources(WinLibrary *fi, int *count) {
- int c, rescnt;
- WinResource *wr;
- Win16NETypeInfo *typeinfo;
-
- /* count number of `type' resources */
- typeinfo = (Win16NETypeInfo *) fi->first_resource;
- RETURN_IF_BAD_POINTER(NULL, *typeinfo);
- for (rescnt = 0 ; typeinfo->type_id != 0 ; rescnt++) {
- typeinfo = NE_TYPEINFO_NEXT(typeinfo);
- RETURN_IF_BAD_POINTER(NULL, *typeinfo);
- }
- *count = rescnt;
-
- /* allocate WinResource's */
- wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
- /* fill in the WinResource's */
- typeinfo = (Win16NETypeInfo *) fi->first_resource;
- for (c = 0 ; c < rescnt ; c++) {
- wr[c].this_ = typeinfo;
- wr[c].is_directory = (typeinfo->count != 0);
- wr[c].children = typeinfo+1;
- wr[c].level = 0;
-
- /* fill in wr->id, wr->numeric_id */
- if (!decode_ne_resource_id(fi, wr + c, typeinfo->type_id))
- return NULL;
-
- typeinfo = NE_TYPEINFO_NEXT(typeinfo);
- }
-
- return wr;
-}
-
-/* list_resources:
- * Return an array of WinResource's in the current
- * resource level specified by res.
- */
-Win32ResExtractor::WinResource *Win32ResExtractor::list_resources(WinLibrary *fi, WinResource *res, int *count) {
- if (res != NULL && !res->is_directory)
- return NULL;
-
- if (fi->is_PE_binary) {
- return list_pe_resources(fi, (Win32ImageResourceDirectory *)
- (res == NULL ? fi->first_resource : res->children),
- (res == NULL ? 0 : res->level+1),
- count);
- } else {
- return (res == NULL
- ? list_ne_type_resources(fi, count)
- : list_ne_name_resources(fi, res, count));
- }
-}
-
-/* read_library:
- * Read header and get resource directory offset in a Windows library
- * (AKA module).
- *
- */
-bool Win32ResExtractor::read_library(WinLibrary *fi) {
- /* check for DOS header signature `MZ' */
- RETURN_IF_BAD_POINTER(false, MZ_HEADER(fi->memory)->magic);
- if (MZ_HEADER(fi->memory)->magic == IMAGE_DOS_SIGNATURE) {
- DOSImageHeader *mz_header = MZ_HEADER(fi->memory);
-
- RETURN_IF_BAD_POINTER(false, mz_header->lfanew);
- if (mz_header->lfanew < sizeof(DOSImageHeader)) {
- error("%s: not a Windows library", fi->file->name());
- return false;
- }
- }
-
- /* check for OS2 (Win16) header signature `NE' */
- RETURN_IF_BAD_POINTER(false, NE_HEADER(fi->memory)->magic);
- if (NE_HEADER(fi->memory)->magic == IMAGE_OS2_SIGNATURE) {
- OS2ImageHeader *header = NE_HEADER(fi->memory);
-
- RETURN_IF_BAD_POINTER(false, header->rsrctab);
- RETURN_IF_BAD_POINTER(false, header->restab);
- if (header->rsrctab >= header->restab) {
- error("%s: no resource directory found", fi->file->name());
- return false;
- }
-
- fi->is_PE_binary = false;
- fi->first_resource = (byte *) NE_HEADER(fi->memory)
- + header->rsrctab + sizeof(uint16);
- RETURN_IF_BAD_POINTER(false, *(Win16NETypeInfo *) fi->first_resource);
-
- return true;
- }
-
- /* check for NT header signature `PE' */
- RETURN_IF_BAD_POINTER(false, PE_HEADER(fi->memory)->signature);
- if (PE_HEADER(fi->memory)->signature == IMAGE_NT_SIGNATURE) {
- Win32ImageSectionHeader *pe_sec;
- Win32ImageDataDirectory *dir;
- Win32ImageNTHeaders *pe_header;
- int d;
-
- /* allocate new memory */
- fi->total_size = calc_vma_size(fi);
- if (fi->total_size == 0) {
- /* calc_vma_size has reported error */
- return false;
- }
- fi->memory = (byte *)realloc(fi->memory, fi->total_size);
-
- /* relocate memory, start from last section */
- pe_header = PE_HEADER(fi->memory);
- RETURN_IF_BAD_POINTER(false, pe_header->file_header.number_of_sections);
-
- /* we don't need to do OFFSET checking for the sections.
- * calc_vma_size has already done that */
- for (d = pe_header->file_header.number_of_sections - 1; d >= 0 ; d--) {
- pe_sec = PE_SECTIONS(fi->memory) + d;
-
- if (pe_sec->characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
- continue;
-
- //if (pe_sec->virtual_address + pe_sec->size_of_raw_data > fi->total_size)
-
- RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->virtual_address, pe_sec->size_of_raw_data);
- RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->pointer_to_raw_data, pe_sec->size_of_raw_data);
- if (pe_sec->virtual_address != pe_sec->pointer_to_raw_data) {
- memmove(fi->memory + pe_sec->virtual_address,
- fi->memory + pe_sec->pointer_to_raw_data,
- pe_sec->size_of_raw_data);
- }
- }
-
- /* find resource directory */
- RETURN_IF_BAD_POINTER(false, pe_header->optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);
- dir = pe_header->optional_header.data_directory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
- if (dir->size == 0) {
- error("%s: file contains no resources", fi->file->name());
- return false;
- }
-
- fi->first_resource = fi->memory + dir->virtual_address;
- fi->is_PE_binary = true;
- return true;
- }
-
- /* other (unknown) header signature was found */
- error("%s: not a Windows library", fi->file->name());
- return false;
-}
-
-/* calc_vma_size:
- * Calculate the total amount of memory needed for a 32-bit Windows
- * module. Returns -1 if file was too small.
- */
-int Win32ResExtractor::calc_vma_size(WinLibrary *fi) {
- Win32ImageSectionHeader *seg;
- int c, segcount, size;
-
- size = 0;
- RETURN_IF_BAD_POINTER(-1, PE_HEADER(fi->memory)->file_header.number_of_sections);
- segcount = PE_HEADER(fi->memory)->file_header.number_of_sections;
-
- /* If there are no segments, just process file like it is.
- * This is (probably) not the right thing to do, but problems
- * will be delt with later anyway.
- */
- if (segcount == 0)
- return fi->total_size;
-
- seg = PE_SECTIONS(fi->memory);
- RETURN_IF_BAD_POINTER(-1, *seg);
- for (c = 0 ; c < segcount ; c++) {
- RETURN_IF_BAD_POINTER(0, *seg);
-
- size = MAX((uint32)size, seg->virtual_address + seg->size_of_raw_data);
- /* I have no idea what misc.virtual_size is for... */
- size = MAX((uint32)size, seg->virtual_address + seg->misc.virtual_size);
- seg++;
- }
-
- return size;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::find_with_resource_array(WinLibrary *fi, WinResource *wr, const char *id) {
- int c, rescnt;
- WinResource *return_wr;
-
- wr = list_resources(fi, wr, &rescnt);
- if (wr == NULL)
- return NULL;
-
- for (c = 0 ; c < rescnt ; c++) {
- if (compare_resource_id(&wr[c], id)) {
- /* duplicate WinResource and return it */
- return_wr = (WinResource *)malloc(sizeof(WinResource));
- memcpy(return_wr, &wr[c], sizeof(WinResource));
-
- /* free old WinResource */
- free(wr);
- return return_wr;
- }
- }
-
- return NULL;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, const char *type, const char *name, const char *language, int *level) {
- WinResource *wr;
-
- *level = 0;
- if (type == NULL)
- return NULL;
- wr = find_with_resource_array(fi, NULL, type);
- if (wr == NULL || !wr->is_directory)
- return wr;
-
- *level = 1;
- if (name == NULL)
- return wr;
- wr = find_with_resource_array(fi, wr, name);
- if (wr == NULL || !wr->is_directory)
- return wr;
-
- *level = 2;
- if (language == NULL)
- return wr;
- wr = find_with_resource_array(fi, wr, language);
- return wr;
-}
-
-#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2)
-
-
-int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) {
- Win32CursorIconFileDir dir;
- Win32CursorIconFileDirEntry *entries = NULL;
- uint32 offset;
- uint32 c, d;
- int completed;
- int matched = 0;
- MemoryReadStream *in = new MemoryReadStream(data, datasize);
-
- if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry)))
- goto cleanup;
- fix_win32_cursor_icon_file_dir_endian(&dir);
-
- if (dir.reserved != 0) {
- error("not an icon or cursor file (reserved non-zero)");
- goto cleanup;
- }
- if (dir.type != 1 && dir.type != 2) {
- error("not an icon or cursor file (wrong type)");
- goto cleanup;
- }
-
- entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry));
- for (c = 0; c < dir.count; c++) {
- if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry)))
- goto cleanup;
- fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]);
- if (entries[c].reserved != 0)
- error("reserved is not zero");
- }
-
- offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry));
-
- for (completed = 0; completed < dir.count; ) {
- uint32 min_offset = 0x7fffffff;
- int previous = completed;
-
- for (c = 0; c < dir.count; c++) {
- if (entries[c].dib_offset == offset) {
- Win32BitmapInfoHeader bitmap;
- Win32RGBQuad *palette = NULL;
- uint32 palette_count = 0;
- uint32 image_size, mask_size;
- uint32 width, height;
- byte *image_data = NULL, *mask_data = NULL;
- byte *row = NULL;
-
- if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader)))
- goto local_cleanup;
-
- fix_win32_bitmap_info_header_endian(&bitmap);
- if (bitmap.size < sizeof(Win32BitmapInfoHeader)) {
- error("bitmap header is too short");
- goto local_cleanup;
- }
- if (bitmap.compression != 0) {
- error("compressed image data not supported");
- goto local_cleanup;
- }
- if (bitmap.x_pels_per_meter != 0)
- error("x_pels_per_meter field in bitmap should be zero");
- if (bitmap.y_pels_per_meter != 0)
- error("y_pels_per_meter field in bitmap should be zero");
- if (bitmap.clr_important != 0)
- error("clr_important field in bitmap should be zero");
- if (bitmap.planes != 1)
- error("planes field in bitmap should be one");
- if (bitmap.size != sizeof(Win32BitmapInfoHeader)) {
- uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader);
- error("skipping %d bytes of extended bitmap header", skip);
- in->seek(skip, SEEK_CUR);
- }
- offset += bitmap.size;
-
- if (bitmap.clr_used != 0 || bitmap.bit_count < 24) {
- palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count);
- palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count);
- if (!in->read(palette, sizeof(Win32RGBQuad) * palette_count))
- goto local_cleanup;
- offset += sizeof(Win32RGBQuad) * palette_count;
- }
-
- width = bitmap.width;
- height = ABS(bitmap.height)/2;
-
- image_size = height * ROW_BYTES(width * bitmap.bit_count);
- mask_size = height * ROW_BYTES(width);
-
- if (entries[c].dib_size != bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad))
- debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)",
- entries[c].dib_size,
- bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)
- );
-
- image_data = (byte *)malloc(image_size);
- if (!in->read(image_data, image_size))
- goto local_cleanup;
-
- mask_data = (byte *)malloc(mask_size);
- if (!in->read(mask_data, mask_size))
- goto local_cleanup;
-
- offset += image_size;
- offset += mask_size;
- completed++;
- matched++;
-
- *hotspot_x = entries[c].hotspot_x;
- *hotspot_y = entries[c].hotspot_y;
- *w = width;
- *h = height;
- *keycolor = 0;
- *cursor = (byte *)malloc(width * height);
-
- row = (byte *)malloc(width * 4);
-
- for (d = 0; d < height; d++) {
- uint32 x;
- uint32 y = (bitmap.height < 0 ? d : height - d - 1);
- uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count;
- //uint32 mmod = y * (mask_size / height) * 8;
-
- for (x = 0; x < width; x++) {
-
- uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count);
-
- // FIXME?: This works only with b/w cursors and white index may be
- // different. But now it's enough.
- if (color) {
- cursor[0][width * d + x] = 15; // white in SCUMM
- } else {
- cursor[0][width * d + x] = 255; // transparent
- }
- /*
-
- if (bitmap.bit_count <= 16) {
- if (color >= palette_count) {
- error("color out of range in image data");
- goto local_cleanup;
- }
- row[4*x+0] = palette[color].red;
- row[4*x+1] = palette[color].green;
- row[4*x+2] = palette[color].blue;
-
- } else {
- row[4*x+0] = (color >> 16) & 0xFF;
- row[4*x+1] = (color >> 8) & 0xFF;
- row[4*x+2] = (color >> 0) & 0xFF;
- }
- if (bitmap.bit_count == 32)
- row[4*x+3] = (color >> 24) & 0xFF;
- else
- row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF;
- */
- }
-
- }
-
- if (row != NULL)
- free(row);
- if (palette != NULL)
- free(palette);
- if (image_data != NULL) {
- free(image_data);
- free(mask_data);
- }
- continue;
-
- local_cleanup:
-
- if (row != NULL)
- free(row);
- if (palette != NULL)
- free(palette);
- if (image_data != NULL) {
- free(image_data);
- free(mask_data);
- }
- goto cleanup;
- } else {
- if (entries[c].dib_offset > offset)
- min_offset = MIN(min_offset, entries[c].dib_offset);
- }
- }
-
- if (previous == completed) {
- if (min_offset < offset) {
- error("offset of bitmap header incorrect (too low)");
- goto cleanup;
- }
- debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset);
- in->seek(min_offset - offset, SEEK_CUR);
- offset = min_offset;
- }
- }
-
- free(entries);
- return matched;
-
-cleanup:
-
- free(entries);
- return -1;
-}
-
-uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) {
- switch (size) {
- case 1:
- return (data[ofs/8] >> (7 - ofs%8)) & 1;
- case 2:
- return (data[ofs/4] >> ((3 - ofs%4) << 1)) & 3;
- case 4:
- return (data[ofs/2] >> ((1 - ofs%2) << 2)) & 15;
- case 8:
- return data[ofs];
- case 16:
- return data[2*ofs] | data[2*ofs+1] << 8;
- case 24:
- return data[3*ofs] | data[3*ofs+1] << 8 | data[3*ofs+2] << 16;
- case 32:
- return data[4*ofs] | data[4*ofs+1] << 8 | data[4*ofs+2] << 16 | data[4*ofs+3] << 24;
- }
-
- return 0;
-}
-
-#define LE16(x) ((x) = TO_LE_16(x))
-#define LE32(x) ((x) = TO_LE_32(x))
-
-void Win32ResExtractor::fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj) {
- LE16(obj->reserved);
- LE16(obj->type);
- LE16(obj->count);
-}
-
-void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj) {
- LE32(obj->size);
- LE32(obj->width);
- LE32(obj->height);
- LE16(obj->planes);
- LE16(obj->bit_count);
- LE32(obj->compression);
- LE32(obj->size_image);
- LE32(obj->x_pels_per_meter);
- LE32(obj->y_pels_per_meter);
- LE32(obj->clr_used);
- LE32(obj->clr_important);
-}
-
-void Win32ResExtractor::fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj) {
- LE16(obj->hotspot_x);
- LE16(obj->hotspot_y);
- LE32(obj->dib_size);
- LE32(obj->dib_offset);
-}
-
-void Win32ResExtractor::fix_win32_image_section_header(Win32ImageSectionHeader *obj) {
- LE32(obj->misc.physical_address);
- LE32(obj->virtual_address);
- LE32(obj->size_of_raw_data);
- LE32(obj->pointer_to_raw_data);
- LE32(obj->pointer_to_relocations);
- LE32(obj->pointer_to_linenumbers);
- LE16(obj->number_of_relocations);
- LE16(obj->number_of_linenumbers);
- LE32(obj->characteristics);
-}
-
-void Win32ResExtractor::fix_os2_image_header_endian(OS2ImageHeader *obj) {
- LE16(obj->magic);
- LE16(obj->enttab);
- LE16(obj->cbenttab);
- LE32(obj->crc);
- LE16(obj->flags);
- LE16(obj->autodata);
- LE16(obj->heap);
- LE16(obj->stack);
- LE32(obj->csip);
- LE32(obj->sssp);
- LE16(obj->cseg);
- LE16(obj->cmod);
- LE16(obj->cbnrestab);
- LE16(obj->segtab);
- LE16(obj->rsrctab);
- LE16(obj->restab);
- LE16(obj->modtab);
- LE16(obj->imptab);
- LE32(obj->nrestab);
- LE16(obj->cmovent);
- LE16(obj->align);
- LE16(obj->cres);
- LE16(obj->fastload_offset);
- LE16(obj->fastload_length);
- LE16(obj->swaparea);
- LE16(obj->expver);
-}
-
-/* fix_win32_image_header_endian:
- * NOTE: This assumes that the optional header is always available.
- */
-void Win32ResExtractor::fix_win32_image_header_endian(Win32ImageNTHeaders *obj) {
- LE32(obj->signature);
- LE16(obj->file_header.machine);
- LE16(obj->file_header.number_of_sections);
- LE32(obj->file_header.time_date_stamp);
- LE32(obj->file_header.pointer_to_symbol_table);
- LE32(obj->file_header.number_of_symbols);
- LE16(obj->file_header.size_of_optional_header);
- LE16(obj->file_header.characteristics);
- LE16(obj->optional_header.magic);
- LE32(obj->optional_header.size_of_code);
- LE32(obj->optional_header.size_of_initialized_data);
- LE32(obj->optional_header.size_of_uninitialized_data);
- LE32(obj->optional_header.address_of_entry_point);
- LE32(obj->optional_header.base_of_code);
- LE32(obj->optional_header.base_of_data);
- LE32(obj->optional_header.image_base);
- LE32(obj->optional_header.section_alignment);
- LE32(obj->optional_header.file_alignment);
- LE16(obj->optional_header.major_operating_system_version);
- LE16(obj->optional_header.minor_operating_system_version);
- LE16(obj->optional_header.major_image_version);
- LE16(obj->optional_header.minor_image_version);
- LE16(obj->optional_header.major_subsystem_version);
- LE16(obj->optional_header.minor_subsystem_version);
- LE32(obj->optional_header.win32_version_value);
- LE32(obj->optional_header.size_of_image);
- LE32(obj->optional_header.size_of_headers);
- LE32(obj->optional_header.checksum);
- LE16(obj->optional_header.subsystem);
- LE16(obj->optional_header.dll_characteristics);
- LE32(obj->optional_header.size_of_stack_reserve);
- LE32(obj->optional_header.size_of_stack_commit);
- LE32(obj->optional_header.size_of_heap_reserve);
- LE32(obj->optional_header.size_of_heap_commit);
- LE32(obj->optional_header.loader_flags);
- LE32(obj->optional_header.number_of_rva_and_sizes);
-}
-
-void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *obj) {
- LE32(obj->virtual_address);
- LE32(obj->size);
-}
-
-
-MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
- _resOffset = -1;
-}
-
-int MacResExtractor::extractResource(int id, byte **buf) {
- Common::File in;
- int size;
-
- if (!_fileName[0]) // We are running for the first time
- if (_vm->_substResFileNameIndex > 0) {
- char buf1[128];
-
- snprintf(buf1, 128, "%s.he3", _vm->getBaseName());
- _vm->generateSubstResFileName(buf1, _fileName, sizeof(buf1));
-
- // Some programs write it as .bin. Try that too
- if (!in.exists(_fileName)) {
- strcpy(buf1, _fileName);
- snprintf(_fileName, 128, "%s.bin", buf1);
-
- if (!in.exists(_fileName)) {
- // And finally check if we have dumped resource fork
- snprintf(_fileName, 128, "%s.rsrc", buf1);
- if (!in.exists(_fileName)) {
- error("Cannot open file any of files '%s', '%s.bin', '%s.rsrc",
- buf1, buf1, buf1);
- }
- }
- }
- }
-
- in.open(_fileName);
- if (!in.isOpen()) {
- error("Cannot open file %s", _fileName);
- }
-
- // we haven't calculated it
- if (_resOffset == -1) {
- if (!init(in))
- error("Resource fork is missing in file '%s'", _fileName);
- in.close();
- in.open(_fileName);
- }
-
- *buf = getResource(in, "crsr", 1000 + id, &size);
-
- in.close();
-
- if (*buf == NULL)
- error("There is no cursor ID #%d", 1000 + id);
-
- return size;
-}
-
-#define MBI_INFOHDR 128
-#define MBI_ZERO1 0
-#define MBI_NAMELEN 1
-#define MBI_ZERO2 74
-#define MBI_ZERO3 82
-#define MBI_DFLEN 83
-#define MBI_RFLEN 87
-#define MAXNAMELEN 63
-
-bool MacResExtractor::init(Common::File in) {
- byte infoHeader[MBI_INFOHDR];
- int32 data_size, rsrc_size;
- int32 data_size_pad, rsrc_size_pad;
- int filelen;
-
- filelen = in.size();
- in.read(infoHeader, MBI_INFOHDR);
-
- // Maybe we have MacBinary?
- if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
- infoHeader[MBI_ZERO3] == 0 && infoHeader[MBI_NAMELEN] <= MAXNAMELEN) {
-
- // Pull out fork lengths
- data_size = READ_BE_UINT32(infoHeader + MBI_DFLEN);
- rsrc_size = READ_BE_UINT32(infoHeader + MBI_RFLEN);
-
- data_size_pad = (((data_size + 127) >> 7) << 7);
- rsrc_size_pad = (((rsrc_size + 127) >> 7) << 7);
-
- // Length check
- int sumlen = MBI_INFOHDR + data_size_pad + rsrc_size_pad;
-
- if (sumlen == filelen)
- _resOffset = MBI_INFOHDR + data_size_pad;
- }
-
- if (_resOffset == -1) // MacBinary check is failed
- _resOffset = 0; // Maybe we have dumped fork?
-
- in.seek(_resOffset);
-
- _dataOffset = in.readUint32BE() + _resOffset;
- _mapOffset = in.readUint32BE() + _resOffset;
- _dataLength = in.readUint32BE();
- _mapLength = in.readUint32BE();
-
- // do sanity check
- if (_dataOffset >= filelen || _mapOffset >= filelen ||
- _dataLength + _mapLength > filelen) {
- _resOffset = -1;
- return false;
- }
-
- debug(7, "got header: data %d [%d] map %d [%d]",
- _dataOffset, _dataLength, _mapOffset, _mapLength);
-
- readMap(in);
-
- return true;
-}
-
-byte *MacResExtractor::getResource(Common::File in, const char *typeID, int16 resID, int *size) {
- int i;
- int typeNum = -1;
- int resNum = -1;
- byte *buf;
- int len;
-
- for (i = 0; i < _resMap.numTypes; i++)
- if (strcmp(_resTypes[i].id, typeID) == 0) {
- typeNum = i;
- break;
- }
-
- if (typeNum == -1)
- return NULL;
-
- for (i = 0; i < _resTypes[typeNum].items; i++)
- if (_resLists[typeNum][i].id == resID) {
- resNum = i;
- break;
- }
-
- if (resNum == -1)
- return NULL;
-
- in.seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
-
- len = in.readUint32BE();
- buf = (byte *)malloc(len);
-
- in.read(buf, len);
-
- *size = len;
-
- return buf;
-}
-
-void MacResExtractor::readMap(Common::File in) {
- int i, j, len;
-
- in.seek(_mapOffset + 22);
-
- _resMap.resAttr = in.readUint16BE();
- _resMap.typeOffset = in.readUint16BE();
- _resMap.nameOffset = in.readUint16BE();
- _resMap.numTypes = in.readUint16BE();
- _resMap.numTypes++;
-
- in.seek(_mapOffset + _resMap.typeOffset + 2);
- _resTypes = new ResType[_resMap.numTypes];
-
- for (i = 0; i < _resMap.numTypes; i++) {
- in.read(_resTypes[i].id, 4);
- _resTypes[i].id[4] = 0;
- _resTypes[i].items = in.readUint16BE();
- _resTypes[i].offset = in.readUint16BE();
- _resTypes[i].items++;
- }
-
- _resLists = new ResPtr[_resMap.numTypes];
-
- for (i = 0; i < _resMap.numTypes; i++) {
- _resLists[i] = new Resource[_resTypes[i].items];
- in.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
-
- for (j = 0; j < _resTypes[i].items; j++) {
- ResPtr resPtr = _resLists[i] + j;
-
- resPtr->id = in.readUint16BE();
- resPtr->nameOffset = in.readUint16BE();
- resPtr->dataOffset = in.readUint32BE();
- in.readUint32BE();
- resPtr->name = 0;
-
- resPtr->attr = resPtr->dataOffset >> 24;
- resPtr->dataOffset &= 0xFFFFFF;
- }
-
- for (j = 0; j < _resTypes[i].items; j++) {
- if (_resLists[i][j].nameOffset != -1) {
- in.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
-
- len = in.readByte();
- _resLists[i][j].name = new byte[len + 1];
- _resLists[i][j].name[len] = 0;
- in.read(_resLists[i][j].name, len);
- }
- }
- }
-}
-
-int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) {
- Common::MemoryReadStream dis(data, datasize);
- int i, b;
- byte imageByte;
- byte *iconData;
- int numBytes;
- int pixelsPerByte, bpp;
- int ctSize;
- byte bitmask;
- int iconRowBytes, iconBounds[4];
- int ignored;
- int iconDataSize;
-
- dis.readUint16BE(); // type
- dis.readUint32BE(); // offset to pixel map
- dis.readUint32BE(); // offset to pixel data
- dis.readUint32BE(); // expanded cursor data
- dis.readUint16BE(); // expanded data depth
- dis.readUint32BE(); // reserved
-
- // Grab B/W icon data
- *cursor = (byte *)malloc(16 * 16);
- for (i = 0; i < 32; i++) {
- imageByte = dis.readByte();
- for (b = 0; b < 8; b++)
- cursor[0][i*8+b] = (byte)((imageByte &
- (0x80 >> b)) > 0? 0x0F: 0x00);
- }
-
- // Apply mask data
- for (i = 0; i < 32; i++) {
- imageByte = dis.readByte();
- for (b = 0; b < 8; b++)
- if ((imageByte & (0x80 >> b)) == 0)
- cursor[0][i*8+b] = 0xff;
- }
-
- *hotspot_y = dis.readUint16BE();
- *hotspot_x = dis.readUint16BE();
- *w = *h = 16;
-
- // Use b/w cursor on backends which don't support cursor palettes
- if (!_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette))
- return 1;
-
- dis.readUint32BE(); // reserved
- dis.readUint32BE(); // cursorID
-
- // Color version of cursor
- dis.readUint32BE(); // baseAddr
-
- // Keep only lowbyte for now
- dis.readByte();
- iconRowBytes = dis.readByte();
-
- if (!iconRowBytes)
- return 1;
-
- iconBounds[0] = dis.readUint16BE();
- iconBounds[1] = dis.readUint16BE();
- iconBounds[2] = dis.readUint16BE();
- iconBounds[3] = dis.readUint16BE();
-
- dis.readUint16BE(); // pmVersion
- dis.readUint16BE(); // packType
- dis.readUint32BE(); // packSize
-
- dis.readUint32BE(); // hRes
- dis.readUint32BE(); // vRes
-
- dis.readUint16BE(); // pixelType
- dis.readUint16BE(); // pixelSize
- dis.readUint16BE(); // cmpCount
- dis.readUint16BE(); // cmpSize
-
- dis.readUint32BE(); // planeByte
- dis.readUint32BE(); // pmTable
- dis.readUint32BE(); // reserved
-
- // Pixel data for cursor
- iconDataSize = iconRowBytes * (iconBounds[3] - iconBounds[1]);
- iconData = (byte *)malloc(iconDataSize);
- dis.read(iconData, iconDataSize);
-
- // Color table
- dis.readUint32BE(); // ctSeed
- dis.readUint16BE(); // ctFlag
- ctSize = dis.readUint16BE() + 1;
-
- *palette = (byte *)malloc(ctSize * 4);
-
- // Read just high byte of 16-bit color
- for (int c = 0; c < ctSize; c++) {
- // We just use indices 0..ctSize, so ignore color ID
- dis.readUint16BE(); // colorID[c]
-
- palette[0][c * 4 + 0] = dis.readByte();
- ignored = dis.readByte();
-
- palette[0][c * 4 + 1] = dis.readByte();
- ignored = dis.readByte();
-
- palette[0][c * 4 + 2] = dis.readByte();
- ignored = dis.readByte();
-
- palette[0][c * 4 + 3] = 0;
- }
-
- *palSize = ctSize;
-
- numBytes =
- (iconBounds[2] - iconBounds[0]) *
- (iconBounds[3] - iconBounds[1]);
-
- pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes;
- bpp = 8 / pixelsPerByte;
-
- // build a mask to make sure the pixels are properly shifted out
- bitmask = 0;
- for (int m = 0; m < bpp; m++) {
- bitmask <<= 1;
- bitmask |= 1;
- }
-
- // Extract pixels from bytes
- for (int j = 0; j < iconDataSize; j++)
- for (b = 0; b < pixelsPerByte; b++) {
- int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b);
-
- if (cursor[0][idx] != 0xff) // if mask is not there
- cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask);
- }
-
- free(iconData);
-
- assert(datasize - dis.pos() == 0);
-
- return 1;
-}
-
-
-
-void ScummEngine_v70he::readRoomsOffsets() {
- int num, i;
- byte *ptr;
-
- debug(9, "readRoomOffsets()");
-
- num = READ_LE_UINT16(_heV7RoomOffsets);
- ptr = _heV7RoomOffsets + 2;
- for (i = 0; i < num; i++) {
- res.roomoffs[rtRoom][i] = READ_LE_UINT32(ptr);
- ptr += 4;
- }
-}
-
-void ScummEngine_v70he::readGlobalObjects() {
- int num = _fileHandle->readUint16LE();
- assert(num == _numGlobalObjects);
-
- _fileHandle->read(_objectStateTable, num);
- _fileHandle->read(_objectOwnerTable, num);
- _fileHandle->read(_objectRoomTable, num);
-
- _fileHandle->read(_classData, num * sizeof(uint32));
-
-#if defined(SCUMM_BIG_ENDIAN)
- // Correct the endianess if necessary
- for (int i = 0; i != num; i++)
- _classData[i] = FROM_LE_32(_classData[i]);
-#endif
-}
-
-void ScummEngine_v99he::readMAXS(int blockSize) {
- debug(0, "ScummEngine_v99he readMAXS: MAXS has blocksize %d", blockSize);
-
- _numVariables = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numRoomVariables = _fileHandle->readUint16LE();
- _numLocalObjects = _fileHandle->readUint16LE();
- _numArray = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numFlObject = _fileHandle->readUint16LE();
- _numInventory = _fileHandle->readUint16LE();
- _numRooms = _fileHandle->readUint16LE();
- _numScripts = _fileHandle->readUint16LE();
- _numSounds = _fileHandle->readUint16LE();
- _numCharsets = _fileHandle->readUint16LE();
- _numCostumes = _fileHandle->readUint16LE();
- _numGlobalObjects = _fileHandle->readUint16LE();
- _numImages = _fileHandle->readUint16LE();
- _numSprites = _fileHandle->readUint16LE();
- _numLocalScripts = _fileHandle->readUint16LE();
- _HEHeapSize = _fileHandle->readUint16LE();
- _numPalettes = _fileHandle->readUint16LE();
- _numUnk = _fileHandle->readUint16LE();
- _numTalkies = _fileHandle->readUint16LE();
- _numNewNames = 10;
-
- _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
- _numGlobalScripts = 2048;
-}
-
-void ScummEngine_v90he::readMAXS(int blockSize) {
- debug(0, "ScummEngine_v90he readMAXS: MAXS has blocksize %d", blockSize);
-
- _numVariables = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numRoomVariables = _fileHandle->readUint16LE();
- _numLocalObjects = _fileHandle->readUint16LE();
- _numArray = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numFlObject = _fileHandle->readUint16LE();
- _numInventory = _fileHandle->readUint16LE();
- _numRooms = _fileHandle->readUint16LE();
- _numScripts = _fileHandle->readUint16LE();
- _numSounds = _fileHandle->readUint16LE();
- _numCharsets = _fileHandle->readUint16LE();
- _numCostumes = _fileHandle->readUint16LE();
- _numGlobalObjects = _fileHandle->readUint16LE();
- _numImages = _fileHandle->readUint16LE();
- _numSprites = _fileHandle->readUint16LE();
- _numLocalScripts = _fileHandle->readUint16LE();
- _HEHeapSize = _fileHandle->readUint16LE();
- _numNewNames = 10;
-
- _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
- if (_features & GF_HE_985)
- _numGlobalScripts = 2048;
- else
- _numGlobalScripts = 200;
-}
-
-void ScummEngine_v72he::readMAXS(int blockSize) {
- debug(0, "ScummEngine_v72he readMAXS: MAXS has blocksize %d", blockSize);
-
- _numVariables = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numBitVariables = _numRoomVariables = _fileHandle->readUint16LE();
- _numLocalObjects = _fileHandle->readUint16LE();
- _numArray = _fileHandle->readUint16LE();
- _fileHandle->readUint16LE();
- _numVerbs = _fileHandle->readUint16LE();
- _numFlObject = _fileHandle->readUint16LE();
- _numInventory = _fileHandle->readUint16LE();
- _numRooms = _fileHandle->readUint16LE();
- _numScripts = _fileHandle->readUint16LE();
- _numSounds = _fileHandle->readUint16LE();
- _numCharsets = _fileHandle->readUint16LE();
- _numCostumes = _fileHandle->readUint16LE();
- _numGlobalObjects = _fileHandle->readUint16LE();
- _numImages = _fileHandle->readUint16LE();
- _numNewNames = 10;
-
- _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
- _numGlobalScripts = 200;
-}
-
-byte *ScummEngine_v72he::getStringAddress(int i) {
- byte *addr = getResourceAddress(rtString, i);
- if (addr == NULL)
- return NULL;
- return ((ScummEngine_v72he::ArrayHeader *)addr)->data;
-}
-
-int ScummEngine_v72he::getSoundResourceSize(int id) {
- const byte *ptr;
- int offs, size;
-
- if (id > _numSounds) {
- if (!_sound->getHEMusicDetails(id, offs, size)) {
- debug(0, "getSoundResourceSize: musicID %d not found", id);
- return 0;
- }
- } else {
- ptr = getResourceAddress(rtSound, id);
- if (!ptr)
- return 0;
-
- if (READ_UINT32(ptr) == MKID('RIFF')) {
- byte flags;
- int rate;
-
- size = READ_BE_UINT32(ptr + 4);
- Common::MemoryReadStream stream(ptr, size);
-
- if (!loadWAVFromStream(stream, size, rate, flags)) {
- error("getSoundResourceSize: Not a valid WAV file");
- }
- } else {
- ptr += 8 + READ_BE_UINT32(ptr + 12);
- if (READ_UINT32(ptr) == MKID('SBNG')) {
- ptr += READ_BE_UINT32(ptr + 4);
- }
-
- assert(READ_UINT32(ptr) == MKID('SDAT'));
- size = READ_BE_UINT32(ptr + 4) - 8;
- }
- }
-
- return size;
-}
-
-void ScummEngine_v80he::createSound(int snd1id, int snd2id) {
- debug(0, "createSound: snd1id %d snd2id %d", snd1id, snd2id);
-
- byte *snd1Ptr, *snd2Ptr;
- byte *sbng1Ptr, *sbng2Ptr;
- byte *sdat1Ptr, *sdat2Ptr;
- byte *src, *dst, *tmp;
- int len, offs, size;
- int sdat1size, sdat2size;
-
- if (snd2id == -1) {
- _sndPtrOffs = 0;
- _sndTmrOffs = 0;
- return;
- }
-
- if (snd1id != _curSndId) {
- _curSndId = snd1id;
- _sndPtrOffs = 0;
- _sndTmrOffs = 0;
- }
-
- snd1Ptr = getResourceAddress(rtSound, snd1id);
- assert(snd1Ptr);
- snd2Ptr = getResourceAddress(rtSound, snd2id);
- assert(snd2Ptr);
-
- int i;
- int chan = -1;
- for (i = 0; i < ARRAYSIZE(_sound->_heChannel); i++) {
- if (_sound->_heChannel[i].sound == snd1id)
- chan = i;
- }
-
- sbng1Ptr = heFindResource(MKID('SBNG'), snd1Ptr);
- sbng2Ptr = heFindResource(MKID('SBNG'), snd2Ptr);
-
- if (sbng1Ptr != NULL && sbng2Ptr != NULL) {
- if (chan != -1 && _sound->_heChannel[chan].codeOffs > 0) {
- int curOffs = _sound->_heChannel[chan].codeOffs;
-
- src = snd1Ptr + curOffs;
- dst = sbng1Ptr + 8;
- size = READ_BE_UINT32(sbng1Ptr + 4);
- len = sbng1Ptr - snd1Ptr + size - curOffs;
-
- byte *data = (byte *)malloc(len);
- memcpy(data, src, len);
- memcpy(dst, data, len);
- free(data);
-
- dst = sbng1Ptr + 8;
- while ((size = READ_LE_UINT16(dst)) != 0)
- dst += size;
- } else {
- dst = sbng1Ptr + 8;
- }
-
- _sound->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8;
-
- tmp = sbng2Ptr + 8;
- while ((offs = READ_LE_UINT16(tmp)) != 0) {
- tmp += offs;
- }
-
- src = sbng2Ptr + 8;
- len = tmp - sbng2Ptr - 6;
- memcpy(dst, src, len);
-
- int32 time;
- while ((size = READ_LE_UINT16(dst)) != 0) {
- time = READ_LE_UINT32(dst + 2);
- time += _sndTmrOffs;
- WRITE_LE_UINT32(dst + 2, time);
- dst += size;
- }
- }
-
- sdat1Ptr = heFindResource(MKID('SDAT'), snd1Ptr);
- assert(sdat1Ptr);
- sdat2Ptr = heFindResource(MKID('SDAT'), snd2Ptr);
- assert(sdat2Ptr);
-
- sdat1size = READ_BE_UINT32(sdat1Ptr + 4) - 8 - _sndPtrOffs;
- sdat2size = READ_BE_UINT32(sdat2Ptr + 4) - 8;
-
- debug(0, "SDAT size1 %d size2 %d", sdat1size, sdat2size);
- if (sdat2size < sdat1size) {
- src = sdat2Ptr + 8;
- dst = sdat1Ptr + 8 + _sndPtrOffs;
- len = sdat2size;
-
- memcpy(dst, src, len);
-
- _sndPtrOffs += sdat2size;
- _sndTmrOffs += sdat2size;
- } else {
- src = sdat2Ptr + 8;
- dst = sdat1Ptr + 8 + _sndPtrOffs;
- len = sdat1size;
-
- memcpy(dst, src, len);
-
- if (sdat2size != sdat1size) {
- src = sdat2Ptr + 8 + sdat1size;
- dst = sdat1Ptr + 8;
- len = sdat2size - sdat1size;
-
- memcpy(dst, src, len);
- }
-
- _sndPtrOffs = sdat2size - sdat1size;
- _sndTmrOffs += sdat2size;
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/resource_v7he.h b/scumm/resource_v7he.h
deleted file mode 100644
index 1496aa3d7f..0000000000
--- a/scumm/resource_v7he.h
+++ /dev/null
@@ -1,556 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2006 The ScummVM project
- *
- * Parts of code heavily based on:
- * icoutils - A set of programs dealing with MS Windows icons and cursors.
- * Copyright (C) 1998-2001 Oskar Liljeblad
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(RESOURCE_V7HE_H) && !defined(DISABLE_HE)
-#define RESOURCE_V7HE_H
-
-namespace Scumm {
-
-#define WINRES_ID_MAXLEN (256)
-
-/*
- * Definitions
- */
-
-#define ACTION_LIST 1 /* command: list resources */
-#define ACTION_EXTRACT 2 /* command: extract resources */
-#define CALLBACK_STOP 0 /* results of ResourceCallback */
-#define CALLBACK_CONTINUE 1
-#define CALLBACK_CONTINUE_RECURS 2
-
-#define MZ_HEADER(x) ((DOSImageHeader *)(x))
-#define NE_HEADER(x) ((OS2ImageHeader *)PE_HEADER(x))
-#define NE_TYPEINFO_NEXT(x) ((Win16NETypeInfo *)((byte *)(x) + sizeof(Win16NETypeInfo) + \
- ((Win16NETypeInfo *)x)->count * sizeof(Win16NENameInfo)))
-#define NE_RESOURCE_NAME_IS_NUMERIC (0x8000)
-
-#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x)
-
-#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
-#define IMAGE_SIZEOF_SHORT_NAME 8
-
-#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
-#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
-
-#define PE_HEADER(module) \
- ((Win32ImageNTHeaders*)((byte *)(module) + \
- (((DOSImageHeader*)(module))->lfanew)))
-
-#define PE_SECTIONS(module) \
- ((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \
- PE_HEADER(module)->file_header.size_of_optional_header))
-
-#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
-#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
-#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
-#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */
-#define IMAGE_VXD_SIGNATURE 0x454C /* LE */
-#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
-
-#if !defined (WIN32)
-#define IMAGE_SCN_CNT_CODE 0x00000020
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
-#endif
-
-#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
-#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
-#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
-#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
-#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
-#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
-#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
-#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
-#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */
-#define IMAGE_DIRECTORY_ENTRY_TLS 9
-#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
-#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
-#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
-#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
-#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
-
-#if !defined (WIN32)
-#define RT_CURSOR 1
-#define RT_BITMAP 2
-#define RT_ICON 3
-#define RT_MENU 4
-#define RT_DIALOG 5
-#define RT_STRING 6
-#define RT_FONTDIR 7
-#define RT_FONT 8
-#define RT_ACCELERATOR 9
-#define RT_RCDATA 10
-#define RT_MESSAGELIST 11
-#define RT_GROUP_CURSOR 12
-#define RT_GROUP_ICON 14
-#endif
-
-#define RETURN_IF_BAD_POINTER(r, x) \
- if (!check_offset(fi->memory, fi->total_size, fi->file->name(), &(x), sizeof(x))) \
- return (r);
-#define RETURN_IF_BAD_OFFSET(r, x, s) \
- if (!check_offset(fi->memory, fi->total_size, fi->file->name(), x, s)) \
- return (r);
-
-class ScummEngine_v70he;
-
-class ResExtractor {
-public:
- ResExtractor(ScummEngine_v70he *scumm);
- virtual ~ResExtractor();
-
- void setCursor(int id);
-
- virtual int extractResource(int id, byte **buf) { return 0; };
- virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor,
- byte **palette, int *palSize) { return 0; };
-
- enum {
- MAX_CACHED_CURSORS = 10
- };
-
- struct CachedCursor {
- bool valid;
- int id;
- byte *bitmap;
- int w, h;
- int hotspot_x, hotspot_y;
- uint32 last_used;
- byte *palette;
- int palSize;
- };
-
- ScummEngine_v70he *_vm;
-
- ResExtractor::CachedCursor *findCachedCursor(int id);
- ResExtractor::CachedCursor *getCachedCursorSlot();
-
- bool _arg_raw;
- char _fileName[256];
- CachedCursor _cursorCache[MAX_CACHED_CURSORS];
-
- typedef Common::MemoryReadStream MemoryReadStream;
-
-};
-
-class Win32ResExtractor : public ResExtractor {
- public:
- Win32ResExtractor(ScummEngine_v70he *scumm);
- ~Win32ResExtractor() {};
- int extractResource(int id, byte **data);
- void setCursor(int id);
- int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
-
- private:
- int extractResource_(const char *resType, char *resName, byte **data);
-/*
- * Structures
- */
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
- struct WinLibrary {
- Common::File *file;
- byte *memory;
- byte *first_resource;
- bool is_PE_binary;
- int total_size;
- };
-
- struct WinResource {
- char id[256];
- void *this_;
- void *children;
- int level;
- bool numeric_id;
- bool is_directory;
- };
-
-
- struct Win32IconResDir {
- byte width;
- byte height;
- byte color_count;
- byte reserved;
- };
-
- struct Win32CursorDir {
- uint16 width;
- uint16 height;
- };
-
- struct Win32CursorIconDirEntry {
- union {
- Win32IconResDir icon;
- Win32CursorDir cursor;
- } res_info;
- uint16 plane_count;
- uint16 bit_count;
- uint32 bytes_in_res;
- uint16 res_id;
- };
-
- struct Win32CursorIconDir {
- uint16 reserved;
- uint16 type;
- uint16 count;
- Win32CursorIconDirEntry entries[1] GCC_PACK;
- };
-
- struct Win32CursorIconFileDirEntry {
- byte width;
- byte height;
- byte color_count;
- byte reserved;
- uint16 hotspot_x;
- uint16 hotspot_y;
- uint32 dib_size;
- uint32 dib_offset;
- };
-
- struct Win32CursorIconFileDir {
- uint16 reserved;
- uint16 type;
- uint16 count;
- Win32CursorIconFileDirEntry entries[1];
- };
-
- struct Win32BitmapInfoHeader {
- uint32 size;
- int32 width;
- int32 height;
- uint16 planes;
- uint16 bit_count;
- uint32 compression;
- uint32 size_image;
- int32 x_pels_per_meter;
- int32 y_pels_per_meter;
- uint32 clr_used;
- uint32 clr_important;
- };
-
- struct Win32RGBQuad {
- byte blue;
- byte green;
- byte red;
- byte reserved;
- };
-
- struct Win32ImageResourceDirectoryEntry {
- union {
- struct {
- #ifdef SCUMM_BIGENDIAN
- unsigned name_is_string:1;
- unsigned name_offset:31;
- #else
- unsigned name_offset:31;
- unsigned name_is_string:1;
- #endif
- } s1;
- uint32 name;
- struct {
- #ifdef SCUMM_BIG_ENDIAN
- uint16 __pad;
- uint16 id;
- #else
- uint16 id;
- uint16 __pad;
- #endif
- } s2;
- } u1;
- union {
- uint32 offset_to_data;
- struct {
- #ifdef SCUMM_BIG_ENDIAN
- unsigned data_is_directory:1;
- unsigned offset_to_directory:31;
- #else
- unsigned offset_to_directory:31;
- unsigned data_is_directory:1;
- #endif
- } s;
- } u2;
- };
-
- struct Win16NETypeInfo {
- uint16 type_id;
- uint16 count;
- uint32 resloader; // FARPROC16 - smaller? uint16?
- };
-
- struct Win16NENameInfo {
- uint16 offset;
- uint16 length;
- uint16 flags;
- uint16 id;
- uint16 handle;
- uint16 usage;
- };
-
- struct OS2ImageHeader {
- uint16 magic;
- byte ver;
- byte rev;
- uint16 enttab;
- uint16 cbenttab;
- int32 crc;
- uint16 flags;
- uint16 autodata;
- uint16 heap;
- uint16 stack;
- uint32 csip;
- uint32 sssp;
- uint16 cseg;
- uint16 cmod;
- uint16 cbnrestab;
- uint16 segtab;
- uint16 rsrctab;
- uint16 restab;
- uint16 modtab;
- uint16 imptab;
- uint32 nrestab;
- uint16 cmovent;
- uint16 align;
- uint16 cres;
- byte exetyp;
- byte flagsothers;
- uint16 fastload_offset;
- uint16 fastload_length;
- uint16 swaparea;
- uint16 expver;
- };
-
- struct DOSImageHeader {
- uint16 magic;
- uint16 cblp;
- uint16 cp;
- uint16 crlc;
- uint16 cparhdr;
- uint16 minalloc;
- uint16 maxalloc;
- uint16 ss;
- uint16 sp;
- uint16 csum;
- uint16 ip;
- uint16 cs;
- uint16 lfarlc;
- uint16 ovno;
- uint16 res[4];
- uint16 oemid;
- uint16 oeminfo;
- uint16 res2[10];
- uint32 lfanew;
- };
-
- struct Win32ImageFileHeader {
- uint16 machine;
- uint16 number_of_sections;
- uint32 time_date_stamp;
- uint32 pointer_to_symbol_table;
- uint32 number_of_symbols;
- uint16 size_of_optional_header;
- uint16 characteristics;
- };
-
- struct Win32ImageDataDirectory {
- uint32 virtual_address;
- uint32 size;
- };
-
- struct Win32ImageOptionalHeader {
- uint16 magic;
- byte major_linker_version;
- byte minor_linker_version;
- uint32 size_of_code;
- uint32 size_of_initialized_data;
- uint32 size_of_uninitialized_data;
- uint32 address_of_entry_point;
- uint32 base_of_code;
- uint32 base_of_data;
- uint32 image_base;
- uint32 section_alignment;
- uint32 file_alignment;
- uint16 major_operating_system_version;
- uint16 minor_operating_system_version;
- uint16 major_image_version;
- uint16 minor_image_version;
- uint16 major_subsystem_version;
- uint16 minor_subsystem_version;
- uint32 win32_version_value;
- uint32 size_of_image;
- uint32 size_of_headers;
- uint32 checksum;
- uint16 subsystem;
- uint16 dll_characteristics;
- uint32 size_of_stack_reserve;
- uint32 size_of_stack_commit;
- uint32 size_of_heap_reserve;
- uint32 size_of_heap_commit;
- uint32 loader_flags;
- uint32 number_of_rva_and_sizes;
- Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- };
-
- struct Win32ImageNTHeaders {
- uint32 signature;
- Win32ImageFileHeader file_header;
- Win32ImageOptionalHeader optional_header;
- };
-
- struct Win32ImageSectionHeader {
- byte name[IMAGE_SIZEOF_SHORT_NAME];
- union {
- uint32 physical_address;
- uint32 virtual_size;
- } misc;
- uint32 virtual_address;
- uint32 size_of_raw_data;
- uint32 pointer_to_raw_data;
- uint32 pointer_to_relocations;
- uint32 pointer_to_linenumbers;
- uint16 number_of_relocations;
- uint16 number_of_linenumbers;
- uint32 characteristics;
- };
-
- struct Win32ImageResourceDataEntry {
- uint32 offset_to_data;
- uint32 size;
- uint32 code_page;
- uint32 resource_handle;
- };
-
- struct Win32ImageResourceDirectory {
- uint32 characteristics;
- uint32 time_date_stamp;
- uint16 major_version;
- uint16 minor_version;
- uint16 number_of_named_entries;
- uint16 number_of_id_entries;
- };
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-/*
- * Function Prototypes
- */
-
- WinResource *list_resources(WinLibrary *, WinResource *, int *);
- bool read_library(WinLibrary *);
- WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *);
- byte *get_resource_entry(WinLibrary *, WinResource *, int *);
- int do_resources(WinLibrary *, const char *, char *, char *, int, byte **);
- bool compare_resource_id(WinResource *, const char *);
- const char *res_type_string_to_id(const char *);
-
- const char *res_type_id_to_string(int);
- char *get_destination_name(WinLibrary *, char *, char *, char *);
-
- byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool);
- int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **);
- byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool);
-
- bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32);
- bool decode_ne_resource_id(WinLibrary *, WinResource *, uint16);
- WinResource *list_ne_type_resources(WinLibrary *, int *);
- WinResource *list_ne_name_resources(WinLibrary *, WinResource *, int *);
- WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *);
- int calc_vma_size(WinLibrary *);
- int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, int, byte **);
- char *get_resource_id_quoted(WinResource *);
- WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *);
-
- bool check_offset(byte *, int, const char *, void *, int);
-
- uint32 simple_vec(byte *data, uint32 ofs, byte size);
-
- void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj);
- void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj);
- void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj);
- void fix_win32_image_section_header(Win32ImageSectionHeader *obj);
- void fix_os2_image_header_endian(OS2ImageHeader *obj);
- void fix_win32_image_header_endian(Win32ImageNTHeaders *obj);
- void fix_win32_image_data_directory(Win32ImageDataDirectory *obj);
-};
-
-class MacResExtractor : public ResExtractor {
-
-public:
- MacResExtractor(ScummEngine_v70he *scumm);
- ~MacResExtractor() { }
- void setCursor(int id) ;
-
-private:
- int extractResource(int id, byte **buf);
- bool init(Common::File in);
- void readMap(Common::File in);
- byte *getResource(Common::File in, const char *typeID, int16 resID, int *size);
- int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
- int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
-
- struct ResMap {
- int16 resAttr;
- int16 typeOffset;
- int16 nameOffset;
- int16 numTypes;
- };
-
- struct ResType {
- char id[5];
- int16 items;
- int16 offset;
- };
-
- struct Resource {
- int16 id;
- int16 nameOffset;
- byte attr;
- int32 dataOffset;
- byte *name;
- };
-
- typedef Resource *ResPtr;
-
-private:
- int _resOffset;
- int32 _dataOffset;
- int32 _dataLength;
- int32 _mapOffset;
- int32 _mapLength;
- ResMap _resMap;
- ResType *_resTypes;
- ResPtr *_resLists;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/room.cpp b/scumm/room.cpp
deleted file mode 100644
index e53b13c663..0000000000
--- a/scumm/room.cpp
+++ /dev/null
@@ -1,751 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/actor.h"
-#include "scumm/boxes.h"
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-/**
- * Start a 'scene' by loading the specified room with the given main actor.
- * The actor is placed next to the object indicated by objectNr.
- */
-void ScummEngine::startScene(int room, Actor *a, int objectNr) {
- int i, where;
-
- CHECK_HEAP;
- debugC(DEBUG_GENERAL, "Loading room %d", room);
-
- stopTalk();
-
- fadeOut(_switchRoomEffect2);
- _newEffect = _switchRoomEffect;
-
- ScriptSlot *ss = &vm.slot[_currentScript];
-
- if (_currentScript != 0xFF) {
- if (ss->where == WIO_ROOM || ss->where == WIO_FLOBJECT) {
- if (ss->cutsceneOverride && _version >= 5)
- error("Object %d stopped with active cutscene/override in exit", ss->number);
-
- nukeArrays(_currentScript);
- _currentScript = 0xFF;
- } else if (ss->where == WIO_LOCAL) {
- if (ss->cutsceneOverride && _version >= 5)
- error("Script %d stopped with active cutscene/override in exit", ss->number);
-
- nukeArrays(_currentScript);
- _currentScript = 0xFF;
- }
- }
-
- if (VAR_NEW_ROOM != 0xFF)
- VAR(VAR_NEW_ROOM) = room;
-
- runExitScript();
-
- killScriptsAndResources();
- if (_version >= 4 && _heversion <= 61)
- stopCycle(0);
- _sound->processSound();
-
- clearDrawQueues();
-
- // For HE80+ games
- for (i = 0; i < _numRoomVariables; i++)
- _roomVars[i] = 0;
- nukeArrays(0xFF);
-
- for (i = 1; i < _numActors; i++) {
- _actors[i].hideActor();
- }
-
- if (_version >= 7) {
- // Set the shadow palette(s) to all black. This fixes
- // bug #795940, and actually makes some sense (after all,
- // shadows tend to be rather black, don't they? ;-)
- memset(_shadowPalette, 0, NUM_SHADOW_PALETTE * 256);
- } else {
- for (i = 0; i < 256; i++) {
- _roomPalette[i] = i;
- if (_shadowPalette)
- _shadowPalette[i] = i;
- }
- if (_features & GF_SMALL_HEADER)
- setDirtyColors(0, 255);
- }
-
- VAR(VAR_ROOM) = room;
- _fullRedraw = true;
-
- res.increaseResourceCounter();
-
- _activeObject = 0;
- _currentRoom = room;
- VAR(VAR_ROOM) = room;
-
- if (room >= 0x80 && _version < 7 && _heversion <= 71)
- _roomResource = _resourceMapper[room & 0x7F];
- else
- _roomResource = room;
-
- if (VAR_ROOM_RESOURCE != 0xFF)
- VAR(VAR_ROOM_RESOURCE) = _roomResource;
-
- if (room != 0)
- ensureResourceLoaded(rtRoom, room);
-
- clearRoomObjects();
-
- if (_currentRoom == 0) {
- _ENCD_offs = _EXCD_offs = 0;
- _numObjectsInRoom = 0;
- restoreFlObjects();
- return;
- }
-
- loadRoomSubBlocks();
- initRoomSubBlocks();
-
- initBGBuffers(_roomHeight);
-
- loadRoomObjects();
- restoreFlObjects();
-
- if (VAR_ROOM_WIDTH != 0xFF && VAR_ROOM_HEIGHT != 0xFF) {
- VAR(VAR_ROOM_WIDTH) = _roomWidth;
- VAR(VAR_ROOM_HEIGHT) = _roomHeight;
- }
-
- VAR(VAR_CAMERA_MIN_X) = _screenWidth / 2;
- VAR(VAR_CAMERA_MAX_X) = _roomWidth - (_screenWidth / 2);
-
- if (_features & GF_NEW_CAMERA) {
- VAR(VAR_CAMERA_MIN_Y) = _screenHeight / 2;
- VAR(VAR_CAMERA_MAX_Y) = _roomHeight - (_screenHeight / 2);
- setCameraAt(_screenWidth / 2, _screenHeight / 2);
- } else {
- camera._mode = kNormalCameraMode;
- if (_version > 2)
- camera._cur.x = camera._dest.x = _screenWidth / 2;
- camera._cur.y = camera._dest.y = _screenHeight / 2;
- }
-
- if (_roomResource == 0)
- return;
-
- memset(gfxUsageBits, 0, sizeof(gfxUsageBits));
-
- if (_version >= 5 && a) {
- where = whereIsObject(objectNr);
- if (where != WIO_ROOM && where != WIO_FLOBJECT)
- error("startScene: Object %d is not in room %d", objectNr,
- _currentRoom);
- int x, y, dir;
- getObjectXYPos(objectNr, x, y, dir);
- a->putActor(x, y, _currentRoom);
- a->setDirection(dir + 180);
- a->stopActorMoving();
- if (_gameId == GID_SAMNMAX) {
- camera._cur.x = camera._dest.x = a->_pos.x;
- setCameraAt(a->_pos.x, a->_pos.y);
- }
- }
-
- showActors();
-
- _egoPositioned = false;
- runEntryScript();
- if ((_version <= 2) && !(_platform == Common::kPlatformC64)) {
- runScript(5, 0, 0, 0);
- } else if (_version >= 5 && _version <= 6) {
- if (a && !_egoPositioned) {
- int x, y;
- getObjectXYPos(objectNr, x, y);
- a->putActor(x, y, _currentRoom);
- a->_moving = 0;
- }
- } else if (_version >= 7) {
- if (camera._follows) {
- a = derefActor(camera._follows, "startScene: follows");
- setCameraAt(a->_pos.x, a->_pos.y);
- }
- }
-
- _doEffect = true;
-
- CHECK_HEAP;
-}
-
-/**
- * Init some static room data after a room has been loaded.
- * E.g. the room dimension, the offset to the graphics data, the room scripts,
- * the offset to the room palette and other things which won't be changed
- * late on.
- * So it is possible to call this after loading a savegame.
- */
-void ScummEngine::loadRoomSubBlocks() {
- int i;
- const byte *ptr;
- byte *roomptr, *searchptr, *roomResPtr = 0;
- const RoomHeader *rmhd;
-
- _ENCD_offs = 0;
- _EXCD_offs = 0;
- _EPAL_offs = 0;
- _CLUT_offs = 0;
- _PALS_offs = 0;
-
- // Determine the room and room script base address
- roomResPtr = roomptr = getResourceAddress(rtRoom, _roomResource);
- if (_version == 8)
- roomResPtr = getResourceAddress(rtRoomScripts, _roomResource);
- if (!roomptr || !roomResPtr)
- error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__);
-
- //
- // Determine the room dimensions (width/height)
- //
- rmhd = (const RoomHeader *)findResourceData(MKID('RMHD'), roomptr);
-
- if (_version == 8) {
- _roomWidth = READ_LE_UINT32(&(rmhd->v8.width));
- _roomHeight = READ_LE_UINT32(&(rmhd->v8.height));
- _numObjectsInRoom = (byte)READ_LE_UINT32(&(rmhd->v8.numObjects));
- } else if (_version == 7) {
- _roomWidth = READ_LE_UINT16(&(rmhd->v7.width));
- _roomHeight = READ_LE_UINT16(&(rmhd->v7.height));
- _numObjectsInRoom = (byte)READ_LE_UINT16(&(rmhd->v7.numObjects));
- } else {
- _roomWidth = READ_LE_UINT16(&(rmhd->old.width));
- _roomHeight = READ_LE_UINT16(&(rmhd->old.height));
- _numObjectsInRoom = (byte)READ_LE_UINT16(&(rmhd->old.numObjects));
- }
-
- //
- // Find the room image data
- //
- if (_version == 8) {
- _IM00_offs = getObjectImage(roomptr, 1) - roomptr;
- } else if (_features & GF_SMALL_HEADER) {
- _IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr;
- } else if (_heversion >= 70) {
- byte *roomImagePtr = getResourceAddress(rtRoomImage, _roomResource);
- _IM00_offs = findResource(MKID('IM00'), roomImagePtr) - roomImagePtr;
- } else {
- _IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr)) - roomptr;
- }
-
- //
- // Look for an exit script
- //
- ptr = findResourceData(MKID('EXCD'), roomResPtr);
- if (ptr)
- _EXCD_offs = ptr - roomResPtr;
- if (_dumpScripts && _EXCD_offs)
- dumpResource("exit-", _roomResource, roomResPtr + _EXCD_offs - _resourceHeaderSize, -1);
-
- //
- // Look for an entry script
- //
- ptr = findResourceData(MKID('ENCD'), roomResPtr);
- if (ptr)
- _ENCD_offs = ptr - roomResPtr;
- if (_dumpScripts && _ENCD_offs)
- dumpResource("entry-", _roomResource, roomResPtr + _ENCD_offs - _resourceHeaderSize, -1);
-
- //
- // Setup local scripts
- //
-
- // Determine the room script base address
- roomResPtr = roomptr = getResourceAddress(rtRoom, _roomResource);
- if (_version == 8)
- roomResPtr = getResourceAddress(rtRoomScripts, _roomResource);
- searchptr = roomResPtr;
-
- memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets));
-
- if (_features & GF_SMALL_HEADER) {
- ResourceIterator localScriptIterator(searchptr, true);
- while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) {
- int id = 0;
- ptr += _resourceHeaderSize; /* skip tag & size */
- id = ptr[0];
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "room-%d-", _roomResource);
- dumpResource(buf, id, ptr - _resourceHeaderSize);
- }
-
- _localScriptOffsets[id - _numGlobalScripts] = ptr + 1 - roomptr;
- }
- } else if (_heversion >= 90) {
- ResourceIterator localScriptIterator2(searchptr, false);
- while ((ptr = localScriptIterator2.findNext(MKID('LSC2'))) != NULL) {
- int id = 0;
-
- ptr += _resourceHeaderSize; /* skip tag & size */
-
- id = READ_LE_UINT32(ptr);
-
- checkRange(_numLocalScripts + _numGlobalScripts, _numGlobalScripts, id, "Invalid local script %d");
- _localScriptOffsets[id - _numGlobalScripts] = ptr + 4 - roomResPtr;
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "room-%d-", _roomResource);
- dumpResource(buf, id, ptr - _resourceHeaderSize);
- }
- }
-
- ResourceIterator localScriptIterator(searchptr, false);
- while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) {
- int id = 0;
-
- ptr += _resourceHeaderSize; /* skip tag & size */
-
- id = ptr[0];
- _localScriptOffsets[id - _numGlobalScripts] = ptr + 1 - roomResPtr;
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "room-%d-", _roomResource);
- dumpResource(buf, id, ptr - _resourceHeaderSize);
- }
- }
-
- } else {
- ResourceIterator localScriptIterator(searchptr, false);
- while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) {
- int id = 0;
-
- ptr += _resourceHeaderSize; /* skip tag & size */
-
- if (_version == 8) {
- id = READ_LE_UINT32(ptr);
- checkRange(_numLocalScripts + _numGlobalScripts, _numGlobalScripts, id, "Invalid local script %d");
- _localScriptOffsets[id - _numGlobalScripts] = ptr + 4 - roomResPtr;
- } else if (_version == 7) {
- id = READ_LE_UINT16(ptr);
- checkRange(_numLocalScripts + _numGlobalScripts, _numGlobalScripts, id, "Invalid local script %d");
- _localScriptOffsets[id - _numGlobalScripts] = ptr + 2 - roomResPtr;
- } else {
- id = ptr[0];
- _localScriptOffsets[id - _numGlobalScripts] = ptr + 1 - roomResPtr;
- }
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "room-%d-", _roomResource);
- dumpResource(buf, id, ptr - _resourceHeaderSize);
- }
- }
- }
-
- // Locate the EGA palette (currently unused).
- ptr = findResourceData(MKID('EPAL'), roomptr);
- if (ptr)
- _EPAL_offs = ptr - roomptr;
-
- // Locate the standard room palette (for V3-V5 games).
- ptr = findResourceData(MKID('CLUT'), roomptr);
- if (ptr)
- _CLUT_offs = ptr - roomptr;
-
- // Locate the standard room palettes (for V6+ games).
- if (_version >= 6) {
- ptr = findResource(MKID('PALS'), roomptr);
- if (ptr) {
- _PALS_offs = ptr - roomptr;
- }
- }
-
- // Transparent color
- byte trans;
- if (_version == 8)
- trans = (byte)READ_LE_UINT32(&(rmhd->v8.transparency));
- else {
- ptr = findResourceData(MKID('TRNS'), roomptr);
- if (ptr)
- trans = ptr[0];
- else
- trans = 255;
- }
-
- // Actor Palette in HE 70 games
- if (_heversion == 70) {
- ptr = findResourceData(MKID('REMP'), roomptr);
- if (ptr) {
- for (i = 0; i < 256; i++)
- _HEV7ActorPalette[i] = *ptr++;
- } else {
- for (i = 0; i < 256; i++)
- _HEV7ActorPalette[i] = i;
- }
- }
-
-
- // WORKAROUND bug #1074444: The dreaded DOTT "Can't get teeth" bug
- // makes it impossible to go on playing w/o cheating in some way.
- // It's not quite clear what causes it, but the effect is that object
- // 182, the teeth, are still in class 32 (kObjectClassUntouchable),
- // when they shouldn't be. Luckily, bitvar69 is set to 1 if and only if
- // the teeth are trapped and have not yet been taken by the player. So
- // we can make use of that fact to fix the object class of obj 182.
- if (_gameId == GID_TENTACLE && _roomResource == 26 && readVar(0x8000 + 69)
- && getClass(182, kObjectClassUntouchable)) {
- putClass(182, kObjectClassUntouchable, 0);
- }
-
- gdi.roomChanged(roomptr, _IM00_offs, trans);
-}
-
-/**
- * Init some dynamic room data after a room has been loaded.
- * E.g. the initial box data is loaded, the initial palette is set etc.
- * All of the things setup in here can be modified later on by scripts.
- * So it is not appropriate to call it after loading a savegame.
- */
-void ScummEngine::initRoomSubBlocks() {
- int i;
- const byte *ptr;
- byte *roomptr;
-
- // Determine the room and room script base address
- roomptr = getResourceAddress(rtRoom, _roomResource);
- if (!roomptr)
- error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__);
-
- //
- // Load box data
- //
- memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));
-
- res.nukeResource(rtMatrix, 1);
- res.nukeResource(rtMatrix, 2);
- if (_features & GF_SMALL_HEADER) {
- ptr = findResourceData(MKID('BOXD'), roomptr);
- if (ptr) {
- byte numOfBoxes = *ptr;
- int size;
- if (_version == 3)
- size = numOfBoxes * SIZEOF_BOX_V3 + 1;
- else
- size = numOfBoxes * SIZEOF_BOX + 1;
-
- res.createResource(rtMatrix, 2, size);
- memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
- ptr += size;
-
- size = getResourceDataSize(ptr - size - _resourceHeaderSize) - size;
- if (size > 0) { // do this :)
- res.createResource(rtMatrix, 1, size);
- memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
- }
-
- }
- } else {
- ptr = findResourceData(MKID('BOXD'), roomptr);
- if (ptr) {
- int size = getResourceDataSize(ptr);
- res.createResource(rtMatrix, 2, size);
- roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResourceData(MKID('BOXD'), roomptr);
- memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
- }
-
- ptr = findResourceData(MKID('BOXM'), roomptr);
- if (ptr) {
- int size = getResourceDataSize(ptr);
- res.createResource(rtMatrix, 1, size);
- roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResourceData(MKID('BOXM'), roomptr);
- memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
- }
- }
-
- //
- // Load scale data
- //
- for (i = 1; i < res.num[rtScaleTable]; i++)
- res.nukeResource(rtScaleTable, i);
-
- ptr = findResourceData(MKID('SCAL'), roomptr);
- if (ptr) {
- int s1, s2, y1, y2;
- if (_version == 8) {
- for (i = 1; i < res.num[rtScaleTable]; i++, ptr += 16) {
- s1 = READ_LE_UINT32(ptr);
- y1 = READ_LE_UINT32(ptr + 4);
- s2 = READ_LE_UINT32(ptr + 8);
- y2 = READ_LE_UINT32(ptr + 12);
- setScaleSlot(i, 0, y1, s1, 0, y2, s2);
- }
- } else {
- for (i = 1; i < res.num[rtScaleTable]; i++, ptr += 8) {
- s1 = READ_LE_UINT16(ptr);
- y1 = READ_LE_UINT16(ptr + 2);
- s2 = READ_LE_UINT16(ptr + 4);
- y2 = READ_LE_UINT16(ptr + 6);
- if (s1 || y1 || s2 || y2) {
- setScaleSlot(i, 0, y1, s1, 0, y2, s2);
- }
- }
- }
- }
-
- // Color cycling
- // HE 7.0 games load resources but don't use them.
- if (_version >= 4 && _heversion <= 61) {
- ptr = findResourceData(MKID('CYCL'), roomptr);
- if (ptr) {
- initCycl(ptr);
- }
- }
-
-#ifndef DISABLE_HE
- // Polygons in HE 80+ games
- if (_heversion >= 80) {
- ptr = findResourceData(MKID('POLD'), roomptr);
- if (ptr) {
- ((ScummEngine_v70he *)this)->_wiz->polygonLoad(ptr);
- }
- }
-#endif
-
- if (_PALS_offs || _CLUT_offs)
- setPalette(0);
-}
-
-
-void ScummEngine_v3old::loadRoomSubBlocks() {
- const byte *ptr;
- byte *roomptr, *searchptr = 0;
- const RoomHeader *rmhd;
-
- _ENCD_offs = 0;
- _EXCD_offs = 0;
- _EPAL_offs = 0;
- _CLUT_offs = 0;
- _PALS_offs = 0;
-
- // Determine the room and room script base address
- roomptr = getResourceAddress(rtRoom, _roomResource);
- if (!roomptr)
- error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__);
-
- //
- // Determine the room dimensions (width/height)
- //
- rmhd = (const RoomHeader *)(roomptr + 4);
-
- if (_version == 1) {
- if (_platform == Common::kPlatformNES) {
- _roomWidth = READ_LE_UINT16(&(rmhd->old.width)) * 8;
- _roomHeight = READ_LE_UINT16(&(rmhd->old.height)) * 8;
-
- // HACK: To let our code work normal with narrow rooms we
- // adjust width. It will render garbage on right edge but we do
- // not render it anyway
- if (_roomWidth < 32 * 8)
- _roomWidth = 32 * 8;
- } else {
- _roomWidth = roomptr[4] * 8;
- _roomHeight = roomptr[5] * 8;
- }
- } else {
- _roomWidth = READ_LE_UINT16(&(rmhd->old.width));
- _roomHeight = READ_LE_UINT16(&(rmhd->old.height));
- }
- _numObjectsInRoom = roomptr[20];
-
- //
- // Find the room image data
- //
- if (_version == 1) {
- _IM00_offs = 0;
- } else {
- _IM00_offs = READ_LE_UINT16(roomptr + 0x0A);
- }
-
- //
- // Look for an exit script
- //
- int EXCD_len = -1;
- if (_version <= 2) {
- _EXCD_offs = READ_LE_UINT16(roomptr + 0x18);
- EXCD_len = READ_LE_UINT16(roomptr + 0x1A) - _EXCD_offs + _resourceHeaderSize; // HACK
- } else {
- _EXCD_offs = READ_LE_UINT16(roomptr + 0x19);
- EXCD_len = READ_LE_UINT16(roomptr + 0x1B) - _EXCD_offs + _resourceHeaderSize; // HACK
- }
- if (_dumpScripts && _EXCD_offs)
- dumpResource("exit-", _roomResource, roomptr + _EXCD_offs - _resourceHeaderSize, EXCD_len);
-
- //
- // Look for an entry script
- //
- int ENCD_len = -1;
- if (_version <= 2) {
- _ENCD_offs = READ_LE_UINT16(roomptr + 0x1A);
- ENCD_len = READ_LE_UINT16(roomptr) - _ENCD_offs + _resourceHeaderSize; // HACK
- } else {
- _ENCD_offs = READ_LE_UINT16(roomptr + 0x1B);
- // FIXME - the following is a hack which assumes that immediately after
- // the entry script the first local script follows.
- int num_objects = *(roomptr + 20);
- int num_sounds = *(roomptr + 23);
- int num_scripts = *(roomptr + 24);
- ptr = roomptr + 29 + num_objects * 4 + num_sounds + num_scripts;
- ENCD_len = READ_LE_UINT16(ptr + 1) - _ENCD_offs + _resourceHeaderSize; // HACK
- }
- if (_dumpScripts && _ENCD_offs)
- dumpResource("entry-", _roomResource, roomptr + _ENCD_offs - _resourceHeaderSize, ENCD_len);
-
- //
- // Setup local scripts
- //
-
- // Determine the room script base address
- roomptr = getResourceAddress(rtRoom, _roomResource);
- searchptr = roomptr;
-
- memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets));
-
- int num_objects = *(roomptr + 20);
- int num_sounds;
- int num_scripts;
-
- if (_version <= 2) {
- num_sounds = *(roomptr + 22);
- num_scripts = *(roomptr + 23);
- ptr = roomptr + 28 + num_objects * 4;
- while (num_sounds--)
- loadResource(rtSound, *ptr++);
- while (num_scripts--)
- loadResource(rtScript, *ptr++);
- } else /* if (_version == 3) */ {
- num_sounds = *(roomptr + 23);
- num_scripts = *(roomptr + 24);
- ptr = roomptr + 29 + num_objects * 4 + num_sounds + num_scripts;
- while (*ptr) {
- int id = *ptr;
-
- _localScriptOffsets[id - _numGlobalScripts] = READ_LE_UINT16(ptr + 1);
- ptr += 3;
-
- if (_dumpScripts) {
- char buf[32];
- sprintf(buf, "room-%d-", _roomResource);
-
- // HACK: to determine the sizes of the local scripts, we assume that
- // a) their order in the data file is the same as in the index
- // b) the last script at the same time is the last item in the room "header"
- int len = - (int)_localScriptOffsets[id - _numGlobalScripts] + _resourceHeaderSize;
- if (*ptr)
- len += READ_LE_UINT16(ptr + 1);
- else
- len += READ_LE_UINT16(roomptr);
- dumpResource(buf, id, roomptr + _localScriptOffsets[id - _numGlobalScripts] - _resourceHeaderSize, len);
- }
- }
- }
-
- gdi.roomChanged(roomptr, _IM00_offs, 255);
-}
-
-void ScummEngine_v3old::initRoomSubBlocks() {
- int i;
- const byte *ptr;
- byte *roomptr;
-
- // Determine the room and room script base address
- roomptr = getResourceAddress(rtRoom, _roomResource);
- if (!roomptr)
- error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__);
-
- // Reset room color for V1 zak
- if (_version == 1)
- _roomPalette[0] = 0;
-
- //
- // Load box data
- //
- res.nukeResource(rtMatrix, 1);
- res.nukeResource(rtMatrix, 2);
-
- // TODO: Convert older walkbox format
- if (_gameId == GID_MANIAC && _platform == Common::kPlatformC64)
- return;
-
- if (_version <= 2)
- ptr = roomptr + *(roomptr + 0x15);
- else
- ptr = roomptr + READ_LE_UINT16(roomptr + 0x15);
- if (ptr) {
- byte numOfBoxes = *ptr;
- int size;
- if (_version <= 2)
- size = numOfBoxes * SIZEOF_BOX_V2 + 1;
- else
- size = numOfBoxes * SIZEOF_BOX_V3 + 1;
-
- res.createResource(rtMatrix, 2, size);
- memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
- ptr += size;
- if (_version <= 2) {
- size = numOfBoxes * (numOfBoxes + 1);
- } else {
- // FIXME. This is an evil HACK!!!
- size = (READ_LE_UINT16(roomptr + 0x0A) - READ_LE_UINT16(roomptr + 0x15)) - size;
- }
-
- if (size > 0) { // do this :)
- res.createResource(rtMatrix, 1, size);
- memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
- }
-
- }
-
- //
- // No scale data in old bundle games
- //
- for (i = 1; i < res.num[rtScaleTable]; i++)
- res.nukeResource(rtScaleTable, i);
-
-}
-
-} // End of namespace Scumm
diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp
deleted file mode 100644
index 9dca7abd40..0000000000
--- a/scumm/saveload.cpp
+++ /dev/null
@@ -1,1648 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-#include "common/savefile.h"
-#include "common/system.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse.h"
-#include "scumm/intern.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/sprite_he.h"
-#include "scumm/verbs.h"
-
-#include "sound/audiocd.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-struct SaveGameHeader {
- uint32 type;
- uint32 size;
- uint32 ver;
- char name[32];
-};
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
-struct SaveInfoSection {
- uint32 type;
- uint32 version;
- uint32 size;
-
- uint32 timeTValue; // Obsolete since version 2, but kept for compatibility
- uint32 playtime;
-
- uint32 date;
- uint16 time;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-#define INFOSECTION_VERSION 2
-
-void ScummEngine::requestSave(int slot, const char *name, bool temporary) {
- _saveLoadSlot = slot;
- _saveTemporaryState = temporary;
- _saveLoadFlag = 1; // 1 for save
- assert(name);
- strncpy(_saveLoadName, name, sizeof(_saveLoadName));
- _saveLoadName[sizeof(_saveLoadName) - 1] = 0;
-}
-
-void ScummEngine::requestLoad(int slot) {
- _saveLoadSlot = slot;
- _saveTemporaryState = false;
- _saveLoadFlag = 2; // 2 for load
-}
-
-bool ScummEngine::saveState(int slot, bool compat) {
- char filename[256];
- Common::OutSaveFile *out;
- SaveGameHeader hdr;
-
- makeSavegameName(filename, slot, compat);
-
- if (!(out = _saveFileMan->openForSaving(filename)))
- return false;
-
- memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
-
- hdr.type = MKID('SCVM');
- hdr.size = 0;
- hdr.ver = TO_LE_32(CURRENT_VER);
-
- out->write(&hdr, sizeof(hdr));
- saveThumbnail(out);
- saveInfos(out);
-
- Serializer ser(0, out, CURRENT_VER);
- saveOrLoad(&ser);
- out->flush();
- if(out->ioFailed()) {
- delete out;
- debug(1, "State save as '%s' FAILED", filename);
- return false;
- }
- delete out;
- debug(1, "State saved as '%s'", filename);
- return true;
-}
-
-bool ScummEngine::loadState(int slot, bool compat) {
- char filename[256];
- Common::InSaveFile *in;
- int i, j;
- SaveGameHeader hdr;
- int sb, sh;
-
- makeSavegameName(filename, slot, compat);
- if (!(in = _saveFileMan->openForLoading(filename)))
- return false;
-
- in->read(&hdr, sizeof(hdr));
- if (hdr.type != MKID('SCVM')) {
- warning("Invalid savegame '%s'", filename);
- delete in;
- return false;
- }
-
- // In older versions of ScummVM, the header version was not endian safe.
- // We account for that by retrying once with swapped byte order.
- if (hdr.ver > CURRENT_VER)
- hdr.ver = SWAP_BYTES_32(hdr.ver);
-
- // Reject save games which are too old or too new. Note that
- // We do not really support V7 games, but still accept them here
- // to work around a bug from the stone age (see below for more
- // information).
- if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER) {
- warning("Invalid version of '%s'", filename);
- delete in;
- return false;
- }
-
- // We (deliberately) broke HE savegame compatibility at some point.
- if (hdr.ver < VER(50) && _heversion >= 71) {
- warning("Unsupported version of '%s'", filename);
- delete in;
- return false;
- }
-
- // Since version 52 a thumbnail is saved directly after the header.
- if (hdr.ver >= VER(52)) {
- uint32 type;
- in->read(&type, 4);
-
- // Check for the THMB header. Also, work around a bug which caused
- // the chunk type (incorrectly) to be written in LE on LE machines.
- if (! (type == MKID('THMB') || (hdr.ver < VER(55) && type == MKID('BMHT')))){
- warning("Can not load thumbnail");
- delete in;
- return false;
- }
- uint32 size = in->readUint32BE();
- in->skip(size - 8);
- }
-
- // Since version 56 we save additional information about the creation of
- // the save game and the save time.
- if (hdr.ver >= VER(56)) {
- InfoStuff infos;
- if (!loadInfos(in, &infos)) {
- warning("Info section could not be found");
- delete in;
- return false;
- }
-
- _engineStartTime = _system->getMillis() / 1000 - infos.playtime;
- } else {
- // start time counting
- _engineStartTime = _system->getMillis() / 1000;
- }
-
- _dialogStartTime = _system->getMillis() / 1000;
-
- // Due to a bug in scummvm up to and including 0.3.0, save games could be saved
- // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here
- if (hdr.ver == VER(7))
- hdr.ver = VER(8);
-
- memcpy(_saveLoadName, hdr.name, sizeof(hdr.name));
-
- // Unless specifically requested with _saveSound, we do not save the iMUSE
- // state for temporary state saves - such as certain cutscenes in DOTT,
- // FOA, Sam and Max, etc.
- //
- // Thusly, we should probably not stop music when restoring from one of
- // these saves. This change stops the Mole Man theme from going quiet in
- // Sam & Max when Doug tells you about the Ball of Twine, as mentioned in
- // patch #886058.
- //
- // If we don't have iMUSE at all we may as well stop the sounds. The previous
- // default behavior here was to stopAllSounds on all state restores.
-
- if (!_imuse || _saveSound || !_saveTemporaryState)
- _sound->stopAllSounds();
-
-#ifndef DISABLE_SCUMM_7_8
- if (_imuseDigital) {
- _imuseDigital->stopAllSounds();
- _imuseDigital->resetState();
- }
-#endif
-
- _sound->stopCD();
-
- _sound->pauseSounds(true);
-
- CHECK_HEAP
-
- closeRoom();
-
- memset(_inventory, 0, sizeof(_inventory[0]) * _numInventory);
- memset(_newNames, 0, sizeof(_newNames[0]) * _numNewNames);
-
- // Because old savegames won't fill the entire gfxUsageBits[] array,
- // clear it here just to be sure it won't hold any unforseen garbage.
- memset(gfxUsageBits, 0, sizeof(gfxUsageBits));
-
- // Nuke all resources
- for (i = rtFirst; i <= rtLast; i++)
- if (i != rtTemp && i != rtBuffer && (i != rtSound || _saveSound || !compat))
- for (j = 0; j < res.num[i]; j++) {
- res.nukeResource(i, j);
- }
-
- initScummVars();
-
- if (_features & GF_OLD_BUNDLE)
- loadCharset(0); // FIXME - HACK ?
-
- //
- // Now do the actual loading
- //
- Serializer ser(in, 0, hdr.ver);
- saveOrLoad(&ser);
- delete in;
-
- // Update volume settings
- setupVolumes();
-
- // Init NES costume data
- if (_platform == Common::kPlatformNES) {
- if (hdr.ver < VER(47))
- _NESCostumeSet = 0;
- NES_loadCostumeSet(_NESCostumeSet);
- }
-
- // Normally, _vm->_screenTop should always be >= 0, but for some old save games
- // it is not, hence we check & correct it here.
- if (_screenTop < 0)
- _screenTop = 0;
-
- if (hdr.ver < VER(33) && _version >= 7) {
- // For a long time, we didn't set these vars to default values.
- VAR(VAR_DEFAULT_TALK_DELAY) = 60;
- if (_version == 7)
- VAR(VAR_NUM_GLOBAL_OBJS) = _numGlobalObjects - 1;
- }
-
- if (hdr.ver < VER(30)) {
- // For a long time, we used incorrect location, causing it to default to zero.
- if (_version == 8)
- _scummVars[VAR_CHARINC] = (_features & GF_DEMO) ? 3 : 1;
- // Needed due to subtitle speed changes
- _defaultTalkDelay /= 20;
- }
-
- // For a long time, we used incorrect locations for some camera related
- // scumm vars. We now know the proper locations. To be able to properly use
- // old save games, we update the old (bad) variables to the new (correct)
- // ones.
- if (hdr.ver < VER(28) && _version == 8) {
- _scummVars[VAR_CAMERA_MIN_X] = _scummVars[101];
- _scummVars[VAR_CAMERA_MAX_X] = _scummVars[102];
- _scummVars[VAR_CAMERA_MIN_Y] = _scummVars[103];
- _scummVars[VAR_CAMERA_MAX_Y] = _scummVars[104];
- _scummVars[VAR_CAMERA_THRESHOLD_X] = _scummVars[105];
- _scummVars[VAR_CAMERA_THRESHOLD_Y] = _scummVars[106];
- _scummVars[VAR_CAMERA_SPEED_X] = _scummVars[107];
- _scummVars[VAR_CAMERA_SPEED_Y] = _scummVars[108];
- _scummVars[VAR_CAMERA_ACCEL_X] = _scummVars[109];
- _scummVars[VAR_CAMERA_ACCEL_Y] = _scummVars[110];
- }
-
- // With version 22, we replaced the scale items with scale slots. So when
- // loading such an old save game, try to upgrade the old to new format.
- if (hdr.ver < VER(22)) {
- // Convert all rtScaleTable resources to matching scale items
- for (i = 1; i < res.num[rtScaleTable]; i++) {
- convertScaleTableToScaleSlot(i);
- }
- }
-
- // We could simply dirty colours 0-15 for 16-colour games -- nowadays
- // they handle their palette pretty much like the more recent games
- // anyway. There was a time, though, when re-initializing was necessary
- // for backwards compatibility, and it may still prove useful if we
- // ever add options for using different 16-colour palettes.
- if (_version == 1) {
- if (_platform == Common::kPlatformC64) {
- setupC64Palette();
- } else if (_platform == Common::kPlatformNES) {
- setupNESPalette();
- } else {
- setupV1Palette();
- }
- } else if (_features & GF_16COLOR) {
- switch (_renderMode) {
- case Common::kRenderEGA:
- setupEGAPalette();
- break;
-
- case Common::kRenderAmiga:
- setupAmigaPalette();
- break;
-
- case Common::kRenderCGA:
- setupCGAPalette();
- break;
-
- case Common::kRenderHercA:
- case Common::kRenderHercG:
- setupHercPalette();
- break;
-
- default:
- if ((_platform == Common::kPlatformAmiga) || (_platform == Common::kPlatformAtariST))
- setupAmigaPalette();
- else
- setupEGAPalette();
- }
- } else
- setDirtyColors(0, 255);
-
-
- if (hdr.ver < VER(35) && _gameId == GID_MANIAC && _version == 1)
- setupV1ActorTalkColor();
-
- // Load the static room data
- loadRoomSubBlocks();
-
- if (!(_features & GF_NEW_CAMERA)) {
- camera._last.x = camera._cur.x;
- }
-
- sb = _screenB;
- sh = _screenH;
-
- // Restore the virtual screens and force a fade to black.
- initScreens(0, _screenHeight);
-
- VirtScreen *vs = &virtscr[kMainVirtScreen];
- memset(vs->getPixels(0, 0), 0, vs->pitch * vs->h);
- vs->setDirtyRange(0, vs->h);
- updateDirtyScreen(kMainVirtScreen);
- updatePalette();
- initScreens(sb, sh);
-
- _completeScreenRedraw = true;
-
- // Reset charset mask
- _charset->_hasMask = false;
- _charset->clearTextSurface();
-
- _lastCodePtr = NULL;
- _drawObjectQueNr = 0;
- _verbMouseOver = 0;
-
- cameraMoved();
-
- initBGBuffers(_roomHeight);
-
- if (VAR_ROOM_FLAG != 0xFF)
- VAR(VAR_ROOM_FLAG) = 1;
-
- // Sync with current config setting
- if (VAR_VOICE_MODE != 0xFF)
- VAR(VAR_VOICE_MODE) = ConfMan.getBool("subtitles");
-
- CHECK_HEAP
- debug(1, "State loaded from '%s'", filename);
-
- _sound->pauseSounds(false);
-
- _engineStartTime += _system->getMillis() / 1000 - _dialogStartTime;
- _dialogStartTime = 0;
-
- return true;
-}
-
-void ScummEngine::makeSavegameName(char *out, int slot, bool temporary) {
- sprintf(out, "%s.%c%.2d", _targetName.c_str(), temporary ? 'c' : 's', slot);
-}
-
-void ScummEngine::listSavegames(bool *marks, int num) {
- char prefix[256];
- makeSavegameName(prefix, 99, false);
- prefix[strlen(prefix)-2] = 0;
- _saveFileMan->listSavefiles(prefix, marks, num);
-}
-
-bool ScummEngine::getSavegameName(int slot, char *desc) {
- char filename[256];
- Common::InSaveFile *in;
- SaveGameHeader hdr;
- int len;
-
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
- strcpy(desc, "");
- return false;
- }
- len = in->read(&hdr, sizeof(hdr));
- delete in;
-
- if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) {
- strcpy(desc, "Invalid savegame");
- return false;
- }
-
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER) {
- strcpy(desc, "Invalid version");
- return false;
- }
-
- // We (deliberately) broke HE savegame compatibility at some point.
- if (hdr.ver < VER(57) && _heversion >= 60) {
- strcpy(desc, "Unsupported version");
- return false;
- }
-
- memcpy(desc, hdr.name, sizeof(hdr.name));
- desc[sizeof(hdr.name) - 1] = 0;
- return true;
-}
-
-Graphics::Surface *ScummEngine::loadThumbnailFromSlot(int slot) {
- char filename[256];
- Common::InSaveFile *in;
- SaveGameHeader hdr;
- int len;
-
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
- return 0;
- }
- len = in->read(&hdr, sizeof(hdr));
-
- if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) {
- delete in;
- return 0;
- }
-
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(52)) {
- delete in;
- return 0;
- }
-
- Graphics::Surface *thumb = loadThumbnail(in);
-
- delete in;
- return thumb;
-}
-
-bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
- char filename[256];
- Common::InSaveFile *in;
- SaveGameHeader hdr;
- int len;
-
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
- return false;
- }
- len = in->read(&hdr, sizeof(hdr));
-
- if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) {
- delete in;
- return false;
- }
-
- if (hdr.ver > CURRENT_VER)
- hdr.ver = TO_LE_32(hdr.ver);
- if (hdr.ver < VER(56)) {
- delete in;
- return false;
- }
-
- uint32 type;
- in->read(&type, 4);
-
- // Check for the THMB header. Also, work around a bug which caused
- // the chunk type (incorrectly) to be written in LE on LE machines.
- if (! (type == MKID('THMB') || (hdr.ver < VER(55) && type == MKID('BMHT')))){
- delete in;
- return false;
- }
- uint32 size = in->readUint32BE();
- in->skip(size - 8);
-
- if (!loadInfos(in, stuff)) {
- delete in;
- return false;
- }
-
- delete in;
- return true;
-}
-
-bool ScummEngine::loadInfos(Common::InSaveFile *file, InfoStuff *stuff) {
- memset(stuff, 0, sizeof(InfoStuff));
-
- SaveInfoSection section;
- file->read(&section.type, 4);
- if (section.type != MKID('INFO')) {
- return false;
- }
-
- section.version = file->readUint32BE();
- section.size = file->readUint32BE();
-
- // if we extend this we should add a table for the special sizes at the versions to check it
- if (section.version == INFOSECTION_VERSION && section.size != sizeof(SaveInfoSection)) {
- warning("Info section is corrupt");
- file->skip(section.size);
- return false;
- }
-
- section.timeTValue = file->readUint32BE();
- section.playtime = file->readUint32BE();
-
- // for compatibility for older version we
- // to load in with our old method
- if (section.version == 1) {
- time_t curTime_ = section.timeTValue;
- tm *curTime = localtime(&curTime_);
- stuff->date = (curTime->tm_mday & 0xFF) << 24 | ((curTime->tm_mon + 1) & 0xFF) << 16 | (curTime->tm_year + 1900) & 0xFFFF;
- stuff->time = (curTime->tm_hour & 0xFF) << 8 | (curTime->tm_min) & 0xFF;
- }
-
- if (section.version >= 2) {
- section.date = file->readUint32BE();
- section.time = file->readUint16BE();
-
- stuff->date = section.date;
- stuff->time = section.time;
- }
-
- stuff->playtime = section.playtime;
-
- // skip all newer features, this could make problems if some older version uses more space for
- // saving informations, but this should NOT happen
- if (section.size > sizeof(SaveInfoSection)) {
- file->skip(section.size - sizeof(SaveInfoSection));
- }
-
- return true;
-}
-
-void ScummEngine::saveInfos(Common::OutSaveFile* file) {
- SaveInfoSection section;
- section.type = MKID('INFO');
- section.version = INFOSECTION_VERSION;
- section.size = sizeof(SaveInfoSection);
-
- // still save old format for older versions
- section.timeTValue = time(0);
- section.playtime = _system->getMillis() / 1000 - _engineStartTime;
-
- time_t curTime_ = time(0);
- tm *curTime = localtime(&curTime_);
- section.date = (curTime->tm_mday & 0xFF) << 24 | ((curTime->tm_mon + 1) & 0xFF) << 16 | (curTime->tm_year + 1900) & 0xFFFF;
- section.time = (curTime->tm_hour & 0xFF) << 8 | (curTime->tm_min) & 0xFF;
-
- file->write(&section.type, 4);
- file->writeUint32BE(section.version);
- file->writeUint32BE(section.size);
- file->writeUint32BE(section.timeTValue);
- file->writeUint32BE(section.playtime);
- file->writeUint32BE(section.date);
- file->writeUint16BE(section.time);
-}
-
-void ScummEngine::saveOrLoad(Serializer *s) {
- const SaveLoadEntry objectEntries[] = {
- MKLINE(ObjectData, OBIMoffset, sleUint32, VER(8)),
- MKLINE(ObjectData, OBCDoffset, sleUint32, VER(8)),
- MKLINE(ObjectData, walk_x, sleUint16, VER(8)),
- MKLINE(ObjectData, walk_y, sleUint16, VER(8)),
- MKLINE(ObjectData, obj_nr, sleUint16, VER(8)),
- MKLINE(ObjectData, x_pos, sleInt16, VER(8)),
- MKLINE(ObjectData, y_pos, sleInt16, VER(8)),
- MKLINE(ObjectData, width, sleUint16, VER(8)),
- MKLINE(ObjectData, height, sleUint16, VER(8)),
- MKLINE(ObjectData, actordir, sleByte, VER(8)),
- MKLINE(ObjectData, parentstate, sleByte, VER(8)),
- MKLINE(ObjectData, parent, sleByte, VER(8)),
- MKLINE(ObjectData, state, sleByte, VER(8)),
- MKLINE(ObjectData, fl_object_index, sleByte, VER(8)),
- MKLINE(ObjectData, flags, sleByte, VER(46)),
- MKEND()
- };
-
- const SaveLoadEntry verbEntries[] = {
- MKLINE(VerbSlot, curRect.left, sleInt16, VER(8)),
- MKLINE(VerbSlot, curRect.top, sleInt16, VER(8)),
- MKLINE(VerbSlot, curRect.right, sleInt16, VER(8)),
- MKLINE(VerbSlot, curRect.bottom, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.left, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.top, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.right, sleInt16, VER(8)),
- MKLINE(VerbSlot, oldRect.bottom, sleInt16, VER(8)),
-
- MKLINE_OLD(VerbSlot, verbid, sleByte, VER(8), VER(11)),
- MKLINE(VerbSlot, verbid, sleInt16, VER(12)),
-
- MKLINE(VerbSlot, color, sleByte, VER(8)),
- MKLINE(VerbSlot, hicolor, sleByte, VER(8)),
- MKLINE(VerbSlot, dimcolor, sleByte, VER(8)),
- MKLINE(VerbSlot, bkcolor, sleByte, VER(8)),
- MKLINE(VerbSlot, type, sleByte, VER(8)),
- MKLINE(VerbSlot, charset_nr, sleByte, VER(8)),
- MKLINE(VerbSlot, curmode, sleByte, VER(8)),
- MKLINE(VerbSlot, saveid, sleByte, VER(8)),
- MKLINE(VerbSlot, key, sleByte, VER(8)),
- MKLINE(VerbSlot, center, sleByte, VER(8)),
- MKLINE(VerbSlot, prep, sleByte, VER(8)),
- MKLINE(VerbSlot, imgindex, sleUint16, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry mainEntries[] = {
- MKARRAY(ScummEngine, _gameMD5[0], sleUint8, 16, VER(39)),
- MK_OBSOLETE(ScummEngine, _roomWidth, sleUint16, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _roomHeight, sleUint16, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _ENCD_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _EXCD_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _IM00_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _CLUT_offs, sleUint32, VER(8), VER(50)),
- MK_OBSOLETE(ScummEngine, _EPAL_offs, sleUint32, VER(8), VER(9)),
- MK_OBSOLETE(ScummEngine, _PALS_offs, sleUint32, VER(8), VER(50)),
- MKLINE(ScummEngine, _curPalIndex, sleByte, VER(8)),
- MKLINE(ScummEngine, _currentRoom, sleByte, VER(8)),
- MKLINE(ScummEngine, _roomResource, sleByte, VER(8)),
- MKLINE(ScummEngine, _numObjectsInRoom, sleByte, VER(8)),
- MKLINE(ScummEngine, _currentScript, sleByte, VER(8)),
- MK_OBSOLETE_ARRAY(ScummEngine, _localScriptOffsets[0], sleUint32, _numLocalScripts, VER(8), VER(50)),
-
-
- // vm.localvar grew from 25 to 40 script entries and then from
- // 16 to 32 bit variables (but that wasn't reflect here)... and
- // THEN from 16 to 25 variables.
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 25, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(8), VER(8)),
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 17, 40, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(9), VER(14)),
-
- // We used to save 25 * 40 = 1000 blocks; but actually, each 'row consisted of 26 entry,
- // i.e. 26 * 40 = 1040. Thus the last 40 blocks of localvar where not saved at all. To be
- // able to load this screwed format, we use a trick: We load 26 * 38 = 988 blocks.
- // Then, we mark the followin 12 blocks (24 bytes) as obsolete.
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint16, 26, 38, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(15), VER(17)),
- MK_OBSOLETE_ARRAY(ScummEngine, vm.localvar[39][0], sleUint16, 12, VER(15), VER(17)),
-
- // This was the first proper multi dimensional version of the localvars, with 32 bit values
- MKARRAY2_OLD(ScummEngine, vm.localvar[0][0], sleUint32, 26, 40, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(18), VER(19)),
-
- // Then we doubled the script slots again, from 40 to 80
- MKARRAY2(ScummEngine, vm.localvar[0][0], sleUint32, 26, NUM_SCRIPT_SLOT, (byte*)vm.localvar[1] - (byte*)vm.localvar[0], VER(20)),
-
-
- MKARRAY(ScummEngine, _resourceMapper[0], sleByte, 128, VER(8)),
- MKARRAY(ScummEngine, _charsetColorMap[0], sleByte, 16, VER(8)),
-
- // _charsetData grew from 10*16 to 15*16 bytes
- MKARRAY_OLD(ScummEngine, _charsetData[0][0], sleByte, 10 * 16, VER(8), VER(9)),
- MKARRAY(ScummEngine, _charsetData[0][0], sleByte, 15 * 16, VER(10)),
-
- MK_OBSOLETE(ScummEngine, _curExecScript, sleUint16, VER(8), VER(62)),
-
- MKLINE(ScummEngine, camera._dest.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._dest.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._cur.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._cur.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._last.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._last.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._accel.x, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._accel.y, sleInt16, VER(8)),
- MKLINE(ScummEngine, _screenStartStrip, sleInt16, VER(8)),
- MKLINE(ScummEngine, _screenEndStrip, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._mode, sleByte, VER(8)),
- MKLINE(ScummEngine, camera._follows, sleByte, VER(8)),
- MKLINE(ScummEngine, camera._leftTrigger, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._rightTrigger, sleInt16, VER(8)),
- MKLINE(ScummEngine, camera._movingToActor, sleUint16, VER(8)),
-
- MKLINE(ScummEngine, _actorToPrintStrFor, sleByte, VER(8)),
- MKLINE(ScummEngine, _charsetColor, sleByte, VER(8)),
-
- // _charsetBufPos was changed from byte to int
- MKLINE_OLD(ScummEngine, _charsetBufPos, sleByte, VER(8), VER(9)),
- MKLINE(ScummEngine, _charsetBufPos, sleInt16, VER(10)),
-
- MKLINE(ScummEngine, _haveMsg, sleByte, VER(8)),
- MKLINE(ScummEngine, _haveActorSpeechMsg, sleByte, VER(61)),
- MKLINE(ScummEngine, _useTalkAnims, sleByte, VER(8)),
-
- MKLINE(ScummEngine, _talkDelay, sleInt16, VER(8)),
- MKLINE(ScummEngine, _defaultTalkDelay, sleInt16, VER(8)),
- MK_OBSOLETE(ScummEngine, _numInMsgStack, sleInt16, VER(8), VER(27)),
- MKLINE(ScummEngine, _sentenceNum, sleByte, VER(8)),
-
- MKLINE(ScummEngine, vm.cutSceneStackPointer, sleByte, VER(8)),
- MKARRAY(ScummEngine, vm.cutScenePtr[0], sleUint32, 5, VER(8)),
- MKARRAY(ScummEngine, vm.cutSceneScript[0], sleByte, 5, VER(8)),
- MKARRAY(ScummEngine, vm.cutSceneData[0], sleInt16, 5, VER(8)),
- MKLINE(ScummEngine, vm.cutSceneScriptIndex, sleInt16, VER(8)),
-
- MKLINE(ScummEngine, vm.numNestedScripts, sleByte, VER(8)),
- MKLINE(ScummEngine, _userPut, sleByte, VER(8)),
- MKLINE(ScummEngine, _userState, sleUint16, VER(17)),
- MKLINE(ScummEngine, _cursor.state, sleByte, VER(8)),
- MK_OBSOLETE(ScummEngine, gdi._cursorActive, sleByte, VER(8), VER(20)),
- MKLINE(ScummEngine, _currentCursor, sleByte, VER(8)),
- MKARRAY(ScummEngine, _grabbedCursor[0], sleByte, 8192, VER(20)),
- MKLINE(ScummEngine, _cursor.width, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.height, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.hotspotX, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.hotspotY, sleInt16, VER(20)),
- MKLINE(ScummEngine, _cursor.animate, sleByte, VER(20)),
- MKLINE(ScummEngine, _cursor.animateIndex, sleByte, VER(20)),
- MKLINE(ScummEngine, _mouse.x, sleInt16, VER(20)),
- MKLINE(ScummEngine, _mouse.y, sleInt16, VER(20)),
-
- MKARRAY(ScummEngine, _colorUsedByCycle[0], sleByte, 256, VER(60)),
- MKLINE(ScummEngine, _doEffect, sleByte, VER(8)),
- MKLINE(ScummEngine, _switchRoomEffect, sleByte, VER(8)),
- MKLINE(ScummEngine, _newEffect, sleByte, VER(8)),
- MKLINE(ScummEngine, _switchRoomEffect2, sleByte, VER(8)),
- MKLINE(ScummEngine, _bgNeedsRedraw, sleByte, VER(8)),
-
- // The state of palManipulate is stored only since V10
- MKLINE(ScummEngine, _palManipStart, sleByte, VER(10)),
- MKLINE(ScummEngine, _palManipEnd, sleByte, VER(10)),
- MKLINE(ScummEngine, _palManipCounter, sleUint16, VER(10)),
-
- // gfxUsageBits grew from 200 to 410 entries. Then 3 * 410 entries:
- MKARRAY_OLD(ScummEngine, gfxUsageBits[0], sleUint32, 200, VER(8), VER(9)),
- MKARRAY_OLD(ScummEngine, gfxUsageBits[0], sleUint32, 410, VER(10), VER(13)),
- MKARRAY(ScummEngine, gfxUsageBits[0], sleUint32, 3 * 410, VER(14)),
-
- MK_OBSOLETE(ScummEngine, gdi._transparentColor, sleByte, VER(8), VER(50)),
- MKARRAY(ScummEngine, _currentPalette[0], sleByte, 768, VER(8)),
- MKARRAY(ScummEngine, _darkenPalette[0], sleByte, 768, VER(53)),
-
- // Sam & Max specific palette replaced by _shadowPalette now.
- MK_OBSOLETE_ARRAY(ScummEngine, _proc_special_palette[0], sleByte, 256, VER(8), VER(33)),
-
- MKARRAY(ScummEngine, _charsetBuffer[0], sleByte, 256, VER(8)),
-
- MKLINE(ScummEngine, _egoPositioned, sleByte, VER(8)),
-
- // gdi._imgBufOffs grew from 4 to 5 entries. Then one day we realized
- // that we don't have to store it since initBGBuffers() recomputes it.
- MK_OBSOLETE_ARRAY(ScummEngine, gdi._imgBufOffs[0], sleUint16, 4, VER(8), VER(9)),
- MK_OBSOLETE_ARRAY(ScummEngine, gdi._imgBufOffs[0], sleUint16, 5, VER(10), VER(26)),
-
- // See _imgBufOffs: _numZBuffer is recomputed by initBGBuffers().
- MK_OBSOLETE(ScummEngine, gdi._numZBuffer, sleByte, VER(8), VER(26)),
-
- MKLINE(ScummEngine, _screenEffectFlag, sleByte, VER(8)),
-
- MK_OBSOLETE(ScummEngine, _randSeed1, sleUint32, VER(8), VER(9)),
- MK_OBSOLETE(ScummEngine, _randSeed2, sleUint32, VER(8), VER(9)),
-
- // Converted _shakeEnabled to boolean and added a _shakeFrame field.
- MKLINE_OLD(ScummEngine, _shakeEnabled, sleInt16, VER(8), VER(9)),
- MKLINE(ScummEngine, _shakeEnabled, sleByte, VER(10)),
- MKLINE(ScummEngine, _shakeFrame, sleUint32, VER(10)),
-
- MKLINE(ScummEngine, _keepText, sleByte, VER(8)),
-
- MKLINE(ScummEngine, _screenB, sleUint16, VER(8)),
- MKLINE(ScummEngine, _screenH, sleUint16, VER(8)),
-
- MKLINE(ScummEngine, _NESCostumeSet, sleUint16, VER(47)),
-
- MK_OBSOLETE(ScummEngine, _cd_track, sleInt16, VER(9), VER(9)),
- MK_OBSOLETE(ScummEngine, _cd_loops, sleInt16, VER(9), VER(9)),
- MK_OBSOLETE(ScummEngine, _cd_frame, sleInt16, VER(9), VER(9)),
- MK_OBSOLETE(ScummEngine, _cd_end, sleInt16, VER(9), VER(9)),
-
- MKEND()
- };
-
- const SaveLoadEntry scriptSlotEntries[] = {
- MKLINE(ScriptSlot, offs, sleUint32, VER(8)),
- MKLINE(ScriptSlot, delay, sleInt32, VER(8)),
- MKLINE(ScriptSlot, number, sleUint16, VER(8)),
- MKLINE(ScriptSlot, delayFrameCount, sleUint16, VER(8)),
- MKLINE(ScriptSlot, status, sleByte, VER(8)),
- MKLINE(ScriptSlot, where, sleByte, VER(8)),
- MKLINE(ScriptSlot, freezeResistant, sleByte, VER(8)),
- MKLINE(ScriptSlot, recursive, sleByte, VER(8)),
- MKLINE(ScriptSlot, freezeCount, sleByte, VER(8)),
- MKLINE(ScriptSlot, didexec, sleByte, VER(8)),
- MKLINE(ScriptSlot, cutsceneOverride, sleByte, VER(8)),
- MKLINE(ScriptSlot, cycle, sleByte, VER(46)),
- MK_OBSOLETE(ScriptSlot, unk5, sleByte, VER(8), VER(10)),
- MKEND()
- };
-
- const SaveLoadEntry nestedScriptEntries[] = {
- MKLINE(NestedScript, number, sleUint16, VER(8)),
- MKLINE(NestedScript, where, sleByte, VER(8)),
- MKLINE(NestedScript, slot, sleByte, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry sentenceTabEntries[] = {
- MKLINE(SentenceTab, verb, sleUint8, VER(8)),
- MKLINE(SentenceTab, preposition, sleUint8, VER(8)),
- MKLINE(SentenceTab, objectA, sleUint16, VER(8)),
- MKLINE(SentenceTab, objectB, sleUint16, VER(8)),
- MKLINE(SentenceTab, freezeCount, sleUint8, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry stringTabEntries[] = {
- // Then _default/restore of a StringTab entry becomes a one liner.
- MKLINE(StringTab, xpos, sleInt16, VER(8)),
- MKLINE(StringTab, _default.xpos, sleInt16, VER(8)),
- MKLINE(StringTab, ypos, sleInt16, VER(8)),
- MKLINE(StringTab, _default.ypos, sleInt16, VER(8)),
- MKLINE(StringTab, right, sleInt16, VER(8)),
- MKLINE(StringTab, _default.right, sleInt16, VER(8)),
- MKLINE(StringTab, color, sleInt8, VER(8)),
- MKLINE(StringTab, _default.color, sleInt8, VER(8)),
- MKLINE(StringTab, charset, sleInt8, VER(8)),
- MKLINE(StringTab, _default.charset, sleInt8, VER(8)),
- MKLINE(StringTab, center, sleByte, VER(8)),
- MKLINE(StringTab, _default.center, sleByte, VER(8)),
- MKLINE(StringTab, overhead, sleByte, VER(8)),
- MKLINE(StringTab, _default.overhead, sleByte, VER(8)),
- MKLINE(StringTab, no_talk_anim, sleByte, VER(8)),
- MKLINE(StringTab, _default.no_talk_anim, sleByte, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry colorCycleEntries[] = {
- MKLINE(ColorCycle, delay, sleUint16, VER(8)),
- MKLINE(ColorCycle, counter, sleUint16, VER(8)),
- MKLINE(ColorCycle, flags, sleUint16, VER(8)),
- MKLINE(ColorCycle, start, sleByte, VER(8)),
- MKLINE(ColorCycle, end, sleByte, VER(8)),
- MKEND()
- };
-
- const SaveLoadEntry scaleSlotsEntries[] = {
- MKLINE(ScaleSlot, x1, sleUint16, VER(13)),
- MKLINE(ScaleSlot, y1, sleUint16, VER(13)),
- MKLINE(ScaleSlot, scale1, sleUint16, VER(13)),
- MKLINE(ScaleSlot, x2, sleUint16, VER(13)),
- MKLINE(ScaleSlot, y2, sleUint16, VER(13)),
- MKLINE(ScaleSlot, scale2, sleUint16, VER(13)),
- MKEND()
- };
-
- // MSVC6 FIX (Jamieson630):
- // MSVC6 has a problem with any notation that involves
- // more than one set of double colons ::
- // The following MKLINE macros expand to such things
- // as AudioCDManager::Status::playing, and MSVC6 has
- // a fit with that. This typedef simplifies the notation
- // to something MSVC6 can grasp.
- typedef AudioCDManager::Status AudioCDManager_Status;
- const SaveLoadEntry audioCDEntries[] = {
- MKLINE(AudioCDManager_Status, playing, sleUint32, VER(24)),
- MKLINE(AudioCDManager_Status, track, sleInt32, VER(24)),
- MKLINE(AudioCDManager_Status, start, sleUint32, VER(24)),
- MKLINE(AudioCDManager_Status, duration, sleUint32, VER(24)),
- MKLINE(AudioCDManager_Status, numLoops, sleInt32, VER(24)),
- MKEND()
- };
-
- int i, j;
- int var120Backup;
- int var98Backup;
- uint8 md5Backup[16];
-
- // MD5 Operations: Backup on load, compare, and reset.
- if (s->isLoading())
- memcpy(md5Backup, _gameMD5, 16);
-
-
- //
- // Save/load main state (many members of class ScummEngine get saved here)
- //
- s->saveLoadEntries(this, mainEntries);
-
- // MD5 Operations: Backup on load, compare, and reset.
- if (s->isLoading()) {
- char md5str1[32+1], md5str2[32+1];
- for (j = 0; j < 16; j++) {
- sprintf(md5str1 + j*2, "%02x", (int)_gameMD5[j]);
- sprintf(md5str2 + j*2, "%02x", (int)md5Backup[j]);
- }
-
- debug(2, "Save version: %d", s->getVersion());
- debug(2, "Saved game MD5: %s", (s->getVersion() >= 39) ? md5str1 : "unknown");
-
- if (memcmp(md5Backup, _gameMD5, 16) != 0) {
- warning("Game was saved with different gamedata - you may encounter problems.");
- debug(1, "You have %s and save is %s.", md5str2, md5str1);
- memcpy(_gameMD5, md5Backup, 16);
- }
- }
-
-
- // Starting V14, we extended the usage bits, to be able to cope with games
- // that have more than 30 actors (up to 94 are supported now, in theory).
- // Since the format of the usage bits was changed by this, we have to
- // convert them when loading an older savegame.
- if (s->isLoading() && s->getVersion() < VER(14))
- upgradeGfxUsageBits();
-
- // When loading, move the mouse to the saved mouse position.
- if (s->isLoading() && s->getVersion() >= VER(20)) {
- updateCursor();
- _system->warpMouse(_mouse.x, _mouse.y);
- }
-
- // Before V61, we re-used the _haveMsg flag to handle "alternative" speech
- // sound files (see charset code 10).
- if (s->isLoading() && s->getVersion() < VER(61)) {
- if (_haveMsg == 0xFE) {
- _haveActorSpeechMsg = false;
- _haveMsg = 0xFF;
- } else {
- _haveActorSpeechMsg = true;
- }
- }
-
- //
- // Save/load actors
- //
- for (i = 0; i < _numActors; i++)
- _actors[i].saveLoadWithSerializer(s);
-
-
- //
- // Save/load sound data
- //
- _sound->saveLoadWithSerializer(s);
-
-
- //
- // Save/load script data
- //
- if (s->getVersion() < VER(9))
- s->saveLoadArrayOf(vm.slot, 25, sizeof(vm.slot[0]), scriptSlotEntries);
- else if (s->getVersion() < VER(20))
- s->saveLoadArrayOf(vm.slot, 40, sizeof(vm.slot[0]), scriptSlotEntries);
- else
- s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]), scriptSlotEntries);
-
- if (s->getVersion() < VER(46)) {
- // When loading an old savegame, make sure that the 'cycle'
- // field is set to something sensible, otherwise the scripts
- // that were running probably won't be.
-
- for (i = 0; i < NUM_SCRIPT_SLOT; i++) {
- vm.slot[i].cycle = 1;
- }
- }
-
-
- //
- // Save/load local objects
- //
- s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries);
- if (s->isLoading() && s->getVersion() < VER(13)) {
- // Since roughly v13 of the save games, the objs storage has changed a bit
- for (i = _numObjectsInRoom; i < _numLocalObjects; i++) {
- _objs[i].obj_nr = 0;
- }
-
- }
-
-
- //
- // Save/load misc stuff
- //
- s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries);
- s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries);
- s->saveLoadArrayOf(_sentence, 6, sizeof(_sentence[0]), sentenceTabEntries);
- s->saveLoadArrayOf(_string, 6, sizeof(_string[0]), stringTabEntries);
- s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]), colorCycleEntries);
- if (s->getVersion() >= VER(13))
- s->saveLoadArrayOf(_scaleSlots, 20, sizeof(_scaleSlots[0]), scaleSlotsEntries);
-
-
- //
- // Save/load resources
- //
- int type, idx;
- if (s->getVersion() >= VER(26)) {
- // New, more robust resource save/load system. This stores the type
- // and index of each resource. Thus if we increase e.g. the maximum
- // number of script resources, savegames won't break.
- if (s->isSaving()) {
- for (type = rtFirst; type <= rtLast; type++) {
- if (res.mode[type] != 1 && type != rtTemp && type != rtBuffer) {
- s->saveUint16(type); // Save the res type...
- for (idx = 0; idx < res.num[type]; idx++) {
- // Only save resources which actually exist...
- if (res.address[type][idx]) {
- s->saveUint16(idx); // Save the index of the resource
- saveResource(s, type, idx);
- }
- }
- s->saveUint16(0xFFFF); // End marker
- }
- }
- s->saveUint16(0xFFFF); // End marker
- } else {
- while ((type = s->loadUint16()) != 0xFFFF) {
- while ((idx = s->loadUint16()) != 0xFFFF) {
- assert(0 <= idx && idx < res.num[type]);
- loadResource(s, type, idx);
- }
- }
- }
- } else {
- // Old, fragile resource save/load system. Doesn't save resources
- // with index 0, and breaks whenever we change the limit on a given
- // resource type.
- for (type = rtFirst; type <= rtLast; type++)
- if (res.mode[type] != 1 && type != rtTemp && type != rtBuffer) {
- // For V1-V5 games, there used to be no object name resources.
- // At some point this changed. But since old savegames rely on
- // unchanged resource counts, we have to hard code the following check
- if (_version < 6 && type == rtObjectName)
- continue;
- for (idx = 1; idx < res.num[type]; idx++)
- saveLoadResource(s, type, idx);
- }
- }
-
-
- //
- // Save/load global object state
- //
- s->saveLoadArrayOf(_objectOwnerTable, _numGlobalObjects, sizeof(_objectOwnerTable[0]), sleByte);
- s->saveLoadArrayOf(_objectStateTable, _numGlobalObjects, sizeof(_objectStateTable[0]), sleByte);
- if (_objectRoomTable)
- s->saveLoadArrayOf(_objectRoomTable, _numGlobalObjects, sizeof(_objectRoomTable[0]), sleByte);
-
-
- //
- // Save/load palette data
- //
- if (_shadowPaletteSize) {
- s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte);
- // _roomPalette didn't show up until V21 save games
- if (s->getVersion() >= VER(21) && _version < 5)
- s->saveLoadArrayOf(_roomPalette, sizeof(_roomPalette), 1, sleByte);
- }
-
- // PalManip data was not saved before V10 save games
- if (s->getVersion() < VER(10))
- _palManipCounter = 0;
- if (_palManipCounter) {
- if (!_palManipPalette)
- _palManipPalette = (byte *)calloc(0x300, 1);
- if (!_palManipIntermediatePal)
- _palManipIntermediatePal = (byte *)calloc(0x600, 1);
- s->saveLoadArrayOf(_palManipPalette, 0x300, 1, sleByte);
- s->saveLoadArrayOf(_palManipIntermediatePal, 0x600, 1, sleByte);
- }
-
- // darkenPalette was not saved before V53
- if (s->isLoading() && s->getVersion() < VER(53)) {
- memcpy(_darkenPalette, _currentPalette, 768);
- }
-
- // _colorUsedByCycle was not saved before V60
- if (s->isLoading() && s->getVersion() < VER(60)) {
- memset(_colorUsedByCycle, 0, sizeof(_colorUsedByCycle));
- }
-
- //
- // Save/load more global object state
- //
- s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32);
-
-
- //
- // Save/load script variables
- //
- var120Backup = _scummVars[120];
- var98Backup = _scummVars[98];
-
- if (s->getVersion() > VER(37))
- s->saveLoadArrayOf(_roomVars, _numRoomVariables, sizeof(_roomVars[0]), sleInt32);
-
- // The variables grew from 16 to 32 bit.
- if (s->getVersion() < VER(15))
- s->saveLoadArrayOf(_scummVars, _numVariables, sizeof(_scummVars[0]), sleInt16);
- else
- s->saveLoadArrayOf(_scummVars, _numVariables, sizeof(_scummVars[0]), sleInt32);
-
- if (_gameId == GID_TENTACLE) // Maybe misplaced, but that's the main idea
- _scummVars[120] = var120Backup;
- if (_gameId == GID_INDY4)
- _scummVars[98] = var98Backup;
-
- s->saveLoadArrayOf(_bitVars, _numBitVariables >> 3, 1, sleByte);
-
-
- //
- // Save/load a list of the locked objects
- //
- if (s->isSaving()) {
- for (i = rtFirst; i <= rtLast; i++)
- for (j = 1; j < res.num[i]; j++) {
- if (res.isLocked(i, j)) {
- s->saveByte(i);
- s->saveUint16(j);
- }
- }
- s->saveByte(0xFF);
- } else {
- while ((i = s->loadByte()) != 0xFF) {
- j = s->loadUint16();
- res.lock(i, j);
- }
- }
-
-
- //
- // Save/load the Audio CD status
- //
- if (s->getVersion() >= VER(24)) {
- AudioCDManager::Status info;
- if (s->isSaving())
- info = AudioCD.getStatus();
- s->saveLoadArrayOf(&info, 1, sizeof(info), audioCDEntries);
- // If we are loading, and the music being loaded was supposed to loop
- // forever, then resume playing it. This helps a lot when the audio CD
- // is used to provide ambient music (see bug #788195).
- if (s->isLoading() && info.playing && info.numLoops < 0)
- AudioCD.play(info.track, info.numLoops, info.start, info.duration);
- }
-
-
- //
- // Save/load the iMuse status
- //
- if (_imuse && (_saveSound || !_saveTemporaryState)) {
- _imuse->save_or_load(s, this);
- }
-}
-
-void ScummEngine_v5::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
-
- const SaveLoadEntry cursorEntries[] = {
- MKARRAY2(ScummEngine_v5, _cursorImages[0][0], sleUint16, 16, 4, (byte*)_cursorImages[1] - (byte*)_cursorImages[0], VER(44)),
- MKARRAY(ScummEngine_v5, _cursorHotspots[0], sleByte, 8, VER(44)),
- MKEND()
- };
-
- // This is probably only needed for Loom.
- s->saveLoadEntries(this, cursorEntries);
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
-
- const SaveLoadEntry subtitleQueueEntries[] = {
- MKARRAY(SubtitleText, text[0], sleByte, 256, VER(61)),
- MKLINE(SubtitleText, charset, sleByte, VER(61)),
- MKLINE(SubtitleText, color, sleByte, VER(61)),
- MKLINE(SubtitleText, xpos, sleInt16, VER(61)),
- MKLINE(SubtitleText, ypos, sleInt16, VER(61)),
- MKLINE(SubtitleText, actorSpeechMsg, sleByte, VER(61)),
- MKEND()
- };
-
- const SaveLoadEntry V7Entries[] = {
- MKLINE(ScummEngine_v7, _subtitleQueuePos, sleInt32, VER(61)),
- MKEND()
- };
-
- _imuseDigital->saveOrLoad(s);
-
- s->saveLoadArrayOf(_subtitleQueue, ARRAYSIZE(_subtitleQueue), sizeof(_subtitleQueue[0]), subtitleQueueEntries);
- s->saveLoadEntries(this, V7Entries);
-}
-#endif
-
-void ScummEngine_v60he::saveOrLoad(Serializer *s) {
- ScummEngine::saveOrLoad(s);
-
- s->saveLoadArrayOf(_arraySlot, _numArray, sizeof(_arraySlot[0]), sleByte);
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v70he::saveOrLoad(Serializer *s) {
- ScummEngine_v60he::saveOrLoad(s);
-
- const SaveLoadEntry HE70Entries[] = {
- MKLINE(ScummEngine_v70he, _heSndSoundId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v70he, _heSndOffset, sleInt32, VER(51)),
- MKLINE(ScummEngine_v70he, _heSndChannel, sleInt32, VER(51)),
- MKLINE(ScummEngine_v70he, _heSndFlags, sleInt32, VER(51)),
- MKEND()
- };
-
- s->saveLoadEntries(this, HE70Entries);
-}
-
-void ScummEngine_v71he::saveOrLoad(Serializer *s) {
- ScummEngine_v70he::saveOrLoad(s);
-
- const SaveLoadEntry polygonEntries[] = {
- MKLINE(WizPolygon, vert[0].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[0].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[1].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[1].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[2].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[2].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[3].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[3].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[4].x, sleInt16, VER(40)),
- MKLINE(WizPolygon, vert[4].y, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.left, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.top, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.right, sleInt16, VER(40)),
- MKLINE(WizPolygon, bound.bottom, sleInt16, VER(40)),
- MKLINE(WizPolygon, id, sleInt16, VER(40)),
- MKLINE(WizPolygon, numVerts, sleInt16, VER(40)),
- MKLINE(WizPolygon, flag, sleByte, VER(40)),
- MKEND()
- };
-
- s->saveLoadArrayOf(_wiz->_polygons, ARRAYSIZE(_wiz->_polygons), sizeof(_wiz->_polygons[0]), polygonEntries);
-}
-
-void ScummEngine_v90he::saveOrLoad(Serializer *s) {
- ScummEngine_v71he::saveOrLoad(s);
-
- const SaveLoadEntry floodFillEntries[] = {
- MKLINE(FloodFillParameters, box.left, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, box.top, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, box.right, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, box.bottom, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, x, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, y, sleInt32, VER(51)),
- MKLINE(FloodFillParameters, flags, sleInt32, VER(51)),
- MK_OBSOLETE(FloodFillParameters, unk1C, sleInt32, VER(51), VER(62)),
- MKEND()
- };
-
- const SaveLoadEntry HE90Entries[] = {
- MKLINE(ScummEngine_v90he, _curMaxSpriteId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _curSpriteId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _curSpriteGroupId, sleInt32, VER(51)),
- MK_OBSOLETE(ScummEngine_v90he, _numSpritesToProcess, sleInt32, VER(51), VER(63)),
- MKLINE(ScummEngine_v90he, _heObject, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _heObjectNum, sleInt32, VER(51)),
- MKLINE(ScummEngine_v90he, _hePaletteNum, sleInt32, VER(51)),
- MKEND()
- };
-
- _sprite->saveOrLoadSpriteData(s);
-
- s->saveLoadArrayOf(&_floodFillParams, 1, sizeof(_floodFillParams), floodFillEntries);
-
- s->saveLoadEntries(this, HE90Entries);
-}
-
-void ScummEngine_v99he::saveOrLoad(Serializer *s) {
- ScummEngine_v90he::saveOrLoad(s);
-
- s->saveLoadArrayOf(_hePalettes, (_numPalettes + 1) * 1024, sizeof(_hePalettes[0]), sleUint8);
-}
-
-void ScummEngine_v100he::saveOrLoad(Serializer *s) {
- ScummEngine_v99he::saveOrLoad(s);
-
- const SaveLoadEntry HE100Entries[] = {
- MKLINE(ScummEngine_v100he, _heResId, sleInt32, VER(51)),
- MKLINE(ScummEngine_v100he, _heResType, sleInt32, VER(51)),
- MKEND()
- };
-
- s->saveLoadEntries(this, HE100Entries);
-}
-#endif
-
-void ScummEngine::saveLoadResource(Serializer *ser, int type, int idx) {
- byte *ptr;
- uint32 size;
-
- if (!res.mode[type]) {
- if (ser->isSaving()) {
- ptr = res.address[type][idx];
- if (ptr == NULL) {
- ser->saveUint32(0);
- return;
- }
-
- size = ((MemBlkHeader *)ptr)->size;
-
- ser->saveUint32(size);
- ser->saveBytes(ptr + sizeof(MemBlkHeader), size);
-
- if (type == rtInventory) {
- ser->saveUint16(_inventory[idx]);
- }
- if (type == rtObjectName && ser->getVersion() >= VER(25)) {
- ser->saveUint16(_newNames[idx]);
- }
- } else {
- size = ser->loadUint32();
- if (size) {
- res.createResource(type, idx, size);
- ser->loadBytes(getResourceAddress(type, idx), size);
- if (type == rtInventory) {
- _inventory[idx] = ser->loadUint16();
- }
- if (type == rtObjectName && ser->getVersion() >= VER(25)) {
- // Paranoia: We increased the possible number of new names
- // to fix bugs #933610 and #936323. The savegame format
- // didn't change, but at least during the transition
- // period there is a slight chance that we try to load
- // more names than we have allocated space for. If so,
- // discard them.
- if (idx < _numNewNames)
- _newNames[idx] = ser->loadUint16();
- }
- }
- }
- } else if (res.mode[type] == 2 && ser->getVersion() >= VER(23)) {
- // Save/load only a list of resource numbers that need reloaded.
- if (ser->isSaving()) {
- ser->saveUint16(res.address[type][idx] ? 1 : 0);
- } else {
- if (ser->loadUint16())
- ensureResourceLoaded(type, idx);
- }
- }
-}
-
-void ScummEngine::saveResource(Serializer *ser, int type, int idx) {
- assert(res.address[type][idx]);
-
- if ((res.mode[type] == 0) || (_heversion >= 60 && res.mode[type] == 2 && idx == 1)) {
- byte *ptr = res.address[type][idx];
- uint32 size = ((MemBlkHeader *)ptr)->size;
-
- ser->saveUint32(size);
- ser->saveBytes(ptr + sizeof(MemBlkHeader), size);
-
- if (type == rtInventory) {
- ser->saveUint16(_inventory[idx]);
- }
- if (type == rtObjectName) {
- ser->saveUint16(_newNames[idx]);
- }
- }
-}
-
-void ScummEngine::loadResource(Serializer *ser, int type, int idx) {
- if ((res.mode[type] == 0) || (_heversion >= 60 && res.mode[type] == 2 && idx == 1)) {
- uint32 size = ser->loadUint32();
- assert(size);
- res.createResource(type, idx, size);
- ser->loadBytes(getResourceAddress(type, idx), size);
-
- if (type == rtInventory) {
- _inventory[idx] = ser->loadUint16();
- }
- if (type == rtObjectName) {
- _newNames[idx] = ser->loadUint16();
- }
- } else if (res.mode[type] == 2) {
- ensureResourceLoaded(type, idx);
- }
-}
-
-void Serializer::saveBytes(void *b, int len) {
- _saveStream->write(b, len);
-}
-
-void Serializer::loadBytes(void *b, int len) {
- _loadStream->read(b, len);
-}
-
-void Serializer::saveUint32(uint32 d) {
- _saveStream->writeUint32LE(d);
-}
-
-void Serializer::saveUint16(uint16 d) {
- _saveStream->writeUint16LE(d);
-}
-
-void Serializer::saveByte(byte b) {
- _saveStream->writeByte(b);
-}
-
-uint32 Serializer::loadUint32() {
- return _loadStream->readUint32LE();
-}
-
-uint16 Serializer::loadUint16() {
- return _loadStream->readUint16LE();
-}
-
-byte Serializer::loadByte() {
- return _loadStream->readByte();
-}
-
-void Serializer::saveArrayOf(void *b, int len, int datasize, byte filetype) {
- byte *at = (byte *)b;
- uint32 data;
-
- // speed up byte arrays
- if (datasize == 1 && filetype == sleByte) {
- if (len > 0) {
- saveBytes(b, len);
- }
- return;
- }
-
- while (--len >= 0) {
- if (datasize == 0) {
- // Do nothing for obsolete data
- data = 0;
- } else if (datasize == 1) {
- data = *(byte *)at;
- at += 1;
- } else if (datasize == 2) {
- data = *(uint16 *)at;
- at += 2;
- } else if (datasize == 4) {
- data = *(uint32 *)at;
- at += 4;
- } else {
- error("saveLoadArrayOf: invalid size %d", datasize);
- }
- switch (filetype) {
- case sleByte:
- saveByte((byte)data);
- break;
- case sleUint16:
- case sleInt16:
- saveUint16((int16)data);
- break;
- case sleInt32:
- case sleUint32:
- saveUint32(data);
- break;
- default:
- error("saveLoadArrayOf: invalid filetype %d", filetype);
- }
- }
-}
-
-void Serializer::loadArrayOf(void *b, int len, int datasize, byte filetype) {
- byte *at = (byte *)b;
- uint32 data;
-
- // speed up byte arrays
- if (datasize == 1 && filetype == sleByte) {
- loadBytes(b, len);
- return;
- }
-
- while (--len >= 0) {
- switch (filetype) {
- case sleByte:
- data = loadByte();
- break;
- case sleUint16:
- data = loadUint16();
- break;
- case sleInt16:
- data = (int16)loadUint16();
- break;
- case sleUint32:
- data = loadUint32();
- break;
- case sleInt32:
- data = (int32)loadUint32();
- break;
- default:
- error("saveLoadArrayOf: invalid filetype %d", filetype);
- }
- if (datasize == 0) {
- // Do nothing for obsolete data
- } else if (datasize == 1) {
- *(byte *)at = (byte)data;
- at += 1;
- } else if (datasize == 2) {
- *(uint16 *)at = (uint16)data;
- at += 2;
- } else if (datasize == 4) {
- *(uint32 *)at = data;
- at += 4;
- } else {
- error("saveLoadArrayOf: invalid size %d", datasize);
- }
- }
-}
-
-void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle) {
- byte *data = (byte *)b;
-
- if (isSaving()) {
- while (--num >= 0) {
- saveEntries(data, sle);
- data += datasize;
- }
- } else {
- while (--num >= 0) {
- loadEntries(data, sle);
- data += datasize;
- }
- }
-}
-
-void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) {
- if (isSaving())
- saveArrayOf(b, len, datasize, filetype);
- else
- loadArrayOf(b, len, datasize, filetype);
-}
-
-void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
- if (isSaving())
- saveEntries(d, sle);
- else
- loadEntries(d, sle);
-}
-
-void Serializer::saveEntries(void *d, const SaveLoadEntry *sle) {
- byte type;
- byte *at;
- int size;
-
- while (sle->offs != 0xFFFF) {
- at = (byte *)d + sle->offs;
- size = sle->size;
- type = (byte) sle->type;
-
- if (sle->maxVersion != CURRENT_VER) {
- // Skip obsolete entries
- if (type & 128)
- sle++;
- } else {
- // save entry
- int columns = 1;
- int rows = 1;
- int rowlen = 0;
- if (type & 128) {
- sle++;
- columns = sle->offs;
- rows = sle->type;
- rowlen = sle->size;
- type &= ~128;
- }
- while (rows--) {
- saveArrayOf(at, columns, size, type);
- at += rowlen;
- }
- }
- sle++;
- }
-}
-
-void Serializer::loadEntries(void *d, const SaveLoadEntry *sle) {
- byte type;
- byte *at;
- int size;
-
- while (sle->offs != 0xFFFF) {
- at = (byte *)d + sle->offs;
- size = sle->size;
- type = (byte) sle->type;
-
- if (_savegameVersion < sle->minVersion || _savegameVersion > sle->maxVersion) {
- // Skip entries which are not present in this save game version
- if (type & 128)
- sle++;
- } else {
- // load entry
- int columns = 1;
- int rows = 1;
- int rowlen = 0;
-
- if (type & 128) {
- sle++;
- columns = sle->offs;
- rows = sle->type;
- rowlen = sle->size;
- type &= ~128;
- }
- while (rows--) {
- loadArrayOf(at, columns, size, type);
- at += rowlen;
- }
- }
- sle++;
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/saveload.h b/scumm/saveload.h
deleted file mode 100644
index dc2c3b5262..0000000000
--- a/scumm/saveload.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SAVELOAD_H
-#define SAVELOAD_H
-
-#include "common/scummsys.h"
-
-namespace Common {
- class InSaveFile;
- class OutSaveFile;
-}
-
-namespace Scumm {
-
-
-/**
- * The current savegame format version.
- * Our save/load system uses an elaborate scheme to allow us to modify the
- * savegame while keeping full backward compatibility, in the sense that newer
- * ScummVM versions always are able to load old savegames.
- * In order to achieve that, we store a version in the savegame files, and whenever
- * the savegame layout is modified, the version is incremented.
- *
- * This roughly works by marking each savegame entry with a range of versions
- * for which it is valid; the save/load code iterates over all entries, but
- * only saves/loads those which are valid for the version of the savegame
- * which is being loaded/saved currently.
- */
-#define CURRENT_VER 64
-
-/**
- * An auxillary macro, used to specify savegame versions. We use this instead
- * of just writing the raw version, because this way they stand out more to
- * the reading eye, making it a bit easier to navigate through the code.
- */
-#define VER(x) x
-
-
-/**
- * The OFFS macro essentially provides the functionality of offsetof(), that
- * is, it determines the offset of a struct/class member within instances of
- * that class.
- *
- * This is a place where we cheat a bit and sacrifice some potential portability
- * (although so far we haven't encountered any platform where this matters).
- *
- * To work around a warning in GCC 3.2 (and 3.1 ?) regarding non-POD types,
- * we use a small trick: instead of 0 we use 42. Why? Well, it seems newer GCC
- * versions have a heuristic built in to detect "offset-of" patterns - which is exactly
- * what our OFFS macro does. Now, for non-POD types this is not really legal, because
- * member need not be at a fixed offset relative to the variable, even if they are in
- * current reality (many of our complex structs are non-POD; for an explanation of
- * what POD means refer to http://www-cpd.fnal.gov/personal/wb/boost/ISOcxx/doc/POD.html)
- */
-#define OFFS(type,item) (((long)(&((type*)42)->type::item))-42)
-
-/**
- * Similar to the OFFS macro, this macro computes the size (in bytes) of a
- * member of a given struct/class type.
- */
-#define SIZE(type,item) sizeof(((type*)42)->type::item)
-
-// Any item that is still in use automatically gets a maxVersion equal to CURRENT_VER
-#define MKLINE(type,item,saveas,minVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,CURRENT_VER}
-#define MKARRAY(type,item,saveas,dim,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {dim,1,0,0,0}
-#define MKARRAY2(type,item,saveas,dim,dim2,rowlen,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {dim,dim2,rowlen,0,0}
-
-// Use this if you have an entry that used to be smaller:
-#define MKLINE_OLD(type,item,saveas,minVer,maxVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,maxVer}
-#define MKARRAY_OLD(type,item,saveas,dim,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {dim,1,0,0,0}
-#define MKARRAY2_OLD(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {dim,dim2,rowlen,0,0}
-
-// An obsolete item/array, to be ignored upon load. We retain the type/item params to make it easier to debug.
-// Obsolete items have size == 0.
-#define MK_OBSOLETE(type,item,saveas,minVer,maxVer) {0,saveas,0,minVer,maxVer}
-#define MK_OBSOLETE_ARRAY(type,item,saveas,dim,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {dim,1,0,0,0}
-#define MK_OBSOLETE_ARRAY2(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {dim,dim2,rowlen,0,0}
-
-// End marker
-#define MKEND() {0xFFFF,0xFF,0xFF,0,0}
-
-
-enum {
- sleByte = 1,
- sleUint8 = 1,
- sleInt8 = 1,
- sleInt16 = 2,
- sleUint16 = 3,
- sleInt32 = 4,
- sleUint32 = 5
-};
-
-struct SaveLoadEntry {
- uint32 offs; // or: array dimension
- uint16 type; // or: array dimension 2
- uint16 size; // or: array row length
- uint8 minVersion;
- uint8 maxVersion;
-};
-
-class Serializer {
-public:
- Serializer(Common::InSaveFile *in, Common::OutSaveFile *out, uint32 savegameVersion)
- : _loadStream(in), _saveStream(out),
- _savegameVersion(savegameVersion)
- { }
-
- void saveLoadArrayOf(void *b, int len, int datasize, byte filetype);
- void saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle);
- void saveLoadEntries(void *d, const SaveLoadEntry *sle);
-
- bool isSaving() { return (_saveStream != 0); }
- bool isLoading() { return (_loadStream != 0); }
- uint32 getVersion() { return _savegameVersion; }
-
- void saveUint32(uint32 d);
- void saveUint16(uint16 d);
- void saveByte(byte b);
-
- byte loadByte();
- uint16 loadUint16();
- uint32 loadUint32();
-
- void saveBytes(void *b, int len);
- void loadBytes(void *b, int len);
-
-protected:
- Common::InSaveFile *_loadStream;
- Common::OutSaveFile *_saveStream;
- uint32 _savegameVersion;
-
- void saveArrayOf(void *b, int len, int datasize, byte filetype);
- void loadArrayOf(void *b, int len, int datasize, byte filetype);
-
- void saveEntries(void *d, const SaveLoadEntry *sle);
- void loadEntries(void *d, const SaveLoadEntry *sle);
-};
-
-
-// Mixin class / interface. Maybe call it ISerializable or SerializableMixin ?
-class Serializable {
-public:
- virtual ~Serializable() {}
- virtual void saveLoadWithSerializer(Serializer *ser) = 0;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/script.cpp b/scumm/script.cpp
deleted file mode 100644
index c6a971837f..0000000000
--- a/scumm/script.cpp
+++ /dev/null
@@ -1,1355 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-#include "common/util.h"
-
-#include "scumm/actor.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/util.h"
-#include "scumm/scumm.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-/* Start executing script 'script' with the given parameters */
-void ScummEngine::runScript(int script, bool freezeResistant, bool recursive, int *lvarptr, int cycle) {
- ScriptSlot *s;
- byte *scriptPtr;
- uint32 scriptOffs;
- byte scriptType;
- int slot;
-
- if (!script)
- return;
-
- if (!recursive)
- stopScript(script);
-
- if (script < _numGlobalScripts) {
- scriptPtr = getResourceAddress(rtScript, script);
- scriptOffs = _resourceHeaderSize;
- scriptType = WIO_GLOBAL;
-
- debugC(DEBUG_SCRIPTS, "runScript(Global-%d) from %d-%d", script,
- vm.slot[_currentScript].number, _roomResource);
- } else {
- scriptOffs = _localScriptOffsets[script - _numGlobalScripts];
- if (scriptOffs == 0)
- error("Local script %d is not in room %d", script, _roomResource);
- scriptType = WIO_LOCAL;
-
- debugC(DEBUG_SCRIPTS, "runScript(%d) from %d-%d", script,
- vm.slot[_currentScript].number, _roomResource);
- }
-
- if (cycle == 0)
- cycle = (_heversion >= 90) ? VAR(VAR_SCRIPT_CYCLE) : 1;
-
- slot = getScriptSlot();
-
- s = &vm.slot[slot];
- s->number = script;
- s->offs = scriptOffs;
- s->status = ssRunning;
- s->where = scriptType;
- s->freezeResistant = freezeResistant;
- s->recursive = recursive;
- s->freezeCount = 0;
- s->delayFrameCount = 0;
- s->cycle = cycle;
-
- initializeLocals(slot, lvarptr);
-
- runScriptNested(slot);
-}
-
-void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, bool recursive, int *vars, int slot, int cycle) {
- ScriptSlot *s;
- uint32 obcd;
- int where, offs;
-
- if (!object)
- return;
-
- if (!recursive && (_version >= 3))
- stopObjectScript(object);
-
- where = whereIsObject(object);
-
- if (where == WIO_NOT_FOUND) {
- warning("Code for object %d not in room %d", object, _roomResource);
- return;
- }
-
- obcd = getOBCDOffs(object);
-
- // Find a free object slot, unless one was specified
- if (slot == -1)
- slot = getScriptSlot();
-
- offs = getVerbEntrypoint(object, entry);
- if (offs == 0)
- return;
-
- if (cycle == 0)
- cycle = (_heversion >= 90) ? VAR(VAR_SCRIPT_CYCLE) : 1;
-
- s = &vm.slot[slot];
- s->number = object;
- s->offs = obcd + offs;
- s->status = ssRunning;
- s->where = where;
- s->freezeResistant = freezeResistant;
- s->recursive = recursive;
- s->freezeCount = 0;
- s->delayFrameCount = 0;
- s->cycle = cycle;
-
- initializeLocals(slot, vars);
-
- runScriptNested(slot);
-}
-
-void ScummEngine::initializeLocals(int slot, int *vars) {
- int i;
- if (!vars) {
- for (i = 0; i < 25; i++)
- vm.localvar[slot][i] = 0;
- } else {
- for (i = 0; i < 25; i++)
- vm.localvar[slot][i] = vars[i];
- }
-}
-
-int ScummEngine::getVerbEntrypoint(int obj, int entry) {
- const byte *objptr, *verbptr;
- int verboffs;
-
- if (whereIsObject(obj) == WIO_NOT_FOUND)
- return 0;
-
- objptr = getOBCDFromObject(obj);
- assert(objptr);
-
- if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC)
- verbptr = objptr + 14;
- else if (_version <= 2)
- verbptr = objptr + 15;
- else if (_features & GF_OLD_BUNDLE)
- verbptr = objptr + 17;
- else if (_features & GF_SMALL_HEADER)
- verbptr = objptr + 19;
- else
- verbptr = findResource(MKID('VERB'), objptr);
-
- assert(verbptr);
-
- verboffs = verbptr - objptr;
-
- if (!(_features & GF_SMALL_HEADER))
- verbptr += _resourceHeaderSize;
-
- if (_version == 8) {
- const uint32 *ptr = (const uint32 *)verbptr;
- uint32 verb;
- do {
- verb = READ_LE_UINT32(ptr);
- if (!verb)
- return 0;
- if (verb == (uint32)entry || verb == 0xFFFFFFFF)
- break;
- ptr += 2;
- } while (1);
- return verboffs + 8 + READ_LE_UINT32(ptr + 1);
- } else if (_version <= 2) {
- do {
- if (!*verbptr)
- return 0;
- if (*verbptr == entry || *verbptr == 0xFF)
- break;
- verbptr += 2;
- } while (1);
-
- return *(verbptr + 1);
- } else {
- do {
- if (!*verbptr)
- return 0;
- if (*verbptr == entry || *verbptr == 0xFF)
- break;
- verbptr += 3;
- } while (1);
-
- if (_features & GF_SMALL_HEADER)
- return READ_LE_UINT16(verbptr + 1);
- else
- return verboffs + READ_LE_UINT16(verbptr + 1);
- }
-}
-
-/* Stop script 'script' */
-void ScummEngine::stopScript(int script) {
- ScriptSlot *ss;
- NestedScript *nest;
- int i, num;
-
- if (script == 0)
- return;
-
- ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
- if (script == ss->number && ss->status != ssDead &&
- (ss->where == WIO_GLOBAL || ss->where == WIO_LOCAL)) {
- if (ss->cutsceneOverride)
- if (_version >= 5)
- error("Script %d stopped with active cutscene/override", script);
- ss->number = 0;
- ss->status = ssDead;
- nukeArrays(i);
- if (_currentScript == i)
- _currentScript = 0xFF;
- }
- }
-
- nest = vm.nest;
- num = vm.numNestedScripts;
-
- while (num > 0) {
- if (nest->number == script &&
- (nest->where == WIO_GLOBAL || nest->where == WIO_LOCAL)) {
- nukeArrays(nest->slot);
- nest->number = 0xFF;
- nest->slot = 0xFF;
- nest->where = 0xFF;
- }
- nest++;
- num--;
- }
-}
-
-/* Stop an object script 'script'*/
-void ScummEngine::stopObjectScript(int script) {
- ScriptSlot *ss;
- NestedScript *nest;
- int i, num;
-
- if (script == 0)
- return;
-
- ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
- if (script == ss->number && ss->status != ssDead &&
- (ss->where == WIO_ROOM || ss->where == WIO_INVENTORY || ss->where == WIO_FLOBJECT)) {
- if (ss->cutsceneOverride)
- if (_version >= 5)
- error("Object %d stopped with active cutscene/override", script);
- ss->number = 0;
- ss->status = ssDead;
- nukeArrays(i);
- if (_currentScript == i)
- _currentScript = 0xFF;
- }
- }
-
- nest = vm.nest;
- num = vm.numNestedScripts;
-
- while (num > 0) {
- if (nest->number == script &&
- (nest->where == WIO_ROOM || nest->where == WIO_INVENTORY || nest->where == WIO_FLOBJECT)) {
- nukeArrays(nest->slot);
- nest->number = 0xFF;
- nest->slot = 0xFF;
- nest->where = 0xFF;
- }
- nest++;
- num--;
- }
-}
-
-/* Return a free script slot */
-int ScummEngine::getScriptSlot() {
- ScriptSlot *s;
- int i;
-
- for (i = 1; i < NUM_SCRIPT_SLOT; i++) {
- s = &vm.slot[i];
- if (s->status == ssDead)
- return i;
- }
- error("Too many scripts running, %d max", NUM_SCRIPT_SLOT);
- return -1;
-}
-
-/* Run script 'script' nested - eg, within the parent script.*/
-void ScummEngine::runScriptNested(int script) {
- NestedScript *nest;
- ScriptSlot *slot;
-
- updateScriptPtr();
-
- nest = &vm.nest[vm.numNestedScripts];
-
- if (_currentScript == 0xFF) {
- nest->number = 0xFF;
- nest->where = 0xFF;
- } else {
- // Store information about the currently running script
- slot = &vm.slot[_currentScript];
- nest->number = slot->number;
- nest->where = slot->where;
- nest->slot = _currentScript;
- }
-
- vm.numNestedScripts++;
-
- if (vm.numNestedScripts > ARRAYSIZE(vm.nest))
- error("Too many nested scripts");
-
- _currentScript = script;
- getScriptBaseAddress();
- getScriptEntryPoint();
- executeScript();
-
- vm.numNestedScripts--;
-
- if (nest->number != 0xFF) {
- // Try to resume the script which called us, if its status has not changed
- // since it invoked us. In particular, we only resume it if it hasn't been
- // stopped in the meantime, and if it did not already move on.
- slot = &vm.slot[nest->slot];
- if (slot->number == nest->number && slot->where == nest->where &&
- slot->status != ssDead && slot->freezeCount == 0) {
- _currentScript = nest->slot;
- getScriptBaseAddress();
- getScriptEntryPoint();
- return;
- }
- }
- _currentScript = 0xFF;
-}
-
-void ScummEngine::updateScriptPtr() {
- if (_currentScript == 0xFF)
- return;
-
- vm.slot[_currentScript].offs = _scriptPointer - _scriptOrgPointer;
-}
-
-/* Nuke arrays based on script */
-void ScummEngine::nukeArrays(byte scriptSlot) {
- int i;
-
- if (_heversion == 0 || scriptSlot == 0)
- return;
-
- for (i = 1; i < _numArray; i++) {
- if (_arraySlot[i] == scriptSlot) {
- res.nukeResource(rtString, i);
- _arraySlot[i] = 0;
- }
- }
-}
-
-/* Get the code pointer to a script */
-void ScummEngine::getScriptBaseAddress() {
- ScriptSlot *ss;
- int idx;
-
- if (_currentScript == 0xFF)
- return;
-
- ss = &vm.slot[_currentScript];
- switch (ss->where) {
- case WIO_INVENTORY: /* inventory script * */
- for (idx = 0; idx < _numInventory; idx++)
- if (_inventory[idx] == ss->number)
- break;
- _scriptOrgPointer = getResourceAddress(rtInventory, idx);
- assert(idx < _numInventory);
- _lastCodePtr = &res.address[rtInventory][idx];
- break;
-
- case WIO_LOCAL:
- case WIO_ROOM: /* room script */
- if (_version == 8) {
- _scriptOrgPointer = getResourceAddress(rtRoomScripts, _roomResource);
- assert(_roomResource < res.num[rtRoomScripts]);
- _lastCodePtr = &res.address[rtRoomScripts][_roomResource];
- } else {
- _scriptOrgPointer = getResourceAddress(rtRoom, _roomResource);
- assert(_roomResource < _numRooms);
- _lastCodePtr = &res.address[rtRoom][_roomResource];
- }
- break;
-
- case WIO_GLOBAL: /* global script */
- _scriptOrgPointer = getResourceAddress(rtScript, ss->number);
- assert(ss->number < _numScripts);
- _lastCodePtr = &res.address[rtScript][ss->number];
- break;
-
- case WIO_FLOBJECT: /* flobject script */
- idx = getObjectIndex(ss->number);
- assert(idx != -1);
- idx = _objs[idx].fl_object_index;
- _scriptOrgPointer = getResourceAddress(rtFlObject, idx);
- assert(idx < _numFlObject);
- _lastCodePtr = &res.address[rtFlObject][idx];
- break;
- default:
- error("Bad type while getting base address");
- }
-
- // The following fixes bug #1202487. Confirmed against disasm.
- if (_version <= 2 && _scriptOrgPointer == NULL) {
- ss->status = ssDead;
- _currentScript = 0xFF;
- }
-}
-
-
-void ScummEngine::getScriptEntryPoint() {
- if (_currentScript == 0xFF)
- return;
- _scriptPointer = _scriptOrgPointer + vm.slot[_currentScript].offs;
-}
-
-/* Execute a script - Read opcode, and execute it from the table */
-void ScummEngine::executeScript() {
- int c;
- while (_currentScript != 0xFF) {
-
- if (_showStack == 1) {
- printf("Stack:");
- for (c=0; c < _scummStackPos; c++) {
- printf(" %d", _vmStack[c]);
- }
- printf("\n");
- }
- _opcode = fetchScriptByte();
- vm.slot[_currentScript].didexec = 1;
- debugC(DEBUG_OPCODES, "Script %d, offset 0x%x: [%X] %s()",
- vm.slot[_currentScript].number,
- _scriptPointer - _scriptOrgPointer,
- _opcode,
- getOpcodeDesc(_opcode));
- if (_hexdumpScripts == true) {
- for (c= -1; c < 15; c++) {
- printf(" %02x", *(_scriptPointer + c));
- }
- printf("\n");
- }
-
- executeOpcode(_opcode);
-
- }
- CHECK_HEAP;
-}
-
-byte ScummEngine::fetchScriptByte() {
- if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) {
- long oldoffs = _scriptPointer - _scriptOrgPointer;
- getScriptBaseAddress();
- _scriptPointer = _scriptOrgPointer + oldoffs;
- }
- return *_scriptPointer++;
-}
-
-uint ScummEngine::fetchScriptWord() {
- int a;
- if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) {
- long oldoffs = _scriptPointer - _scriptOrgPointer;
- getScriptBaseAddress();
- _scriptPointer = _scriptOrgPointer + oldoffs;
- }
- a = READ_LE_UINT16(_scriptPointer);
- _scriptPointer += 2;
- return a;
-}
-
-int ScummEngine::fetchScriptWordSigned() {
- return (int16)fetchScriptWord();
-}
-
-uint ScummEngine::fetchScriptDWord() {
- int a;
- if (*_lastCodePtr + sizeof(MemBlkHeader) != _scriptOrgPointer) {
- uint32 oldoffs = _scriptPointer - _scriptOrgPointer;
- getScriptBaseAddress();
- _scriptPointer = _scriptOrgPointer + oldoffs;
- }
- a = READ_LE_UINT32(_scriptPointer);
- _scriptPointer += 4;
- return a;
-}
-
-int ScummEngine::fetchScriptDWordSigned() {
- return (int32)fetchScriptDWord();
-}
-
-int ScummEngine::readVar(uint var) {
- int a;
-
- debugC(DEBUG_VARS, "readvar(%d)", var);
-
- if ((var & 0x2000) && (_version <= 5)) {
- a = fetchScriptWord();
- if (a & 0x2000)
- var += readVar(a & ~0x2000);
- else
- var += a & 0xFFF;
- var &= ~0x2000;
- }
-
- if (!(var & 0xF000)) {
- if (!_copyProtection) {
- if (var == 490 && _gameId == GID_MONKEY2) {
- var = 518;
- }
- }
-
- if (VAR_SUBTITLES != 0xFF && var == VAR_SUBTITLES) {
- return ConfMan.getBool("subtitles");
- }
- if (VAR_NOSUBTITLES != 0xFF && var == VAR_NOSUBTITLES) {
- return !ConfMan.getBool("subtitles");
- }
-
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(r)");
- return _scummVars[var];
- }
-
- if (var & 0x8000) {
- if (_heversion >= 80) {
- var &= 0xFFF;
- checkRange(_numRoomVariables - 1, 0, var, "Room variable %d out of range(w)");
- return _roomVars[var];
-
- } else if (_version <= 3 && !(_gameId == GID_INDY3 && (_platform == Common::kPlatformFMTowns))) {
- int bit = var & 0xF;
- var = (var >> 4) & 0xFF;
-
- if (!_copyProtection) {
- if (_gameId == GID_LOOM && (_platform == Common::kPlatformFMTowns) && var == 214 && bit == 15) {
- return 0;
- } else if (_gameId == GID_ZAK && (_platform == Common::kPlatformFMTowns) && var == 151 && bit == 8) {
- return 0;
- }
- }
-
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(rzb)");
- return (_scummVars[ var ] & ( 1 << bit ) ) ? 1 : 0;
- } else {
- var &= 0x7FFF;
- if (!_copyProtection) {
- if (_gameId == GID_INDY3 && (_platform == Common::kPlatformFMTowns) && var == 1508)
- return 0;
- }
-
- checkRange(_numBitVariables - 1, 0, var, "Bit variable %d out of range(r)");
- return (_bitVars[var >> 3] & (1 << (var & 7))) ? 1 : 0;
- }
- }
-
- if (var & 0x4000) {
- if (_features & GF_FEW_LOCALS) {
- var &= 0xF;
- } else {
- var &= 0xFFF;
- }
-
- if (_heversion >= 80)
- checkRange(25, 0, var, "Local variable %d out of range(r)");
- else
- checkRange(20, 0, var, "Local variable %d out of range(r)");
- return vm.localvar[_currentScript][var];
- }
-
- error("Illegal varbits (r)");
- return -1;
-}
-
-void ScummEngine::writeVar(uint var, int value) {
- debugC(DEBUG_VARS, "writeVar(%d, %d)", var, value);
-
- if (!(var & 0xF000)) {
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(w)");
-
- if (VAR_SUBTITLES != 0xFF && var == VAR_SUBTITLES) {
- // Ignore default setting in HE72-73 games
- if (_heversion <= 73 && vm.slot[_currentScript].number == 1)
- return;
- assert(value == 0 || value == 1);
- ConfMan.set("subtitles", value);
- }
- if (VAR_NOSUBTITLES != 0xFF && var == VAR_NOSUBTITLES) {
- // Ignore default setting in HE60-71 games
- if (_heversion >= 60 && vm.slot[_currentScript].number == 1)
- return;
- assert(value == 0 || value == 1);
- ConfMan.set("subtitles", !value);
- }
-
- if (var == VAR_CHARINC && ConfMan.hasKey("talkspeed")) {
- uint talkspeed = ConfMan.getInt("talkspeed");
- if (talkspeed <= 9)
- VAR(VAR_CHARINC) = talkspeed;
- } else {
- _scummVars[var] = value;
- }
-
- if ((_varwatch == (int)var) || (_varwatch == 0)) {
- if (vm.slot[_currentScript].number < 100)
- debug(1, "vars[%d] = %d (via script-%d)", var, value, vm.slot[_currentScript].number);
- else
- debug(1, "vars[%d] = %d (via room-%d-%d)", var, value, _currentRoom,
- vm.slot[_currentScript].number);
- }
- return;
- }
-
- if (var & 0x8000) {
- if (_heversion >= 80) {
- var &= 0xFFF;
- checkRange(_numRoomVariables - 1, 0, var, "Room variable %d out of range(w)");
- _roomVars[var] = value;
-
- } else if (_version <= 3 && !(_gameId == GID_INDY3 && (_platform == Common::kPlatformFMTowns))) {
- // In the old games, the bit variables were using the same memory
- // as the normal variables!
- int bit = var & 0xF;
- var = (var >> 4) & 0xFF;
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(wzb)");
- if (value)
- _scummVars[var] |= ( 1 << bit );
- else
- _scummVars[var] &= ~( 1 << bit );
- } else {
- var &= 0x7FFF;
- checkRange(_numBitVariables - 1, 0, var, "Bit variable %d out of range(w)");
-
- if (value)
- _bitVars[var >> 3] |= (1 << (var & 7));
- else
- _bitVars[var >> 3] &= ~(1 << (var & 7));
- }
- return;
- }
-
- if (var & 0x4000) {
- if (_features & GF_FEW_LOCALS) {
- var &= 0xF;
- } else {
- var &= 0xFFF;
- }
-
- if (_heversion >= 80)
- checkRange(25, 0, var, "Local variable %d out of range(w)");
- else
- checkRange(20, 0, var, "Local variable %d out of range(w)");
-
- vm.localvar[_currentScript][var] = value;
- return;
- }
-
- error("Illegal varbits (w)");
-}
-
-void ScummEngine::getResultPos() {
- int a;
-
- _resultVarNumber = fetchScriptWord();
- if (_resultVarNumber & 0x2000) {
- a = fetchScriptWord();
- if (a & 0x2000) {
- _resultVarNumber += readVar(a & ~0x2000);
- } else {
- _resultVarNumber += a & 0xFFF;
- }
- _resultVarNumber &= ~0x2000;
- }
-}
-
-void ScummEngine::setResult(int value) {
- writeVar(_resultVarNumber, value);
-}
-
-void ScummEngine::push(int a) {
- assert(_scummStackPos >= 0 && _scummStackPos < ARRAYSIZE(_vmStack));
- debug(9, "push %d", a);
- _vmStack[_scummStackPos++] = a;
-}
-
-int ScummEngine::pop() {
- if (_scummStackPos < 1 || _scummStackPos > ARRAYSIZE(_vmStack)) {
- error("No items on stack to pop() for %s (0x%X) at [%d-%d]", getOpcodeDesc(_opcode), _opcode, _roomResource, vm.slot[_currentScript].number);
- }
- --_scummStackPos;
- debug(9, "pop %d", _vmStack[_scummStackPos]);
- return _vmStack[_scummStackPos];
-}
-
-void ScummEngine::stopObjectCode() {
- ScriptSlot *ss;
-
- ss = &vm.slot[_currentScript];
- if (ss->cutsceneOverride == 255) { /* FIXME: What does this? */
- warning("Cutscene for script %d has overflown. Resetting.", ss->number);
- ss->cutsceneOverride = 0;
- }
-
- if (ss->where != WIO_GLOBAL && ss->where != WIO_LOCAL) {
- if (ss->cutsceneOverride) {
- if (_version >= 5)
- warning("Object %d ending with active cutscene/override (%d)", ss->number, ss->cutsceneOverride);
- ss->cutsceneOverride = 0;
- }
- } else {
- if (ss->cutsceneOverride) {
- if (_version >= 5)
- warning("Script %d ending with active cutscene/override (%d)", ss->number, ss->cutsceneOverride);
- ss->cutsceneOverride = 0;
- }
- }
- nukeArrays(_currentScript);
- ss->number = 0;
- ss->status = ssDead;
- _currentScript = 0xFF;
-}
-
-void ScummEngine::runInventoryScript(int i) {
- int args[24];
- memset(args, 0, sizeof(args));
- args[0] = i;
- if (VAR(VAR_INVENTORY_SCRIPT)) {
- if (_gameId == GID_INDY3 && _platform == Common::kPlatformMacintosh) {
- inventoryScript();
- } else {
- runScript(VAR(VAR_INVENTORY_SCRIPT), 0, 0, args);
- }
- }
-}
-
-void ScummEngine::inventoryScript() {
- VerbSlot *vs;
- int args[24];
- int j, slot;
-
- memset(args, 0, sizeof(args));
-
- if (VAR(67) < 0) {
- VAR(67) = 0;
- }
- args[5] = getInventoryCount(VAR(VAR_EGO));
- if (args[5] <= 6) {
- VAR(67) = 0;
- }
- if (args[5] >= 6) {
- args[5] -= 6;
- }
- args[6] = 0;
- if (VAR(67) >= args[5]) {
- VAR(67) = args[5];
- args[4] = args[5];
- args[5] /= 2;
- args[5] *= 2;
- args[4] -= args[5];
- if (args[4]) {
- VAR(67)++;
- }
- args[6]++;
- }
- args[2] = 1;
- for (j = 1; j < 7; j++) {
- args[1] = (VAR(67) + args[2]);
- args[3] = findInventory(VAR(VAR_EGO),args[1]);
- VAR(82 + args[2]) = args[3];
- args[2]++;
- }
-
- byte tmp[6];
-
- tmp[0] = 0xFF;
- tmp[1] = 0x06;
- tmp[3] = 0x00;
- tmp[4] = 0x00;
-
- for (j = 0; j < 6; j++) {
- tmp[2] = 0x53 + j;
-
- slot = getVerbSlot(101 + j, 0);
- vs = &_verbs[slot];
- loadPtrToResource(rtVerb, slot, tmp);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- vs->curmode = 1;
- drawVerb(slot, 0);
- }
-
- args[5] = getInventoryCount(VAR(VAR_EGO));
- if (args[5] > 6) {
- slot = getVerbSlot(107, 0);
- if (VAR(67)) {
- vs = &_verbs[slot];
- vs->curmode = 1;
- } else {
- vs = &_verbs[slot];
- vs->curmode = 0;
- }
- drawVerb(slot, 0);
- slot = getVerbSlot(108, 0);
- if (!args[6]) {
- vs = &_verbs[slot];
- vs->curmode = 1;
- } else {
- vs = &_verbs[slot];
- vs->curmode = 0;
- }
- drawVerb(slot, 0);
- } else {
- slot = getVerbSlot(107, 0);
- vs = &_verbs[slot];
- vs->curmode = 0;
- drawVerb(slot, 0);
- slot = getVerbSlot(108, 0);
- vs = &_verbs[slot];
- vs->curmode = 0;
- drawVerb(slot, 0);
- }
-
- verbMouseOver(0);
-}
-
-void ScummEngine::freezeScripts(int flag) {
- int i;
-
- if (_version <= 2) {
- for (i = 0; i < NUM_SCRIPT_SLOT; i++) {
- if (_currentScript != i && vm.slot[i].status != ssDead && !vm.slot[i].freezeResistant) {
- vm.slot[i].status |= 0x80;
- vm.slot[i].freezeCount = 1;
- }
- }
- return;
- }
-
- for (i = 0; i < NUM_SCRIPT_SLOT; i++) {
- if (_currentScript != i && vm.slot[i].status != ssDead && (!vm.slot[i].freezeResistant || flag >= 0x80)) {
- vm.slot[i].status |= 0x80;
- vm.slot[i].freezeCount++;
- }
- }
-
- for (i = 0; i < NUM_SENTENCE; i++)
- _sentence[i].freezeCount++;
-
- if (vm.cutSceneScriptIndex != 0xFF) {
- vm.slot[vm.cutSceneScriptIndex].status &= 0x7F;
- vm.slot[vm.cutSceneScriptIndex].freezeCount = 0;
- }
-}
-
-void ScummEngine::unfreezeScripts() {
- int i;
-
- if (_version <= 2) {
- for (i = 0; i < NUM_SCRIPT_SLOT; i++) {
- vm.slot[i].status &= 0x7F;
- vm.slot[i].freezeCount = 0;
- }
- return;
- }
-
- for (i = 0; i < NUM_SCRIPT_SLOT; i++) {
- if (vm.slot[i].status & 0x80) {
- if (!--vm.slot[i].freezeCount) {
- vm.slot[i].status &= 0x7F;
- }
- }
- }
-
- for (i = 0; i < NUM_SENTENCE; i++) {
- if (_sentence[i].freezeCount > 0)
- _sentence[i].freezeCount--;
- }
-}
-
-
-void ScummEngine::runAllScripts() {
- int i;
-
- for (i = 0; i < NUM_SCRIPT_SLOT; i++)
- vm.slot[i].didexec = 0;
-
- _currentScript = 0xFF;
- int numCycles = (_heversion >= 90) ? VAR(VAR_NUM_SCRIPT_CYCLES) : 1;
-
- for (int cycle = 1; cycle <= numCycles; cycle++) {
- for (i = 0; i < NUM_SCRIPT_SLOT; i++) {
- if (vm.slot[i].cycle == cycle && vm.slot[i].status == ssRunning && vm.slot[i].didexec == 0) {
- _currentScript = (byte)i;
- getScriptBaseAddress();
- getScriptEntryPoint();
- executeScript();
- }
- }
- }
-}
-
-void ScummEngine::runExitScript() {
- if (_version > 2 && VAR(VAR_EXIT_SCRIPT))
- runScript(VAR(VAR_EXIT_SCRIPT), 0, 0, 0);
- if (_EXCD_offs) {
- int slot = getScriptSlot();
- vm.slot[slot].status = ssRunning;
- vm.slot[slot].number = 10001;
- vm.slot[slot].where = WIO_ROOM;
- vm.slot[slot].offs = _EXCD_offs;
- vm.slot[slot].freezeResistant = false;
- vm.slot[slot].recursive = false;
- vm.slot[slot].freezeCount = 0;
- vm.slot[slot].delayFrameCount = 0;
- vm.slot[slot].cycle = 1;
-
- // FIXME: the exit script of room 7 in indy3 only seems to have a size
- // and tag not actual data not even a 00 (stop code). Maybe we should
- // be limiting ourselves to strictly reading the size from the header?
- if (_gameId == GID_INDY3 && !(_features & GF_OLD_BUNDLE)) {
- byte *roomptr = getResourceAddress(rtRoom, _roomResource);
- const byte *excd = findResourceData(MKID('EXCD'), roomptr) - _resourceHeaderSize;
- if (!excd || (getResourceDataSize(excd) < 1)) {
- debug(2, "Exit-%d is empty", _roomResource);
- return;
- }
- }
-
- initializeLocals(slot, 0);
- runScriptNested(slot);
- }
- if (_version > 2 && VAR(VAR_EXIT_SCRIPT2))
- runScript(VAR(VAR_EXIT_SCRIPT2), 0, 0, 0);
-}
-
-void ScummEngine::runEntryScript() {
- if (_version > 2 && VAR(VAR_ENTRY_SCRIPT))
- runScript(VAR(VAR_ENTRY_SCRIPT), 0, 0, 0);
- if (_ENCD_offs) {
- int slot = getScriptSlot();
- vm.slot[slot].status = ssRunning;
- vm.slot[slot].number = 10002;
- vm.slot[slot].where = WIO_ROOM;
- vm.slot[slot].offs = _ENCD_offs;
- vm.slot[slot].freezeResistant = false;
- vm.slot[slot].recursive = false;
- vm.slot[slot].freezeCount = 0;
- vm.slot[slot].delayFrameCount = 0;
- vm.slot[slot].cycle = 1;
- initializeLocals(slot, 0);
- runScriptNested(slot);
- }
- if (_version > 2 && VAR(VAR_ENTRY_SCRIPT2))
- runScript(VAR(VAR_ENTRY_SCRIPT2), 0, 0, 0);
-}
-
-void ScummEngine::killScriptsAndResources() {
- ScriptSlot *ss;
- int i;
-
- ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
- if (ss->where == WIO_ROOM || ss->where == WIO_FLOBJECT) {
- if (ss->cutsceneOverride) {
- if (_version >= 5)
- warning("Object %d stopped with active cutscene/override in exit", ss->number);
- ss->cutsceneOverride = 0;
- }
- nukeArrays(i);
- ss->status = ssDead;
- } else if (ss->where == WIO_LOCAL) {
- if (ss->cutsceneOverride) {
- if (_version >= 5)
- warning("Script %d stopped with active cutscene/override in exit", ss->number);
- ss->cutsceneOverride = 0;
- }
- nukeArrays(i);
- ss->status = ssDead;
- }
- }
-
- /* Nuke local object names */
- if (_newNames) {
- for (i = 0; i < _numNewNames; i++) {
- const int obj = _newNames[i];
- if (obj) {
- const int owner = getOwner(obj);
- // We can delete custom name resources if either the object is
- // no longer in use (i.e. not owned by anyone anymore); or if
- // it is an object which is owned by a room.
- if (owner == 0 || (_version < 7 && owner == OF_OWNER_ROOM)) {
- // WORKAROUND for a problem mentioned in bug report #941275:
- // In FOA in the sentry room, in the chest plate of the statue,
- // the pegs may be renamed to mouth: this custom name is lost
- // when leaving the room; this hack prevents this).
- if (owner == OF_OWNER_ROOM && _gameId == GID_INDY4 && 336 <= obj && obj <= 340)
- continue;
-
- _newNames[i] = 0;
- res.nukeResource(rtObjectName, i);
- }
- }
- }
- }
-}
-
-void ScummEngine::killAllScriptsExceptCurrent() {
- for (int i = 0; i < NUM_SCRIPT_SLOT; i++) {
- if (i != _currentScript) {
- vm.slot[i].status = ssDead;
- if (_version == 6)
- vm.slot[i].cutsceneOverride = 0;
- }
- }
-}
-
-void ScummEngine::doSentence(int verb, int objectA, int objectB) {
- SentenceTab *st;
-
- if (_version >= 7) {
-
- if (objectA == objectB)
- return;
-
- if (_sentenceNum) {
- st = &_sentence[_sentenceNum - 1];
-
- // Check if this doSentence request is identical to the previous one;
- // if yes, ignore this invocation.
- if (_sentenceNum && st->verb == verb && st->objectA == objectA && st->objectB == objectB)
- return;
- }
-
- }
-
- st = &_sentence[_sentenceNum++];
-
- st->verb = verb;
- st->objectA = objectA;
- st->objectB = objectB;
- st->preposition = (objectB != 0);
- st->freezeCount = 0;
-}
-
-void ScummEngine::checkAndRunSentenceScript() {
- int i;
- int localParamList[24];
- const ScriptSlot *ss;
- int sentenceScript;
- if (_version <= 2)
- sentenceScript = 2;
- else
- sentenceScript = VAR(VAR_SENTENCE_SCRIPT);
-
- memset(localParamList, 0, sizeof(localParamList));
- if (isScriptInUse(sentenceScript)) {
- ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
- if (ss->number == sentenceScript && ss->status != ssDead && ss->freezeCount == 0)
- return;
- }
-
- if (!_sentenceNum || _sentence[_sentenceNum - 1].freezeCount)
- return;
-
- _sentenceNum--;
-
- if (_version < 7)
- if (_sentence[_sentenceNum].preposition && _sentence[_sentenceNum].objectB == _sentence[_sentenceNum].objectA)
- return;
-
- if (_version <= 2) {
- _scummVars[VAR_ACTIVE_VERB] = _sentence[_sentenceNum].verb;
- _scummVars[VAR_ACTIVE_OBJECT1] = _sentence[_sentenceNum].objectA;
- _scummVars[VAR_ACTIVE_OBJECT2] = _sentence[_sentenceNum].objectB;
- _scummVars[VAR_VERB_ALLOWED] = (0 != getVerbEntrypoint(_sentence[_sentenceNum].objectA, _sentence[_sentenceNum].verb));
- } else {
- localParamList[0] = _sentence[_sentenceNum].verb;
- localParamList[1] = _sentence[_sentenceNum].objectA;
- localParamList[2] = _sentence[_sentenceNum].objectB;
-
- // WORKAROUND for bug #1407789. The buggy script clearly
- // assumes that one of the two objects is an actor. If that's
- // not the case, fall back on the default sentence script.
-
- if (_gameId == GID_FT && sentenceScript == _buggyFTSentenceScript && !isValidActor(localParamList[1]) && !isValidActor(localParamList[2])) {
- sentenceScript = _defaultFTSentenceScript;
- }
- }
- _currentScript = 0xFF;
- if (sentenceScript)
- runScript(sentenceScript, 0, 0, localParamList);
-}
-
-void ScummEngine::runInputScript(int a, int cmd, int mode) {
- int args[24];
- int verbScript;
-
- if (_gameId == GID_MANIAC && _platform == Common::kPlatformC64) {
- verbScript = 3;
- //_scummVars[9] = cmd;
-
- } else if (_version <= 2) {
- verbScript = 4;
- _scummVars[VAR_CLICK_AREA] = a;
- switch (a) {
- case 1: // Verb clicked
- _scummVars[33] = cmd;
- break;
- case 3: // Inventory clicked
- _scummVars[35] = cmd;
- break;
- }
- } else {
- verbScript = VAR(VAR_VERB_SCRIPT);
- }
-
- memset(args, 0, sizeof(args));
- args[0] = a;
- args[1] = cmd;
- args[2] = mode;
- // All HE 72+ games but only some HE 71 games.
- if (_heversion >= 71) {
- args[3] = VAR(VAR_VIRT_MOUSE_X);
- args[4] = VAR(VAR_VIRT_MOUSE_Y);
- }
-
- // Macintosh verison of indy3ega used different interface, so adjust values.
- if (_gameId == GID_INDY3 && _platform == Common::kPlatformMacintosh) {
- if (a == 1 && (cmd >= 101 && cmd <= 108)) {
- if (cmd == 107) {
- VAR(67) -= 2;
- inventoryScript();
- return;
- } else if (cmd == 108) {
- VAR(67) += 2;
- inventoryScript();
- return;
- } else {
- args[0] = 3;
- args[1] = VAR(83 + (cmd - 101));
- }
- }
- }
-
- if (verbScript)
- runScript(verbScript, 0, 0, args);
-}
-
-void ScummEngine::decreaseScriptDelay(int amount) {
- ScriptSlot *ss = vm.slot;
- int i;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
- if (ss->status == ssPaused) {
- ss->delay -= amount;
- if (ss->delay < 0) {
- ss->status = ssRunning;
- ss->delay = 0;
- }
- }
- }
-}
-
-bool ScummEngine::isScriptInUse(int script) const {
- int i;
- const ScriptSlot *ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
- if (ss->number == script)
- return true;
- return false;
-}
-
-bool ScummEngine::isScriptRunning(int script) const {
- int i;
- const ScriptSlot *ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
- if (ss->number == script && (ss->where == WIO_GLOBAL || ss->where == WIO_LOCAL) && ss->status != ssDead)
- return true;
- return false;
-}
-
-bool ScummEngine::isRoomScriptRunning(int script) const {
- int i;
- const ScriptSlot *ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++)
- if (ss->number == script && ss->where == WIO_ROOM && ss->status != ssDead)
- return true;
- return false;
-}
-
-void ScummEngine::copyScriptString(byte *dst) {
- int len = resStrLen(_scriptPointer) + 1;
- while (len--)
- *dst++ = fetchScriptByte();
- *dst = 0;
-}
-
-//
-// Given a pointer to a Scumm string, this function returns the total byte length
-// of the string data in that resource. To do so it has to understand certain
-// special characters embedded into the string. The reason for this function is that
-// sometimes this embedded data contains zero bytes, thus we can't just use strlen.
-//
-int ScummEngine::resStrLen(const byte *src) const {
- int num = 0;
- byte chr;
- if (src == NULL)
- src = _scriptPointer;
- while ((chr = *src++) != 0) {
- num++;
- if (chr == 255) {
- chr = *src++;
- num++;
-
- // WORKAROUND for bug #985948, a script bug in Indy3. See also
- // the corresponding code in ScummEngine::convertMessageToString().
- if (_gameId == GID_INDY3 && chr == 0x2E) {
- continue;
- }
-
- if (chr != 1 && chr != 2 && chr != 3 && chr != 8) {
- if (_version == 8) {
- src += 4;
- num += 4;
- } else {
- src += 2;
- num += 2;
- }
- }
- }
- }
- return num;
-}
-
-void ScummEngine::beginCutscene(int *args) {
- int scr = _currentScript;
- vm.slot[scr].cutsceneOverride++;
-
- if (++vm.cutSceneStackPointer > ARRAYSIZE(vm.cutSceneData))
- error("Cutscene stack overflow");
-
- vm.cutSceneData[vm.cutSceneStackPointer] = args[0];
- vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
- vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
-
- vm.cutSceneScriptIndex = scr;
- if (VAR(VAR_CUTSCENE_START_SCRIPT))
- runScript(VAR(VAR_CUTSCENE_START_SCRIPT), 0, 0, args);
- vm.cutSceneScriptIndex = 0xFF;
-}
-
-void ScummEngine::endCutscene() {
- ScriptSlot *ss = &vm.slot[_currentScript];
- int args[16];
-
- if (ss->cutsceneOverride > 0) // Only terminate if active
- ss->cutsceneOverride--;
-
- memset(args, 0, sizeof(args));
- args[0] = vm.cutSceneData[vm.cutSceneStackPointer];
-
- VAR(VAR_OVERRIDE) = 0;
-
- if (vm.cutScenePtr[vm.cutSceneStackPointer] && (ss->cutsceneOverride > 0)) // Only terminate if active
- ss->cutsceneOverride--;
-
- vm.cutSceneScript[vm.cutSceneStackPointer] = 0;
- vm.cutScenePtr[vm.cutSceneStackPointer] = 0;
- vm.cutSceneStackPointer--;
-
- if (VAR(VAR_CUTSCENE_END_SCRIPT))
- runScript(VAR(VAR_CUTSCENE_END_SCRIPT), 0, 0, args);
-}
-
-void ScummEngine::abortCutscene() {
- const int idx = vm.cutSceneStackPointer;
- assert(0 <= idx && idx < 5);
-
- uint32 offs = vm.cutScenePtr[idx];
- if (offs) {
- ScriptSlot *ss = &vm.slot[vm.cutSceneScript[idx]];
- ss->offs = offs;
- ss->status = ssRunning;
- ss->freezeCount = 0;
-
- if (ss->cutsceneOverride > 0)
- ss->cutsceneOverride--;
-
- VAR(VAR_OVERRIDE) = 1;
- vm.cutScenePtr[idx] = 0;
-
- // HACK to fix issues with SMUSH and the way it does keyboard handling.
- // In particular, normally abortCutscene() is being called while no
- // scripts are active. But SMUSH runs from *inside* the script engine.
- // And it calls abortCutscene() if ESC is pressed... not good.
- // Proper fix might be to let SMUSH/INSANE run from outside the script
- // engine but that would require lots of changes and may actually have
- // negative effects, too. So we cheat here, to fix bug #751670.
- if (_version == 7)
- getScriptEntryPoint();
-
- }
-}
-
-void ScummEngine::beginOverride() {
- const int idx = vm.cutSceneStackPointer;
- assert(0 <= idx && idx < 5);
-
- vm.cutScenePtr[idx] = _scriptPointer - _scriptOrgPointer;
- vm.cutSceneScript[idx] = _currentScript;
-
- // Skip the jump instruction following the override instruction
- // (the jump is responsible for "skipping" cutscenes, and the reason
- // why we record the current script position in vm.cutScenePtr).
- fetchScriptByte();
- fetchScriptWord();
-
- // This is based on disassembly
- VAR(VAR_OVERRIDE) = 0;
-}
-
-void ScummEngine::endOverride() {
- const int idx = vm.cutSceneStackPointer;
- assert(0 <= idx && idx < 5);
-
- vm.cutScenePtr[idx] = 0;
- vm.cutSceneScript[idx] = 0;
-
- if (_version > 3)
- VAR(VAR_OVERRIDE) = 0;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script.h b/scumm/script.h
deleted file mode 100644
index e832aee8d9..0000000000
--- a/scumm/script.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCRIPT_H
-#define SCRIPT_H
-
-#include "base/engine.h"
-
-namespace Scumm {
-
-/**
- * The number of script slots, which determines the maximal number
- * of concurrently running scripts.
- * WARNING: Do NOT changes this value unless you really have to, as
- * this will break savegame compatibility if done carelessly. If you
- * have to change it, make sure you update saveload.cpp accordingly!
- */
-enum {
- NUM_SCRIPT_SLOT = 80
-};
-
-/* Script status type (slot.status) */
-enum {
- ssDead = 0,
- ssPaused = 1,
- ssRunning = 2
-};
-
-struct ScriptSlot {
- uint32 offs;
- int32 delay;
- uint16 number;
- uint16 delayFrameCount;
- bool freezeResistant, recursive;
- bool didexec;
- byte status;
- byte where;
- byte freezeCount;
- byte cutsceneOverride;
- byte cycle;
-};
-
-struct NestedScript {
- uint16 number;
- uint8 where;
- uint8 slot;
-};
-
-struct VirtualMachineState {
- uint32 cutScenePtr[5];
- byte cutSceneScript[5];
- int16 cutSceneData[5];
- int16 cutSceneScriptIndex;
- byte cutSceneStackPointer;
- ScriptSlot slot[NUM_SCRIPT_SLOT];
- int32 localvar[NUM_SCRIPT_SLOT][26];
-
- NestedScript nest[15];
- byte numNestedScripts;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/script_c64.cpp b/scumm/script_c64.cpp
deleted file mode 100644
index 2e8ff5f4d6..0000000000
--- a/scumm/script_c64.cpp
+++ /dev/null
@@ -1,849 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern.h"
-#include "scumm/object.h"
-#include "scumm/scumm.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_c64, x)
-
-void ScummEngine_c64::setupOpcodes() {
- static const OpcodeEntryC64 opcodes[256] = {
- /* 00 */
- OPCODE(o5_stopObjectCode),
- OPCODE(o2_putActor),
- OPCODE(o5_startMusic),
- OPCODE(o_doSentence),
- /* 04 */
- OPCODE(o_isGreaterEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_getDist),
- OPCODE(o5_getActorRoom),
- /* 08 */
- OPCODE(o_isNotEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_setActorBitVar),
- /* 0C */
- OPCODE(o_loadSound),
- OPCODE(o_printEgo_c64),
- OPCODE(o_putActorAtObject),
- OPCODE(o2_clearState02),
- /* 10 */
- OPCODE(o5_breakHere),
- OPCODE(o_animateActor),
- OPCODE(o2_panCameraTo),
- OPCODE(o_lockActor),
- /* 14 */
- OPCODE(o_print_c64),
- OPCODE(o2_actorFromPos),
- OPCODE(o5_getRandomNr),
- OPCODE(o_clearState08),
- /* 18 */
- OPCODE(o_jumpRelative),
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_move),
- OPCODE(o_getActorBitVar),
- /* 1C */
- OPCODE(o5_startSound),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState04),
- /* 20 */
- OPCODE(o5_stopMusic),
- OPCODE(o2_putActor),
- OPCODE(o5_saveLoadGame),
- OPCODE(o_stopCurrentScript),
- /* 24 */
- OPCODE(o_unknown2),
- OPCODE(o5_loadRoom),
- OPCODE(o_getClosestObjActor),
- OPCODE(o2_getActorY),
- /* 28 */
- OPCODE(o_equalZero),
- OPCODE(o2_setOwnerOf),
- OPCODE(o2_delay),
- OPCODE(o_setActorBitVar),
- /* 2C */
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_putActorInRoom),
- OPCODE(o_print_c64),
- OPCODE(o2_ifState08),
- /* 30 */
- OPCODE(o_loadActor),
- OPCODE(o2_getBitVar),
- OPCODE(o2_setCameraAt),
- OPCODE(o_lockScript),
- /* 34 */
- OPCODE(o5_getDist),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_clearState04),
- /* 38 */
- OPCODE(o_isLessEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_subtract),
- OPCODE(o_stopCurrentScript),
- /* 3C */
- OPCODE(o5_stopSound),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState02),
- /* 40 */
- OPCODE(o2_cutscene),
- OPCODE(o2_putActor),
- OPCODE(o2_startScript),
- OPCODE(o_doSentence),
- /* 44 */
- OPCODE(o_isLess),
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_increment),
- OPCODE(o2_getActorX),
- /* 48 */
- OPCODE(o_isEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_loadRoom),
- OPCODE(o_setActorBitVar),
- /* 4C */
- OPCODE(o_loadScript),
- OPCODE(o_lockRoom),
- OPCODE(o_putActorAtObject),
- OPCODE(o2_clearState02),
- /* 50 */
- OPCODE(o_nop),
- OPCODE(o_animateActor),
- OPCODE(o5_actorFollowCamera),
- OPCODE(o_lockSound),
- /* 54 */
- OPCODE(o5_setObjectName),
- OPCODE(o2_actorFromPos),
- OPCODE(o_getActorMoving),
- OPCODE(o_clearState08),
- /* 58 */
- OPCODE(o_beginOverride),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_add),
- OPCODE(o_getActorBitVar),
- /* 5C */
- OPCODE(o5_startSound),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState04),
- /* 60 */
- OPCODE(o_cursorCommand),
- OPCODE(o2_putActor),
- OPCODE(o2_stopScript),
- OPCODE(o_stopCurrentScript),
- /* 64 */
- OPCODE(o_unknown3),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_getClosestObjActor),
- OPCODE(o5_getActorFacing),
- /* 68 */
- OPCODE(o5_isScriptRunning),
- OPCODE(o2_setOwnerOf),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_setActorBitVar),
- /* 6C */
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_putActorInRoom),
- OPCODE(o2_dummy),
- OPCODE(o2_ifState08),
- /* 70 */
- OPCODE(o_lights),
- OPCODE(o2_getBitVar),
- OPCODE(o_nop),
- OPCODE(o5_getObjectOwner),
- /* 74 */
- OPCODE(o5_getDist),
- OPCODE(o_printEgo_c64),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_clearState04),
- /* 78 */
- OPCODE(o_isGreater),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- /* 7C */
- OPCODE(o5_isSoundRunning),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState02),
- /* 80 */
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_putActor),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_doSentence),
- /* 84 */
- OPCODE(o_isGreaterEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_badOpcode),
- OPCODE(o5_getActorRoom),
- /* 88 */
- OPCODE(o_isNotEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_setActorBitVar),
- /* 8C */
- OPCODE(o_loadSound),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_putActorAtObject),
- OPCODE(o2_setState02),
- /* 90 */
- OPCODE(o2_pickupObject),
- OPCODE(o_animateActor),
- OPCODE(o2_panCameraTo),
- OPCODE(o_unlockActor),
- /* 94 */
- OPCODE(o5_print),
- OPCODE(o2_actorFromPos),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_setState08),
- /* 98 */
- OPCODE(o2_restart),
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_move),
- OPCODE(o_getActorBitVar),
- /* 9C */
- OPCODE(o5_startSound),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState04),
- /* A0 */
- OPCODE(o5_stopObjectCode),
- OPCODE(o2_putActor),
- OPCODE(o5_saveLoadGame),
- OPCODE(o_stopCurrentScript),
- /* A4 */
- OPCODE(o_unknown2),
- OPCODE(o5_loadRoom),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_getActorY),
- /* A8 */
- OPCODE(o_notEqualZero),
- OPCODE(o2_setOwnerOf),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_setActorBitVar),
- /* AC */
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_putActorInRoom),
- OPCODE(o_print_c64),
- OPCODE(o2_ifNotState08),
- /* B0 */
- OPCODE(o_loadActor),
- OPCODE(o2_getBitVar),
- OPCODE(o2_setCameraAt),
- OPCODE(o_unlockScript),
- /* B4 */
- OPCODE(o5_getDist),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_setState04),
- /* B8 */
- OPCODE(o_isLessEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_subtract),
- OPCODE(o_stopCurrentScript),
- /* BC */
- OPCODE(o5_stopSound),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState02),
- /* C0 */
- OPCODE(o2_endCutscene),
- OPCODE(o2_putActor),
- OPCODE(o2_startScript),
- OPCODE(o_doSentence),
- /* C4 */
- OPCODE(o_isLess),
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_decrement),
- OPCODE(o2_getActorX),
- /* C8 */
- OPCODE(o_isEqual),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_loadRoom),
- OPCODE(o_setActorBitVar),
- /* CC */
- OPCODE(o_loadScript),
- OPCODE(o_unlockRoom),
- OPCODE(o_putActorAtObject),
- OPCODE(o2_setState02),
- /* D0 */
- OPCODE(o_nop),
- OPCODE(o_animateActor),
- OPCODE(o5_actorFollowCamera),
- OPCODE(o_unlockSound),
- /* D4 */
- OPCODE(o5_setObjectName),
- OPCODE(o2_actorFromPos),
- OPCODE(o_getActorMoving),
- OPCODE(o_setState08),
- /* D8 */
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_add),
- OPCODE(o_getActorBitVar),
- /* DC */
- OPCODE(o5_startSound),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState04),
- /* E0 */
- OPCODE(o_cursorCommand),
- OPCODE(o2_putActor),
- OPCODE(o2_stopScript),
- OPCODE(o_stopCurrentScript),
- /* E4 */
- OPCODE(o_unknown3),
- OPCODE(o_loadRoomWithEgo),
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_getActorFacing),
- /* E8 */
- OPCODE(o5_isScriptRunning),
- OPCODE(o2_setOwnerOf),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_setActorBitVar),
- /* EC */
- OPCODE(o_stopCurrentScript),
- OPCODE(o5_putActorInRoom),
- OPCODE(o2_dummy),
- OPCODE(o2_ifNotState08),
- /* F0 */
- OPCODE(o_lights),
- OPCODE(o2_getBitVar),
- OPCODE(o_nop),
- OPCODE(o5_getObjectOwner),
- /* F4 */
- OPCODE(o5_getDist),
- OPCODE(o_stopCurrentScript),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_setState04),
- /* F8 */
- OPCODE(o_isGreater),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- OPCODE(o_stopCurrentScript),
- /* FC */
- OPCODE(o5_isSoundRunning),
- OPCODE(o2_setBitVar),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState02)
- };
-
- _opcodesC64 = opcodes;
-}
-
-#define SENTENCE_SCRIPT 2
-
-#define PARAM_1 0x80
-#define PARAM_2 0x40
-#define PARAM_3 0x20
-
-void ScummEngine_c64::executeOpcode(byte i) {
- OpcodeProcC64 op = _opcodesC64[i].proc;
- (this->*op) ();
-}
-
-int ScummEngine_c64::getVarOrDirectWord(byte mask) {
- return getVarOrDirectByte(mask);
-}
-
-uint ScummEngine_c64::fetchScriptWord() {
- return fetchScriptByte();
-}
-
-const char *ScummEngine_c64::getOpcodeDesc(byte i) {
- return _opcodesC64[i].desc;
-}
-
-int ScummEngine_c64::getObjectFlag() {
- if (_opcode & 0x40)
- return _activeObject;
- return fetchScriptByte();
-}
-
-void ScummEngine_c64::decodeParseString() {
- byte buffer[512];
- byte *ptr = buffer;
- byte c;
- bool insertSpace = false;
-
- while ((c = fetchScriptByte())) {
-
- insertSpace = (c & 0x80) != 0;
- c &= 0x7f;
-
- if (c == '/') {
- *ptr++ = 13;
- } else {
- *ptr++ = c;
- }
-
- if (insertSpace)
- *ptr++ = ' ';
-
- }
- *ptr = 0;
-
- int textSlot = 0;
- _string[textSlot].xpos = 0;
- _string[textSlot].ypos = 0;
- _string[textSlot].right = 320;
- _string[textSlot].center = false;
- _string[textSlot].overhead = false;
-
- if (_actorToPrintStrFor == 0xFF)
- _string[textSlot].color = 14;
-
- actorTalk(buffer);
-}
-
-void ScummEngine_c64::setStateCommon(byte type) {
- int obj = getObjectFlag();
- putState(obj, getState(obj) | type);
-}
-
-void ScummEngine_c64::clearStateCommon(byte type) {
- int obj = getObjectFlag();
- putState(obj, getState(obj) & ~type);
-}
-
-void ScummEngine_c64::ifStateCommon(byte type) {
- int obj = getObjectFlag();
-
- if ((getState(obj) & type) == 0) {
- o_jumpRelative();
- } else {
- fetchScriptByte();
- fetchScriptByte();
- }
-}
-
-void ScummEngine_c64::ifNotStateCommon(byte type) {
- int obj = getObjectFlag();
-
- if ((getState(obj) & type) != 0) {
- o_jumpRelative();
- } else {
- fetchScriptByte();
- fetchScriptByte();
- }
-}
-
-void ScummEngine_c64::o_setState08() {
- int obj = getObjectFlag();
- putState(obj, getState(obj) | 0x08);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
-}
-
-void ScummEngine_c64::o_clearState08() {
- int obj = getObjectFlag();
- putState(obj, getState(obj) & ~0x08);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
-}
-
-void ScummEngine_c64::o_stopCurrentScript() {
- int script;
-
- script = vm.slot[_currentScript].number;
-
- if (_currentScript != 0 && vm.slot[_currentScript].number == script)
- stopObjectCode();
- else
- stopScript(script);
-}
-
-void ScummEngine_c64::o_loadSound() {
- int resid = fetchScriptByte();
- ensureResourceLoaded(rtSound, resid);
-}
-
-void ScummEngine_c64::o_lockSound() {
- int resid = fetchScriptByte();
- res.lock(rtSound, resid);
- debug(0, "o_lockSound (%d)", resid);
-}
-
-void ScummEngine_c64::o_unlockSound() {
- int resid = fetchScriptByte();
- res.unlock(rtSound, resid);
- debug(0, "o_unlockSound (%d)", resid);
-}
-
-void ScummEngine_c64::o_loadActor() {
- debug(0, "o_loadActor (%d)", getVarOrDirectByte(PARAM_1));
-}
-
-void ScummEngine_c64::o_lockActor() {
- debug(0, "o_lockActor (%d)", fetchScriptByte());
-}
-
-void ScummEngine_c64::o_unlockActor() {
- debug(0, "o_unlockActor (%d)", fetchScriptByte());
-}
-
-void ScummEngine_c64::o_loadScript() {
- int resid = getVarOrDirectByte(PARAM_1);
- ensureResourceLoaded(rtScript, resid);
-}
-
-void ScummEngine_c64::o_lockScript() {
- int resid = fetchScriptByte();
- res.lock(rtScript, resid);
- debug(0, "o_lockScript (%d)", resid);
-}
-
-void ScummEngine_c64::o_unlockScript() {
- int resid = fetchScriptByte();
- res.unlock(rtScript, resid);
- debug(0, "o_unlockScript (%d)", resid);
-}
-
-void ScummEngine_c64::o_loadRoom() {
- int resid = getVarOrDirectByte(PARAM_1);
- ensureResourceLoaded(rtRoom, resid);
-}
-
-void ScummEngine_c64::o_loadRoomWithEgo() {
- Actor *a;
- int obj, room, x, y, dir;
-
- obj = fetchScriptByte();
- room = fetchScriptByte();
-
- a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
-
- a->putActor(0, 0, room);
- _egoPositioned = false;
-
- startScene(a->_room, a, obj);
-
- getObjectXYPos(obj, x, y, dir);
- a->putActor(x, y, _currentRoom);
- a->setDirection(dir + 180);
-
- camera._dest.x = camera._cur.x = a->_pos.x;
- setCameraAt(a->_pos.x, a->_pos.y);
- setCameraFollows(a);
-
- _fullRedraw = true;
-
- resetSentence();
-
- if (x >= 0 && y >= 0) {
- a->startWalkActor(x, y, -1);
- }
-}
-
-void ScummEngine_c64::o_lockRoom() {
- int resid = fetchScriptByte();
- res.lock(rtRoom, resid);
- debug(0, "o_lockRoom (%d)", resid);
-}
-
-void ScummEngine_c64::o_unlockRoom() {
- int resid = fetchScriptByte();
- res.unlock(rtRoom, resid);
- debug(0, "o_unlockRoom (%d)", resid);
-}
-
-void ScummEngine_c64::o_cursorCommand() {
- // TODO
- int state = 0;
-
- _currentMode = fetchScriptByte();
- switch (_currentMode) {
- case 0:
- state = 15;
- break;
- case 1:
- state = 31;
- break;
- case 2:
- break;
- case 3:
- state = 247;
- break;
- }
-
- setUserState(state);
- debug(0, "o_cursorCommand(%d)", _currentMode);
-}
-
-void ScummEngine_c64::o_lights() {
- int a;
-
- a = getVarOrDirectByte(PARAM_1);
- // Convert older light mode values into
- // equivalent values.of later games
- // 0 Darkness
- // 1 Flashlight
- // 2 Lighted area
- if (a == 2)
- VAR(VAR_CURRENT_LIGHTS) = 11;
- else if (a == 1)
- VAR(VAR_CURRENT_LIGHTS) = 4;
- else
- VAR(VAR_CURRENT_LIGHTS) = 0;
-
- _fullRedraw = true;
-}
-
-void ScummEngine_c64::o_animateActor() {
- int act = getVarOrDirectByte(PARAM_1);
- int anim = getVarOrDirectByte(PARAM_2);
- int unk = fetchScriptByte();
- debug(0,"o_animateActor: unk %d", unk);
-
- Actor *a = derefActor(act, "o_animateActor");
- a->animateActor(anim);
-}
-
-void ScummEngine_c64::o_getActorMoving() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o_getActorMoving");
- if (a->_moving)
- setResult(1);
- else
- setResult(2);
-}
-
-void ScummEngine_c64::o_putActorAtObject() {
- int obj, x, y;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o_putActorAtObject");
-
- obj = fetchScriptByte();
- if (whereIsObject(obj) != WIO_NOT_FOUND)
- getObjectXYPos(obj, x, y);
- else {
- x = 30;
- y = 60;
- }
-
- a->putActor(x, y, a->_room);
-}
-
-void ScummEngine_c64::o_badOpcode() {
- warning("Bad opcode 0x86 encountered");
-}
-
-void ScummEngine_c64::o_nop() {
-}
-
-void ScummEngine_c64::o_setActorBitVar() {
- byte flag = getVarOrDirectByte(PARAM_1);
- byte mask = getVarOrDirectByte(PARAM_2);
- byte mod = getVarOrDirectByte(PARAM_3);
-
- //if (mod)
- // _miscFlags[flag] |= mask;
- //else
- // _miscFlags[flag] &= ~mash;
-
- warning("STUB: o_setActorBitVar(%d, %d, %d)", flag, mask, mod);
-}
-
-void ScummEngine_c64::o_getActorBitVar() {
- getResultPos();
- byte flag = getVarOrDirectByte(PARAM_1);
- byte mask = getVarOrDirectByte(PARAM_2);
-
- //setResult((_miscFlags[flag] & mask) ? 1 : 0);
-
- setResult(0);
- warning("STUB: o_getActorBitVar(%d, %d)", flag, mask);
-}
-
-void ScummEngine_c64::o_print_c64() {
- _actorToPrintStrFor = fetchScriptByte();
- decodeParseString();
-}
-
-void ScummEngine_c64::o_printEgo_c64() {
- _actorToPrintStrFor = (byte)VAR(VAR_EGO);
- decodeParseString();
-}
-
-void ScummEngine_c64::o_doSentence() {
- byte var1 = fetchScriptByte();
- byte var2 = fetchScriptByte();
- byte var3 = fetchScriptByte();
- warning("STUB: o_doSentence(%d, %d, %d)", var1, var2, var3);
-}
-
-void ScummEngine_c64::o_unknown2() {
- byte var1 = fetchScriptByte();
- warning("STUB: o_unknown2(%d)", var1);
-}
-
-void ScummEngine_c64::o_unknown3() {
- byte var1 = fetchScriptByte();
- warning("STUB: o_unknown3(%d)", var1);
-}
-
-void ScummEngine_c64::o_getClosestObjActor() {
- int obj;
- int act;
- int dist;
-
- // This code can't detect any actors farther away than 255 units
- // (pixels in newer games, characters in older ones.) But this is
- // perfectly OK, as it is exactly how the original behaved.
-
- int closest_obj = 0xFF, closest_dist = 0xFF;
-
- getResultPos();
-
- act = getVarOrDirectByte(PARAM_1);
- obj = (_opcode & 0x40) ? 25 : 7;
-
- do {
- dist = getObjActToObjActDist(act, obj);
- if (dist < closest_dist) {
- closest_dist = dist;
- closest_obj = obj;
- }
- } while (--obj);
-
- setResult(closest_obj);
-}
-
-void ScummEngine_c64::o_beginOverride() {
- const int idx = vm.cutSceneStackPointer;
- assert(0 <= idx && idx < 5);
-
- vm.cutScenePtr[idx] = _scriptPointer - _scriptOrgPointer;
- vm.cutSceneScript[idx] = _currentScript;
-
- // Skip the jump instruction following the override instruction
- // (the jump is responsible for "skipping" cutscenes, and the reason
- // why we record the current script position in vm.cutScenePtr).
- fetchScriptByte();
- ScummEngine::fetchScriptWord();
-
- // This is based on disassembly
- VAR(VAR_OVERRIDE) = 0;
-}
-
-void ScummEngine_c64::o_isEqual() {
- int16 a, b;
- int var;
-
- var = fetchScriptByte();
- a = readVar(var);
- b = getVarOrDirectByte(PARAM_1);
-
- if (b == a)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-
-}
-
-void ScummEngine_c64::o_isGreater() {
- int16 a = getVar();
- int16 b = getVarOrDirectByte(PARAM_1);
- if (b > a)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_isGreaterEqual() {
- int16 a = getVar();
- int16 b = getVarOrDirectByte(PARAM_1);
- if (b >= a)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_isLess() {
- int16 a = getVar();
- int16 b = getVarOrDirectByte(PARAM_1);
- if (b < a)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_isLessEqual() {
- int16 a = getVar();
- int16 b = getVarOrDirectByte(PARAM_1);
-
- if (b <= a)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_isNotEqual() {
- int16 a = getVar();
- int16 b = getVarOrDirectByte(PARAM_1);
- if (b != a)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_notEqualZero() {
- int a = getVar();
- if (a != 0)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_equalZero() {
- int a = getVar();
- if (a == 0)
- ScummEngine::fetchScriptWord();
- else
- o_jumpRelative();
-}
-
-void ScummEngine_c64::o_jumpRelative() {
- int16 offset = (int16)ScummEngine::fetchScriptWord();
- _scriptPointer += offset;
-}
-
-
-
-#undef PARAM_1
-#undef PARAM_2
-#undef PARAM_3
-
-} // End of namespace Scumm
diff --git a/scumm/script_v100he.cpp b/scumm/script_v100he.cpp
deleted file mode 100644
index 790f65e021..0000000000
--- a/scumm/script_v100he.cpp
+++ /dev/null
@@ -1,2958 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/sprite_he.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v100he, x)
-
-void ScummEngine_v100he::setupOpcodes() {
- static const OpcodeEntryV100he opcodes[256] = {
- /* 00 */
- OPCODE(o100_actorOps),
- OPCODE(o6_add),
- OPCODE(o6_faceActor),
- OPCODE(o90_sortArray),
- /* 04 */
- OPCODE(o100_arrayOps),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- OPCODE(o6_breakHere),
- /* 08 */
- OPCODE(o6_delayFrames),
- OPCODE(o90_shl),
- OPCODE(o90_shr),
- OPCODE(o90_xor),
- /* 0C */
- OPCODE(o6_setCameraAt),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_loadRoom),
- OPCODE(o6_panCameraTo),
- /* 10 */
- OPCODE(o72_captureWizImage),
- OPCODE(o100_jumpToScript),
- OPCODE(o6_setClass),
- OPCODE(o60_closeFile),
- /* 14 */
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o72_setFilePath),
- OPCODE(o100_createSound),
- /* 18 */
- OPCODE(o6_cutscene),
- OPCODE(o6_pop),
- OPCODE(o72_traceStatus),
- OPCODE(o6_wordVarDec),
- /* 1C */
- OPCODE(o6_wordArrayDec),
- OPCODE(o72_deleteFile),
- OPCODE(o100_dim2dimArray),
- OPCODE(o100_dimArray),
- /* 20 */
- OPCODE(o6_div),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- OPCODE(o6_drawBox),
- /* 24 */
- OPCODE(o72_drawWizImage),
- OPCODE(o80_drawWizPolygon),
- OPCODE(o100_drawLine),
- OPCODE(o100_drawObject),
- /* 28 */
- OPCODE(o6_dup),
- OPCODE(o90_dup_n),
- OPCODE(o6_endCutscene),
- OPCODE(o6_stopObjectCode),
- /* 2C */
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_eq),
- OPCODE(o100_floodFill),
- OPCODE(o6_freezeUnfreeze),
- /* 30 */
- OPCODE(o6_ge),
- OPCODE(o6_getDateTime),
- OPCODE(o100_setSpriteGroupInfo),
- OPCODE(o6_gt),
- /* 34 */
- OPCODE(o100_resourceRoutines),
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o100_wizImageOps),
- /* 38 */
- OPCODE(o72_isAnyOf),
- OPCODE(o6_wordVarInc),
- OPCODE(o6_wordArrayInc),
- OPCODE(o6_jump),
- /* 3C */
- OPCODE(o90_kernelSetFunctions),
- OPCODE(o6_land),
- OPCODE(o6_le),
- OPCODE(o60_localizeArrayToScript),
- /* 40 */
- OPCODE(o6_wordArrayRead),
- OPCODE(o6_wordArrayIndexedRead),
- OPCODE(o6_lor),
- OPCODE(o6_lt),
- /* 44 */
- OPCODE(o90_mod),
- OPCODE(o6_mul),
- OPCODE(o6_neq),
- OPCODE(o100_dim2dim2Array),
- /* 48 */
- OPCODE(o6_setObjectName),
- OPCODE(o100_redim2dimArray),
- OPCODE(o6_not),
- OPCODE(o6_invalid),
- /* 4C */
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o72_resetCutscene),
- OPCODE(o6_setOwner),
- /* 50 */
- OPCODE(o100_paletteOps),
- OPCODE(o70_pickupObject),
- OPCODE(o70_polygonOps),
- OPCODE(o6_pop),
- /* 54 */
- OPCODE(o6_printDebug),
- OPCODE(o72_printWizImage),
- OPCODE(o6_printLine),
- OPCODE(o6_printSystem),
- /* 58 */
- OPCODE(o6_printText),
- OPCODE(o100_jumpToScriptUnk),
- OPCODE(o100_startScriptUnk),
- OPCODE(o6_pseudoRoom),
- /* 5C */
- OPCODE(o6_pushByte),
- OPCODE(o72_pushDWord),
- OPCODE(o72_getScriptString),
- OPCODE(o6_pushWord),
- /* 60 */
- OPCODE(o6_pushWordVar),
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_putActorAtXY),
- OPCODE(o6_invalid),
- /* 64 */
- OPCODE(o100_redimArray),
- OPCODE(o72_rename),
- OPCODE(o6_stopObjectCode),
- OPCODE(o80_localizeArrayToRoom),
- /* 68 */
- OPCODE(o100_roomOps),
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o72_talkActor),
- /* 6C */
- OPCODE(o72_talkEgo),
- OPCODE(o6_invalid),
- OPCODE(o70_seekFilePos),
- OPCODE(o6_setBoxFlags),
- /* 70 */
- OPCODE(o6_invalid),
- OPCODE(o6_setBoxSet),
- OPCODE(o72_setWindowCaption),
- OPCODE(o6_shuffle),
- /* 74 */
- OPCODE(o6_delay),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_delaySeconds),
- OPCODE(o100_startSound),
- /* 78 */
- OPCODE(o80_sourceDebug),
- OPCODE(o100_setSpriteInfo),
- OPCODE(o6_stampObject),
- OPCODE(o72_startObject),
- /* 7C */
- OPCODE(o100_startScript),
- OPCODE(o6_startScriptQuick),
- OPCODE(o80_setState),
- OPCODE(o6_stopObjectScript),
- /* 80 */
- OPCODE(o6_stopScript),
- OPCODE(o6_stopSentence),
- OPCODE(o6_stopSound),
- OPCODE(o6_stopTalking),
- /* 84 */
- OPCODE(o6_writeWordVar),
- OPCODE(o6_wordArrayWrite),
- OPCODE(o6_wordArrayIndexedWrite),
- OPCODE(o6_sub),
- /* 88 */
- OPCODE(o100_systemOps),
- OPCODE(o6_invalid),
- OPCODE(o72_setTimer),
- OPCODE(o100_cursorCommand),
- /* 8C */
- OPCODE(o100_videoOps),
- OPCODE(o100_wait),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- /* 90 */
- OPCODE(o100_writeFile),
- OPCODE(o72_writeINI),
- OPCODE(o80_writeConfigFile),
- OPCODE(o6_abs),
- /* 94 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getObjectOldDir),
- /* 98 */
- OPCODE(o6_getActorMoving),
- OPCODE(o90_getActorData),
- OPCODE(o6_getActorRoom),
- OPCODE(o6_getActorScaleX),
- /* 9C */
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_getActorWidth),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- /* A0 */
- OPCODE(o90_atan2),
- OPCODE(o90_getSegmentAngle),
- OPCODE(o90_getActorAnimProgress),
- OPCODE(o90_getDistanceBetweenPoints),
- /* A4 */
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_invalid),
- OPCODE(o90_cond),
- OPCODE(o90_cos),
- /* A8 */
- OPCODE(o6_invalid),
- OPCODE(o80_getFileSize),
- OPCODE(o6_getActorFromXY),
- OPCODE(o72_findAllObjects),
- /* AC */
- OPCODE(o90_findAllObjectsWithClassOf),
- OPCODE(o6_invalid),
- OPCODE(o6_findInventory),
- OPCODE(o72_findObject),
- /* B0 */
- OPCODE(o72_findObjectWithClassOf),
- OPCODE(o70_polygonHit),
- OPCODE(o90_getLinesIntersectionPoint),
- OPCODE(o90_fontUnk),
- /* B4 */
- OPCODE(o72_getNumFreeArrays),
- OPCODE(o72_getArrayDimSize),
- OPCODE(o100_isResourceLoaded),
- OPCODE(o100_getResourceSize),
- /* B8 */
- OPCODE(o100_getSpriteGroupInfo),
- OPCODE(o6_invalid),
- OPCODE(o100_getWizData),
- OPCODE(o6_isActorInBox),
- /* BC */
- OPCODE(o6_isAnyOf),
- OPCODE(o6_getInventoryCount),
- OPCODE(o90_kernelGetFunctions),
- OPCODE(o90_max),
- /* C0 */
- OPCODE(o90_min),
- OPCODE(o72_getObjectImageX),
- OPCODE(o72_getObjectImageY),
- OPCODE(o6_isRoomScriptRunning),
- /* C4 */
- OPCODE(o90_getObjectData),
- OPCODE(o72_openFile),
- OPCODE(o90_getPolygonOverlap),
- OPCODE(o6_getOwner),
- /* C8 */
- OPCODE(o100_getPaletteData),
- OPCODE(o6_pickOneOf),
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o80_pickVarRandom),
- /* CC */
- OPCODE(o72_getPixel),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* D0 */
- OPCODE(o6_getRandomNumber),
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o100_readFile),
- /* D4 */
- OPCODE(o72_readINI),
- OPCODE(o80_readConfigFile),
- OPCODE(o6_isScriptRunning),
- OPCODE(o90_sin),
- /* D8 */
- OPCODE(o72_getSoundPosition),
- OPCODE(o6_isSoundRunning),
- OPCODE(o80_getSoundVar),
- OPCODE(o100_getSpriteInfo),
- /* DC */
- OPCODE(o90_sqrt),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- OPCODE(o6_getState),
- /* E0 */
- OPCODE(o70_compareString),
- OPCODE(o70_copyString),
- OPCODE(o70_appendString),
- OPCODE(o70_concatString),
- /* E4 */
- OPCODE(o70_getStringLen),
- OPCODE(o70_getStringLenForWidth),
- OPCODE(o80_stringToInt),
- OPCODE(o70_getCharIndexInString),
- /* E8 */
- OPCODE(o70_getStringWidth),
- OPCODE(o60_readFilePos),
- OPCODE(o72_getTimer),
- OPCODE(o6_getVerbEntrypoint),
- /* EC */
- OPCODE(o100_getVideoData),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F0 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F4 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* FC */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV100he = opcodes;
-}
-
-void ScummEngine_v100he::executeOpcode(byte i) {
- OpcodeProcV100he op = _opcodesV100he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v100he::getOpcodeDesc(byte i) {
- return _opcodesV100he[i].desc;
-}
-
-void ScummEngine_v100he::o100_actorOps() {
- Actor *a;
- int i, j, k;
- int args[32];
- byte string[256];
-
- byte subOp = fetchScriptByte();
- if (subOp == 129) {
- _curActor = pop();
- return;
- }
-
- a = derefActorSafe(_curActor, "o100_actorOps");
- if (!a)
- return;
-
- switch (subOp) {
- case 0:
- // freddicove Ru Updated
- // FIXME: check stack parameters
- debug(0,"o100_actorOps: case 0 UNHANDLED");
- break;
- case 3:
- pop();
- pop();
- pop();
- break;
- case 4: // SO_ANIMATION_SPEED
- a->setAnimSpeed(pop());
- break;
- case 6:
- j = pop();
- i = pop();
- a->putActor(i, j, a->_room);
- break;
- case 8:
- a->_drawToBackBuf = false;
- a->_needRedraw = true;
- a->_needBgReset = true;
- break;
- case 9:
- a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
- break;
- case 14:
- a->_charset = pop();
- break;
- case 18:
- a->_clipOverride.bottom = pop();
- a->_clipOverride.right = pop();
- a->_clipOverride.top = pop();
- a->_clipOverride.left = pop();
- break;
- case 22:
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; ++i) {
- a->setUserCondition(args[i] & 0x7F, args[i] & 0x80);
- }
- break;
- case 25: // SO_COSTUME
- a->setActorCostume(pop());
- break;
- case 27: // SO_DEFAULT
- a->initActor(0);
- break;
- case 32:
- i = pop();
- debug(0,"o100_actorOps: case 32 (%d)", i);
- break;
- case 52: // SO_ACTOR_NAME
- copyScriptString(string, sizeof(string));
- loadPtrToResource(rtActorName, a->_number, string);
- break;
- case 53: // SO_ACTOR_NEW
- a->initActor(2);
- break;
- case 57: // SO_PALETTE
- j = pop();
- i = pop();
- checkRange(255, 0, i, "o100_actorOps: Illegal palette slot %d");
- a->remapActorPaletteColor(i, j);
- a->_needRedraw = true;
- break;
- case 59:
- // HE games use reverse order of layering, so we adjust
- a->_layer = -pop();
- a->_needRedraw = true;
- break;
- case 63:
- a->_hePaletteNum = pop();
- a->_needRedraw = true;
- break;
- case 65: // SO_SCALE
- i = pop();
- a->setScale(i, i);
- break;
- case 70: // SO_SHADOW
- a->_heXmapNum = pop();
- a->_needRedraw = true;
- break;
- case 74: // SO_STEP_DIST
- j = pop();
- i = pop();
- a->setActorWalkSpeed(i, j);
- break;
- case 78:
- {
- copyScriptString(string, sizeof(string));
- int slot = pop();
-
- int len = resStrLen(string) + 1;
- memcpy(a->_heTalkQueue[slot].sentence, string, len);
-
- a->_heTalkQueue[slot].posX = a->_talkPosX;
- a->_heTalkQueue[slot].posY = a->_talkPosY;
- a->_heTalkQueue[slot].color = a->_talkColor;
- }
- break;
- case 83: // SO_ACTOR_VARIABLE
- i = pop();
- a->setAnimVar(pop(), i);
- break;
- case 87: // SO_ALWAYS_ZCLIP
- a->_forceClip = pop();
- break;
- case 89: // SO_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 128:
- _actorClipOverride.bottom = pop();
- _actorClipOverride.right = pop();
- _actorClipOverride.top = pop();
- _actorClipOverride.left = pop();
- break;
- case 130: // SO_SOUND
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; i++)
- a->_sound[i] = args[i];
- break;
- case 131: // SO_ACTOR_WIDTH
- a->_width = pop();
- break;
- case 132: // SO_ANIMATION_DEFAULT
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 133: // SO_ELEVATION
- a->setElevation(pop());
- break;
- case 134: // SO_FOLLOW_BOXES
- a->_ignoreBoxes = 0;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 135: // SO_IGNORE_BOXES
- a->_ignoreBoxes = 1;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 136: // SO_ACTOR_IGNORE_TURNS_OFF
- a->_ignoreTurns = false;
- break;
- case 137: // SO_ACTOR_IGNORE_TURNS_ON
- a->_ignoreTurns = true;
- break;
- case 138: // SO_INIT_ANIMATION
- a->_initFrame = pop();
- break;
- case 139: // SO_STAND_ANIMATION
- a->_standFrame = pop();
- break;
- case 140: // SO_TALK_ANIMATION
- a->_talkStopFrame = pop();
- a->_talkStartFrame = pop();
- break;
- case 141: // SO_TALK_COLOR
- a->_talkColor = pop();
- break;
- case 142:
- k = pop();
- if (k == 0)
- k = _rnd.getRandomNumberRng(1, 10);
- a->_heNoTalkAnimation = 1;
- a->setTalkCondition(k);
- break;
- case 143: // SO_TEXT_OFFSET
- a->_talkPosY = pop();
- a->_talkPosX = pop();
- break;
- case 144: // SO_WALK_ANIMATION
- a->_walkFrame = pop();
- break;
- default:
- error("o100_actorOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_arrayOps() {
- ArrayHeader *ah;
- byte string[1024];
- int dim1end, dim1start, dim2end, dim2start;
- int id, len, b, c, list[128];
- int offs, tmp, tmp2;
- uint tmp3;
-
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord();
- debug(9,"o100_arrayOps: array %d case %d", array, subOp);
-
- switch (subOp) {
- case 35:
- decodeScriptString(string);
- len = resStrLen(string);
- ah = defineArray(array, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- break;
- case 77: // SO_ASSIGN_STRING
- copyScriptString(string, sizeof(string));
- len = resStrLen(string);
- ah = defineArray(array, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- break;
-
- case 128: // SO_ASSIGN_2DIM_LIST
- len = getStackList(list, ARRAYSIZE(list));
- id = readVar(array);
- if (id == 0)
- error("Must DIM a two dimensional array before assigning");
- c = pop();
- while (--len >= 0) {
- writeArray(array, c, len, list[len]);
- }
- break;
- case 129: // SO_ASSIGN_INT_LIST
- b = pop();
- c = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, 0, 0, 0, b + c - 1);
- }
- while (c--) {
- writeArray(array, 0, b + c, pop());
- }
- break;
- case 130:
- len = getStackList(list, ARRAYSIZE(list));
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
- }
- tmp2 = 0;
- while (dim2start <= dim2end) {
- tmp = dim1start;
- while (tmp <= dim1end) {
- writeArray(array, dim2start, tmp, list[tmp2++]);
- if (tmp2 == len)
- tmp2 = 0;
- tmp++;
- }
- dim2start++;
- }
- break;
- case 131:
- {
- int a2_dim1end = pop();
- int a2_dim1start = pop();
- int a2_dim2end = pop();
- int a2_dim2start = pop();
- int array2 = fetchScriptWord();
- int a1_dim1end = pop();
- int a1_dim1start = pop();
- int a1_dim2end = pop();
- int a1_dim2start = pop();
- if (a1_dim1end - a1_dim1start != a2_dim1end - a2_dim1start || a2_dim2end - a2_dim2start != a1_dim2end - a1_dim2start) {
- error("Source and dest ranges size are mismatched");
- }
- copyArray(array, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
- }
- break;
- case 133:
- b = pop();
- c = pop();
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
- }
-
- offs = (b >= c) ? 1 : -1;
- tmp2 = c;
- tmp3 = c - b + 1;
- while (dim2start <= dim2end) {
- tmp = dim1start;
- while (tmp <= dim1end) {
- writeArray(array, dim2start, tmp, tmp2);
- if (--tmp3 == 0) {
- tmp2 = c;
- tmp3 = c - b + 1;
- } else {
- tmp2 += offs;
- }
- tmp++;
- }
- dim2start++;
- }
- break;
- default:
- error("o100_arrayOps: default case %d (array %d)", subOp, array);
- }
-}
-
-void ScummEngine_v100he::o100_jumpToScript() {
- int args[25];
- int script;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = fetchScriptByte();
- stopObjectCode();
- runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args);
-}
-
-void ScummEngine_v100he::o100_createSound() {
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- _heSndResId = pop();
- break;
- case 53:
- createSound(_heSndResId, -1);
- break;
- case 92:
- // dummy case
- break;
- case 128:
- createSound(_heSndResId, pop());
- break;
- default:
- error("o100_createSound: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_dim2dimArray() {
- int data, dim1end, dim2end;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 41: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 42: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 43:
- data = kDwordArray;
- break;
- case 44: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 45: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 77: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- default:
- error("o100_dim2dimArray: default case %d", subOp);
- }
-
- dim1end = pop();
- dim2end = pop();
- defineArray(fetchScriptWord(), data, 0, dim2end, 0, dim1end);
-}
-
-void ScummEngine_v100he::o100_dimArray() {
- int data;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 41: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 42: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 43:
- data = kDwordArray;
- break;
- case 44: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 45: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 77: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- case 135: // SO_UNDIM_ARRAY
- nukeArray(fetchScriptWord());
- return;
- default:
- error("o100_dimArray: default case %d", subOp);
- }
-
- defineArray(fetchScriptWord(), data, 0, 0, 0, pop());
-}
-
-void ScummEngine_v100he::o100_drawLine() {
- int id, unk1, unk2, x, x1, y1;
-
- unk2 = pop();
- id = pop();
- unk1 = pop();
- x = pop();
- y1 = pop();
- x1 = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 1:
- drawLine(x1, y1, x, unk1, unk2, 2, id);
- break;
- case 20:
- drawLine(x1, y1, x, unk1, unk2, 1, id);
- break;
- case 40:
- drawLine(x1, y1, x, unk1, unk2, 3, id);
- break;
- default:
- error("o100_drawLine: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_drawObject() {
- int state, y, x;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 6:
- state = 1;
- y = pop();
- x = pop();
- break;
- case 7:
- state = pop();
- y = pop();
- x = pop();
- break;
- case 40:
- state = pop();
- if (state == 0)
- state = 1;
- y = x = -100;
- break;
- default:
- error("o100_drawObject: default case %d", subOp);
- }
-
- int object = pop();
- int objnum = getObjectIndex(object);
- if (objnum == -1)
- return;
-
- if (y != -100 && x != -100) {
- _objs[objnum].x_pos = x * 8;
- _objs[objnum].y_pos = y * 8;
- }
-
- if (state != -1) {
- addObjectToDrawQue(objnum);
- putState(object, state);
- }
-}
-
-void ScummEngine_v100he::o100_floodFill() {
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- memset(&_floodFillParams, 0, sizeof(_floodFillParams));
- _floodFillParams.box.left = 0;
- _floodFillParams.box.top = 0;
- _floodFillParams.box.right = 639;
- _floodFillParams.box.bottom = 479;
- break;
- case 6:
- _floodFillParams.y = pop();
- _floodFillParams.x = pop();
- break;
- case 18:
- _floodFillParams.box.bottom = pop();
- _floodFillParams.box.right = pop();
- _floodFillParams.box.top = pop();
- _floodFillParams.box.left = pop();
- break;
- case 20:
- _floodFillParams.flags = pop();
- break;
- case 67:
- pop();
- break;
- case 92:
- floodFill(&_floodFillParams, this);
- break;
- default:
- error("o100_floodFill: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_setSpriteGroupInfo() {
- byte string[260];
- int type, value1, value2, value3, value4;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- _curSpriteGroupId = pop();
- break;
- case 6:
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupPosition(_curSpriteGroupId, value1, value2);
- break;
- case 18:
- value4 = pop();
- value3 = pop();
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupBounds(_curSpriteGroupId, value1, value2, value3, value4);
- break;
- case 38:
- type = pop() - 1;
- switch (type) {
- case 0:
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->moveGroupMembers(_curSpriteGroupId, value1, value2);
- break;
- case 1:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersPriority(_curSpriteGroupId, value1);
- break;
- case 2:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersGroup(_curSpriteGroupId, value1);
- break;
- case 3:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersUpdateType(_curSpriteGroupId, value1);
- break;
- case 4:
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersResetSprite(_curSpriteGroupId);
- break;
- case 5:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersAnimationSpeed(_curSpriteGroupId, value1);
- break;
- case 6:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersAutoAnimFlag(_curSpriteGroupId, value1);
- break;
- case 7:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersShadow(_curSpriteGroupId, value1);
- break;
- default:
- error("o100_setSpriteGroupInfo subOp 38: Unknown case %d", subOp);
- }
- break;
- case 40:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupImage(_curSpriteGroupId, value1);
- break;
- case 49:
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->moveGroup(_curSpriteGroupId, value1, value2);
- break;
- case 52:
- copyScriptString(string, sizeof(string));
- break;
- case 53:
- if (!_curSpriteGroupId)
- break;
-
- _sprite->resetGroup(_curSpriteGroupId);
- break;
- case 54:
- // dummy case
- pop();
- pop();
- break;
- case 59:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupPriority(_curSpriteGroupId, value1);
- break;
- case 60:
- type = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- switch (type) {
- case 0:
- _sprite->setGroupXMul(_curSpriteGroupId, value1);
- break;
- case 1:
- _sprite->setGroupXDiv(_curSpriteGroupId, value1);
- break;
- case 2:
- _sprite->setGroupYMul(_curSpriteGroupId, value1);
- break;
- case 3:
- _sprite->setGroupYDiv(_curSpriteGroupId, value1);
- break;
- default:
- error("o100_setSpriteGroupInfo subOp 60: Unknown case %d", subOp);
- }
- break;
- case 89:
- if (!_curSpriteGroupId)
- break;
-
- _sprite->resetGroupBounds(_curSpriteGroupId);
- break;
- default:
- error("o100_setSpriteGroupInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_resourceRoutines() {
- int objidx, room;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 14:
- _heResType = rtCharset;
- _heResId = pop();
- break;
- case 25:
- _heResType = rtCostume;
- _heResId = pop();
- break;
- case 34:
- _heResType = rtFlObject;
- _heResId = pop();
- break;
- case 40:
- _heResType = rtImage;
- _heResId = pop();
- break;
- case 47:
- if (_heResType == rtFlObject) {
- room = getObjectRoom(_heResId);
- loadFlObject(_heResId, room);
- } else if (_heResType == rtCharset) {
- loadCharset(_heResId);
- } else {
- ensureResourceLoaded(_heResType, _heResId);
- }
- break;
- case 62:
- _heResType = rtRoom;
- _heResId = pop();
- break;
- case 66:
- _heResType = rtScript;
- _heResId = pop();
- break;
- case 72:
- _heResType = rtSound;
- _heResId = pop();
- break;
- case 128:
- break;
- case 132:
- if (_heResType == rtScript && _heResId >= _numGlobalScripts)
- break;
-
- if (_heResType == rtFlObject) {
- objidx = getObjectIndex(_heResId);
- if (objidx == -1)
- break;
- res.lock(rtFlObject, _objs[objidx].fl_object_index);
- } else {
- res.lock(_heResType, _heResId);
- }
- break;
- case 133:
- if (_heResType == rtCharset)
- nukeCharset(_heResId);
- else
- res.nukeResource(_heResType, _heResId);
- break;
- case 134:
- case 135:
- // Heap related
- break;
- case 136:
- if (_heResType == rtScript && _heResId >= _numGlobalScripts)
- break;
-
- //queueLoadResource(_heResType, _heResId);
- break;
- case 137:
- if (_heResType == rtScript && _heResId >= _numGlobalScripts)
- break;
-
- if (_heResType == rtFlObject) {
- objidx = getObjectIndex(_heResId);
- if (objidx == -1)
- break;
- res.unlock(rtFlObject, _objs[objidx].fl_object_index);
- } else {
- res.unlock(_heResType, _heResId);
- }
- break;
- default:
- error("o100_resourceRoutines: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_wizImageOps() {
- int a, b;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- _wizParams.img.resNum = pop();
- _wizParams.processMode = 0;
- _wizParams.processFlags = 0;
- _wizParams.remapNum = 0;
- _wizParams.img.flags = 0;
- _wizParams.field_184 = 0;
- _wizParams.field_180 = 0;
- _wizParams.spriteId = 0;
- _wizParams.spriteGroup = 0;
- break;
- case 2:
- _wizParams.processFlags |= kWPFRotate;
- _wizParams.angle = pop();
- break;
- case 6:
- case 132:
- _wizParams.processFlags |= kWPFSetPos;
- _wizParams.img.y1 = pop();
- _wizParams.img.x1 = pop();
- break;
- case 7:
- _wizParams.processFlags |= kWPFMaskImg;
- _wizParams.sourceImage = pop();
- break;
- case 11:
- _wizParams.processFlags |= kWPFClipBox | 0x100;
- _wizParams.processMode = 2;
- _wizParams.box.bottom = pop();
- _wizParams.box.right = pop();
- _wizParams.box.top = pop();
- _wizParams.box.left = pop();
- _wizParams.compType = pop();
- break;
- case 18:
- _wizParams.processFlags |= kWPFClipBox;
- _wizParams.box.bottom = pop();
- _wizParams.box.right = pop();
- _wizParams.box.top = pop();
- _wizParams.box.left = pop();
- break;
- case 21:
- b = pop();
- a = pop();
- _wizParams.processFlags |= kWPFRemapPalette;
- _wizParams.processMode = 6;
- if (_wizParams.remapNum == 0) {
- memset(_wizParams.remapIndex, 0, sizeof(_wizParams.remapIndex));
- } else {
- assert(_wizParams.remapNum < ARRAYSIZE(_wizParams.remapIndex));
- _wizParams.remapIndex[_wizParams.remapNum] = a;
- _wizParams.remapColor[a] = b;
- ++_wizParams.remapNum;
- }
- break;
- case 29:
- _wizParams.processMode = 1;
- break;
- case 36:
- _wizParams.box.bottom = pop();
- _wizParams.box.right = pop();
- _wizParams.box.top = pop();
- _wizParams.box.left = pop();
- break;
- case 37:
- // Dummy case
- pop();
- break;
- case 39:
- _wizParams.processFlags |= kWPFUseDefImgHeight;
- _wizParams.resDefImgH = pop();
- break;
- case 47:
- _wizParams.processFlags |= kWPFUseFile;
- _wizParams.processMode = 3;
- copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
- break;
- case 53:
- _wizParams.processMode = 8;
- break;
- case 54:
- _wizParams.processFlags |= 0x100000;
- _wizParams.field_180 = pop();
- _wizParams.field_184 = pop();
- break;
- case 55:
- _wizParams.img.flags = pop();
- _wizParams.img.state = pop();
- _wizParams.img.y1 = pop();
- _wizParams.img.x1 = pop();
- _wizParams.spriteId = 0;
- _wizParams.spriteGroup = 0;
- _wizParams.img.resNum = pop();
- _wiz->displayWizImage(&_wizParams.img);
- break;
- case 57:
- _wizParams.processFlags |= kWPFPaletteNum;
- _wizParams.img.palette = pop();
- break;
- case 58:
- _wizParams.processFlags |= 0x1000 | 0x100 | 0x2;
- _wizParams.processMode = 7;
- _wizParams.field_168 = pop();
- _wizParams.field_164 = pop();
- _wizParams.compType = pop();
- break;
- case 64:
- _wizParams.processFlags |= kWPFUseFile;
- _wizParams.processMode = 4;
- copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
- _wizParams.fileWriteMode = pop();
- break;
- case 65:
- _wizParams.processFlags |= kWPFScaled;
- _wizParams.scale = pop();
- break;
- case 67:
- _wizParams.processFlags |= kWPFNewFlags;
- _wizParams.img.flags |= pop();
- break;
- case 68:
- _wizParams.processFlags |= kWPFNewFlags | kWPFSetPos | 2;
- _wizParams.img.flags |= kWIFIsPolygon;
- _wizParams.field_164 = _wizParams.img.y1 = _wizParams.img.x1 = pop();
- break;
- case 70:
- _wizParams.processFlags |= kWPFShadow;
- _wizParams.img.shadow = pop();
- break;
- case 73:
- _wizParams.processFlags |= kWPFNewState;
- _wizParams.img.state = pop();
- break;
- case 84:
- _wizParams.processFlags |= kWPFUseDefImgWidth;
- _wizParams.resDefImgW = pop();
- break;
- case 92:
- if (_wizParams.img.resNum)
- _wiz->processWizImage(&_wizParams);
- break;
- case 128:
- _wizParams.field_239D = pop();
- _wizParams.field_2399 = pop();
- _wizParams.field_23A5 = pop();
- _wizParams.field_23A1 = pop();
- copyScriptString(_wizParams.string2, sizeof(_wizParams.string2));
- _wizParams.processMode = 15;
- break;
- case 129:
- _wizParams.processMode = 14;
- break;
- case 130:
- _wizParams.processMode = 16;
- _wizParams.field_23AD = pop();
- _wizParams.field_23A9 = pop();
- copyScriptString(_wizParams.string1, sizeof(_wizParams.string1));
- break;
- case 131:
- _wizParams.processMode = 13;
- break;
- case 133:
- _wizParams.processMode = 17;
- _wizParams.field_23CD = pop();
- _wizParams.field_23C9 = pop();
- _wizParams.field_23C5 = pop();
- _wizParams.field_23C1 = pop();
- _wizParams.field_23BD = pop();
- _wizParams.field_23B9 = pop();
- _wizParams.field_23B5 = pop();
- _wizParams.field_23B1 = pop();
- break;
- case 134:
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 12;
- _wizParams.fillColor = pop();
- _wizParams.box2.top = _wizParams.box2.bottom = pop();
- _wizParams.box2.left = _wizParams.box2.right = pop();
- break;
- case 135:
- _wizParams.processFlags |= kWPFDstResNum;
- _wizParams.dstResNum = pop();
- break;
- case 136:
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 10;
- _wizParams.fillColor = pop();
- _wizParams.box2.bottom = pop();
- _wizParams.box2.right = pop();
- _wizParams.box2.top = pop();
- _wizParams.box2.left = pop();
- break;
- case 137:
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 11;
- _wizParams.fillColor = pop();
- _wizParams.box2.top = _wizParams.box2.bottom = pop();
- _wizParams.box2.left = _wizParams.box2.right = pop();
- break;
- case 138:
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 9;
- _wizParams.fillColor = pop();
- _wizParams.box2.bottom = pop();
- _wizParams.box2.right = pop();
- _wizParams.box2.top = pop();
- _wizParams.box2.left = pop();
- break;
- default:
- error("o100_wizImageOps: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_dim2dim2Array() {
- int data, dim1start, dim1end, dim2start, dim2end;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 41: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 42: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 43:
- data = kDwordArray;
- break;
- case 44: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 45: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 77: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- default:
- error("o100_dim2dim2Array: default case %d", subOp);
- }
-
- if (pop() == 2) {
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- } else {
- dim2end = pop();
- dim2start = pop();
- dim1end = pop();
- dim1start = pop();
- }
-
- defineArray(fetchScriptWord(), data, dim2start, dim2end, dim1start, dim1end);
-}
-
-void ScummEngine_v100he::o100_redim2dimArray() {
- int a, b, c, d;
- d = pop();
- c = pop();
- b = pop();
- a = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 42:
- redimArray(fetchScriptWord(), a, b, c, d, kIntArray);
- break;
- case 43:
- redimArray(fetchScriptWord(), a, b, c, d, kDwordArray);
- break;
- case 45:
- redimArray(fetchScriptWord(), a, b, c, d, kByteArray);
- break;
- default:
- error("o100_redim2dimArray: default type %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_paletteOps() {
- int a, b, c, d, e;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- _hePaletteNum = pop();
- break;
- case 20:
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- for (; a <= b; ++a) {
- setHEPaletteColor(_hePaletteNum, a, c, d, e);
- }
- }
- break;
- case 25:
- a = pop();
- if (_hePaletteNum != 0) {
- setHEPaletteFromCostume(_hePaletteNum, a);
- }
- break;
- case 40:
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- setHEPaletteFromImage(_hePaletteNum, a, b);
- }
- break;
- case 53:
- if (_hePaletteNum != 0) {
- restoreHEPalette(_hePaletteNum);
- }
- break;
- case 57:
- a = pop();
- if (_hePaletteNum != 0) {
- copyHEPalette(_hePaletteNum, a);
- }
- break;
- case 63:
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- setHEPaletteFromRoom(_hePaletteNum, a, b);
- }
- break;
- case 81:
- c = pop();
- b = pop();
- a = pop();
- if (_hePaletteNum) {
- for (; a <= b; ++a) {
- copyHEPaletteColor(_hePaletteNum, a, c);
- }
- }
- break;
- case 92:
- _hePaletteNum = 0;
- break;
- default:
- error("o100_paletteOps: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_jumpToScriptUnk() {
- int args[25];
- int script, cycle;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- cycle = pop();
- script = pop();
- flags = fetchScriptByte();
- stopObjectCode();
- runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args, cycle);
-}
-
-void ScummEngine_v100he::o100_startScriptUnk() {
- int args[25];
- int script, cycle;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- cycle = pop();
- script = pop();
- flags = fetchScriptByte();
- runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args, cycle);
-}
-
-void ScummEngine_v100he::o100_redimArray() {
- int newX, newY;
- newY = pop();
- newX = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 42:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kIntArray);
- break;
- case 43:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kDwordArray);
- break;
- case 45:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kByteArray);
- break;
- default:
- error("o100_redimArray: default type %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_roomOps() {
- int a, b, c, d, e;
- byte filename[100];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 63: // SO_ROOM_PALETTE
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setPalColor(d, a, b, c);
- break;
-
- case 129:
- b = pop();
- a = pop();
- swapObjects(a, b);
- break;
-
- case 130:
- a = pop();
- b = pop();
- copyPalColor(a, b);
- break;
-
- case 131: // SO_ROOM_FADE
- // Defaults to 1 but doesn't use fade effects
- a = pop();
- break;
-
- case 132: // SO_ROOM_INTENSITY
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, a, a, b, c);
- break;
-
- case 133: // SO_RGB_ROOM_INTENSITY
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, b, c, d, e);
- break;
-
- case 134: // SO_ROOM_NEW_PALETTE
- a = pop();
- setPalette(a);
- break;
-
- case 135:
- b = pop();
- a = pop();
- setRoomPalette(a, b);
- break;
-
- case 136: // SO_ROOM_SAVEGAME
- _saveTemporaryState = true;
- _saveLoadSlot = pop();
- _saveLoadFlag = pop();
- break;
-
- case 137:
- copyScriptString(filename, sizeof(filename));
- _saveLoadFlag = pop();
- _saveLoadSlot = 1;
- _saveTemporaryState = true;
- break;
-
- case 138: // SO_ROOM_SCREEN
- b = pop();
- a = pop();
- initScreens(a, _screenHeight);
- break;
-
- case 139: // SO_ROOM_SCROLL
- b = pop();
- a = pop();
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
-
- default:
- error("o100_roomOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_startSound() {
- byte filename[260];
- int var, value;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 6:
- _heSndFlags |= 16;
- _heSndOffset = pop();
- break;
- case 47:
- copyScriptString(filename, sizeof(filename));
- _heSndSoundId = pop();
- if (_heSndSoundId)
- debug(0, "Load sound %d from file %s\n", _heSndSoundId, filename);
- break;
- case 55:
- _heSndFlags |= 8;
- break;
- case 83:
- value = pop();
- var = pop();
- _heSndSoundId = pop();
- _sound->setSoundVar(_heSndSoundId, var, value);
- break;
- case 92:
- _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags);
- break;
- case 128:
- _heSndFlags |= 2;
- break;
- case 129:
- _heSndChannel = pop();
- break;
- case 130:
- _heSndFlags |= 64;
- pop();
- break;
- case 131:
- _heSndFlags |= 1;
- break;
- case 132: // Music
- case 134: // Sound
- _heSndSoundId = pop();
- _heSndOffset = 0;
- _heSndSoundFreq = 11025;
- _heSndChannel = VAR(VAR_SOUND_CHANNEL);
- _heSndFlags = 0;
- break;
- case 133:
- _heSndFlags |= 128;
- pop();
- break;
- case 135:
- _heSndFlags |= 4;
- break;
- case 136:
- _heSndFlags |= 32;
- pop();
- break;
- default:
- error("o100_startSound invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_setSpriteInfo() {
- int args[16];
- int spriteId, n;
- int32 tmp[2];
- byte string[80];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- _curMaxSpriteId = pop();
- _curSpriteId = pop();
-
- if (_curSpriteId > _curMaxSpriteId)
- SWAP(_curSpriteId, _curMaxSpriteId);
- break;
- case 2:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteAngle(spriteId, args[0]);
- break;
- case 3:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteFlagAutoAnim(spriteId, args[0]);
- break;
- case 4:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteAnimSpeed(spriteId, args[0]);
- break;
- case 6:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpritePosition(spriteId, args[0], args[1]);
- break;
- case 7:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteSourceImage(spriteId, args[0]);
- break;
- case 16:
- n = getStackList(args, ARRAYSIZE(args));
- if (_curSpriteId != 0 && _curMaxSpriteId != 0 && n != 0) {
- int *p = &args[n - 1];
- do {
- int code = *p;
- if (code == 0) {
- for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
- _sprite->setSpriteResetClass(i);
- }
- } else if (code & 0x80) {
- for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
- _sprite->setSpriteSetClass(i, code & 0x7F, 1);
- }
- } else {
- for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
- _sprite->setSpriteSetClass(i, code & 0x7F, 0);
- }
- }
- --p;
- } while (--n);
- }
- break;
- case 32:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteFlagEraseType(spriteId, args[0]);
- break;
- case 38:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteGroup(spriteId, args[0]);
- break;
- case 40:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteImage(spriteId, args[0]);
- break;
- case 48:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteMaskImage(spriteId, args[0]);
- break;
- case 49:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->moveSprite(spriteId, args[0], args[1]);
- break;
- case 52:
- copyScriptString(string, sizeof(string));
- break;
- case 53:
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->resetSprite(spriteId);
- break;
- case 54:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteGeneralProperty(spriteId, args[0], args[1]);
- break;
- case 57:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpritePalette(spriteId, args[0]);
- break;
- case 59:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpritePriority(spriteId, args[0]);
- break;
- case 60:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- switch(args[1]) {
- case 0:
- _sprite->setSpriteFlagXFlipped(spriteId, args[0]);
- break;
- case 1:
- _sprite->setSpriteFlagYFlipped(spriteId, args[0]);
- break;
- case 2:
- _sprite->setSpriteFlagActive(spriteId, args[0]);
- break;
- case 3:
- _sprite->setSpriteFlagDoubleBuffered(spriteId, args[0]);
- break;
- case 4:
- _sprite->setSpriteFlagRemapPalette(spriteId, args[0]);
- break;
- default:
- break;
- }
- break;
- case 61:
- _sprite->resetTables(true);
- break;
- case 65:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteScale(spriteId, args[0]);
- break;
- case 70:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteShadow(spriteId, args[0]);
- break;
- case 73:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteImageState(spriteId, args[0]);
- break;
- case 74:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteDist(spriteId, args[0], args[1]);
- break;
- case 75:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++) {
- _sprite->getSpriteDist(spriteId, tmp[0], tmp[1]);
- _sprite->setSpriteDist(spriteId, args[0], tmp[1]);
- }
- break;
- case 76:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++) {
- _sprite->getSpriteDist(spriteId, tmp[0], tmp[1]);
- _sprite->setSpriteDist(spriteId, tmp[0], args[0]);
- }
- break;
- case 82:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteFlagUpdateType(spriteId, args[0]);
- break;
- case 83:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteUserValue(spriteId, args[0], args[1]);
- break;
- case 88:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteField84(spriteId, args[0]);
- break;
- case 89:
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteField84(spriteId, 0);
- break;
- default:
- error("o100_setSpriteInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_startScript() {
- int args[25];
- int script;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = fetchScriptByte();
- runScript(script, (flags == 128 || flags == 129), (flags == 130 || flags == 129), args);
-}
-
-void ScummEngine_v100he::o100_systemOps() {
- byte string[1024];
-
- byte subOp = fetchScriptByte();
- subOp -= 61;
-
- switch (subOp) {
- case 0:
- restart();
- break;
- case 67:
- clearDrawObjectQueue();
- break;
- case 71:
- // Confirm shutdown
- shutDown();
- break;
- case 72:
- shutDown();
- break;
- case 73:
- copyScriptString(string, sizeof(string));
- debug(0, "Start game (%s)", string);
- break;
- case 74:
- copyScriptString(string, sizeof(string));
- debug(0, "Start executable (%s)", string);
- break;
- case 75:
- gdi.copyVirtScreenBuffers(Common::Rect(_screenWidth, _screenHeight));
- updatePalette();
- break;
- default:
- error("o100_systemOps invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_cursorCommand() {
- int a, i;
- int args[16];
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0xE: // SO_CHARSET_SET
- initCharset(pop());
- break;
- case 0xF: // SO_CHARSET_COLOR
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- break;
- case 0x80:
- case 0x81:
- a = pop();
- _wiz->loadWizCursor(a);
- break;
- case 0x82:
- pop();
- a = pop();
- _wiz->loadWizCursor(a);
- break;
- case 0x86: // SO_CURSOR_ON Turn cursor on
- _cursor.state = 1;
- break;
- case 0x87: // SO_CURSOR_OFF Turn cursor off
- _cursor.state = 0;
- break;
- case 0x88: // SO_CURSOR_SOFT_ON Turn soft cursor on
- _cursor.state++;
- if (_cursor.state > 1)
- error("o100_cursorCommand: Cursor state greater than 1 in script");
- break;
-
- case 0x89: // SO_CURSOR_SOFT_OFF Turn soft cursor off
- _cursor.state--;
- break;
- case 0x8B: // SO_USERPUT_ON
- _userPut = 1;
- break;
- case 0x8C: // SO_USERPUT_OFF
- _userPut = 0;
- break;
- case 0x8D: // SO_USERPUT_SOFT_ON
- _userPut++;
- break;
- case 0x8E: // SO_USERPUT_SOFT_OFF
- _userPut--;
- break;
- default:
- error("o100_cursorCommand: default case %x", subOp);
- }
-
- VAR(VAR_CURSORSTATE) = _cursor.state;
- VAR(VAR_USERPUT) = _userPut;
-}
-
-void ScummEngine_v100he::o100_videoOps() {
- // Uses Bink video
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0:
- memset(_videoParams.filename, 0, sizeof(_videoParams.filename));
- _videoParams.unk2 = pop();
- break;
- case 19:
- _videoParams.status = 19;
- break;
- case 40:
- _videoParams.wizResNum = pop();
- if (_videoParams.wizResNum)
- _videoParams.flags |= 2;
- break;
- case 47:
- copyScriptString(_videoParams.filename, sizeof(_videoParams.filename));
- _videoParams.status = 47;
- break;
- case 67:
- _videoParams.flags |= pop();
- break;
- case 92:
- if (_videoParams.status == 47) {
- // Start video
- if (_videoParams.flags == 0)
- _videoParams.flags = 4;
-
- if (_videoParams.flags == 2) {
- // result = startVideo(_videoParams.filename, _videoParams.flags, _videoParams.wizResNum);
- // VAR(119) = result;
- } else {
- // result = startVideo(_videoParams.filename, _videoParams.flags);
- // VAR(119) = result;
- }
- } else if (_videoParams.status == 19) {
- // Stop video
- }
- break;
- default:
- error("o100_videoOps: unhandled case %d", subOp);
- }
-
- debug(1,"o100_videoOps stub (%d)", subOp);
-}
-
-void ScummEngine_v100he::o100_wait() {
- int actnum;
- int offs = -2;
- Actor *a;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 128: // SO_WAIT_FOR_ACTOR Wait for actor
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o100_wait:168");
- if (a->_moving)
- break;
- return;
- case 129: // SO_WAIT_FOR_CAMERA Wait for camera
- if (camera._cur.x / 8 != camera._dest.x / 8)
- break;
- return;
- case 130: // SO_WAIT_FOR_MESSAGE Wait for message
- if (VAR(VAR_HAVE_MSG))
- break;
- return;
- case 131: // SO_WAIT_FOR_SENTENCE
- if (_sentenceNum) {
- if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- }
- if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- default:
- error("o100_wait: default case 0x%x", subOp);
- }
-
- _scriptPointer += offs;
- o6_breakHere();
-}
-
-void ScummEngine_v100he::o100_writeFile() {
- int32 resID = pop();
- int slot = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 5:
- fetchScriptByte();
- writeFileFromArray(slot, resID);
- break;
- case 42:
- _hFileTable[slot].writeUint16LE(resID);
- break;
- case 43:
- _hFileTable[slot].writeUint32LE(resID);
- break;
- case 45:
- _hFileTable[slot].writeByte(resID);
- break;
- default:
- error("o100_writeFile: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_isResourceLoaded() {
- // Reports percentage of resource loaded by queue
- int type;
-
- byte subOp = fetchScriptByte();
- /* int idx = */ pop();
-
- switch (subOp) {
- case 25:
- type = rtCostume;
- break;
- case 40:
- type = rtImage;
- break;
- case 62:
- type = rtRoom;
- break;
- case 66:
- type = rtScript;
- break;
- case 72:
- type = rtSound;
- break;
- default:
- error("o100_isResourceLoaded: default case %d", subOp);
- }
-
- push(100);
-}
-
-void ScummEngine_v100he::o100_getResourceSize() {
- const byte *ptr;
- int size, type;
-
- int resid = pop();
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 25:
- type = rtCostume;
- break;
- case 40:
- type = rtImage;
- break;
- case 62:
- type = rtRoomImage;
- break;
- case 66:
- type = rtScript;
- break;
- case 72:
- push (getSoundResourceSize(resid));
- return;
- default:
- error("o100_getResourceSize: default type %d", subOp);
- }
-
- ptr = getResourceAddress(type, resid);
- assert(ptr);
- size = READ_BE_UINT32(ptr + 4) - 8;
- push(size);
-}
-
-void ScummEngine_v100he::o100_getSpriteGroupInfo() {
- int32 tx, ty;
- int spriteGroupId, type;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 5:
- spriteGroupId = pop();
- if (spriteGroupId)
- push(getGroupSpriteArray(spriteGroupId));
- else
- push(0);
- break;
- case 40:
- spriteGroupId = pop();
- if (spriteGroupId)
- push(_sprite->getGroupDstResNum(spriteGroupId));
- else
- push(0);
- break;
- case 54:
- // TODO: U32 related
- pop();
- pop();
- push(0);
- break;
- case 59:
- spriteGroupId = pop();
- if (spriteGroupId)
- push(_sprite->getGroupPriority(spriteGroupId));
- else
- push(0);
- break;
- case 60:
- type = pop();
- spriteGroupId = pop();
- if (spriteGroupId) {
- switch(type) {
- case 0:
- push(_sprite->getGroupXMul(spriteGroupId));
- break;
- case 1:
- push(_sprite->getGroupXDiv(spriteGroupId));
- break;
- case 2:
- push(_sprite->getGroupYMul(spriteGroupId));
- break;
- case 3:
- push(_sprite->getGroupYDiv(spriteGroupId));
- break;
- default:
- push(0);
- }
- } else {
- push(0);
- }
- break;
- case 85:
- spriteGroupId = pop();
- if (spriteGroupId) {
- _sprite->getGroupPosition(spriteGroupId, tx, ty);
- push(tx);
- } else {
- push(0);
- }
- break;
- case 86:
- spriteGroupId = pop();
- if (spriteGroupId) {
- _sprite->getGroupPosition(spriteGroupId, tx, ty);
- push(ty);
- } else {
- push(0);
- }
- break;
- default:
- error("o100_getSpriteGroupInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_getWizData() {
- byte filename[4096];
- int resId, state, type;
- int32 w, h;
- int32 x, y;
-
- byte subOp = fetchScriptByte();
- subOp -= 20;
-
- switch (subOp) {
- case 0:
- y = pop();
- x = pop();
- state = pop();
- resId = pop();
- push(_wiz->getWizPixelColor(resId, state, x, y, 0));
- break;
- case 6:
- resId = pop();
- push(_wiz->getWizImageStates(resId));
- break;
- case 13:
- y = pop();
- x = pop();
- state = pop();
- resId = pop();
- push(_wiz->isWizPixelNonTransparent(resId, state, x, y, 0));
- break;
- case 19:
- state = pop();
- resId = pop();
- _wiz->getWizImageDim(resId, state, w, h);
- push(h);
- break;
- case 34:
- type = pop();
- state = pop();
- resId = pop();
- push(_wiz->getWizImageData(resId, state, type));
- break;
- case 64:
- state = pop();
- resId = pop();
- _wiz->getWizImageDim(resId, state, w, h);
- push(w);
- break;
- case 65:
- state = pop();
- resId = pop();
- _wiz->getWizImageSpot(resId, state, x, y);
- push(x);
- break;
- case 66:
- state = pop();
- resId = pop();
- _wiz->getWizImageSpot(resId, state, x, y);
- push(y);
- break;
- case 111:
- pop();
- copyScriptString(filename, sizeof(filename));
- pop();
- push(0);
- debug(0, "o100_getWizData() case 111 unhandled");
- break;
- case 112:
- h = pop();
- w = pop();
- y = pop();
- x = pop();
- state = pop();
- resId = pop();
- if (x == -1 && y == -1 && w == -1 && h == -1) {
- _wiz->getWizImageDim(resId, state, w, h);
- x = 0;
- y = 0;
- }
- push(computeWizHistogram(resId, state, x, y, w, h));
- break;
- default:
- error("o100_getWizData: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_getPaletteData() {
- int b, c, d, e;
- int palSlot, color;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 13:
- c = pop();
- b = pop();
- push(getHEPaletteColorComponent(1, b, c));
- break;
- case 20:
- color = pop();
- palSlot = pop();
- push(getHEPaletteColor(palSlot, color));
- break;
- case 33:
- e = pop();
- d = pop();
- palSlot = pop();
- pop();
- c = pop();
- b = pop();
- push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
- break;
- case 53:
- pop();
- c = pop();
- c = MAX(0, c);
- c = MIN(c, 255);
- b = pop();
- b = MAX(0, b);
- b = MIN(b, 255);
- push(getHEPaletteSimilarColor(1, b, c, 10, 245));
- break;
- case 73:
- c = pop();
- b = pop();
- palSlot = pop();
- push(getHEPaletteColorComponent(palSlot, b, c));
- break;
- default:
- error("o100_getPaletteData: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_readFile() {
- int slot, val;
- int32 size;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 5:
- fetchScriptByte();
- size = pop();
- slot = pop();
- val = readFileToArray(slot, size);
- push(val);
- break;
- case 42:
- slot = pop();
- val = _hFileTable[slot].readUint16LE();
- push(val);
- break;
- case 43:
- slot = pop();
- val = _hFileTable[slot].readUint32LE();
- push(val);
- break;
- case 45:
- slot = pop();
- val = _hFileTable[slot].readByte();
- push(val);
- break;
- default:
- error("o100_readFile: default case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_getSpriteInfo() {
- int args[16];
- int spriteId, flags, groupId, type;
- int32 x, y;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 3:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteFlagAutoAnim(spriteId));
- else
- push(0);
- break;
- case 4:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteAnimSpeed(spriteId));
- else
- push(1);
- break;
- case 7:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteSourceImage(spriteId));
- else
- push(0);
- break;
- case 16:
- flags = getStackList(args, ARRAYSIZE(args));
- spriteId = pop();
- if (spriteId) {
- push(_sprite->getSpriteClass(spriteId, flags, args));
- } else {
- push(0);
- }
- break;
- case 26:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteImageStateCount(spriteId));
- else
- push(0);
- break;
- case 30:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteDisplayX(spriteId));
- else
- push(0);
- break;
- case 31:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteDisplayY(spriteId));
- else
- push(0);
- break;
- case 32:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteFlagEraseType(spriteId));
- else
- push(1);
- break;
- case 33:
- flags = getStackList(args, ARRAYSIZE(args));
- type = pop();
- groupId = pop();
- y = pop();
- x = pop();
- push(_sprite->findSpriteWithClassOf(x, y, groupId, type, flags, args));
- break;
- case 38:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteGroup(spriteId));
- else
- push(0);
- break;
- case 39:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteImageDim(spriteId, x, y);
- push(y);
- } else {
- push(0);
- }
- break;
- case 40:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteImage(spriteId));
- else
- push(0);
- break;
- case 48:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteMaskImage(spriteId));
- else
- push(0);
- break;
- case 54:
- flags = pop();
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteGeneralProperty(spriteId, flags));
- else
- push(0);
- break;
- case 57:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpritePalette(spriteId));
- else
- push(0);
- break;
- case 59:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpritePriority(spriteId));
- else
- push(0);
- break;
- case 60:
- flags = pop();
- spriteId = pop();
- if (spriteId) {
- switch(flags) {
- case 0:
- push(_sprite->getSpriteFlagXFlipped(spriteId));
- break;
- case 1:
- push(_sprite->getSpriteFlagYFlipped(spriteId));
- break;
- case 2:
- push(_sprite->getSpriteFlagActive(spriteId));
- break;
- case 3:
- push(_sprite->getSpriteFlagDoubleBuffered(spriteId));
- break;
- case 4:
- push(_sprite->getSpriteFlagRemapPalette(spriteId));
- break;
- default:
- push(0);
- }
- } else {
- push(0);
- }
- break;
- case 65:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteScale(spriteId));
- else
- push(0);
- break;
- case 70:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteShadow(spriteId));
- else
- push(0);
- break;
- case 73:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteImageState(spriteId));
- else
- push(0);
- break;
- case 75:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteDist(spriteId, x, y);
- push(x);
- } else {
- push(0);
- }
- break;
- case 76:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteDist(spriteId, x, y);
- push(y);
- } else {
- push(0);
- }
- break;
- case 82:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteFlagUpdateType(spriteId));
- else
- push(0);
- break;
- case 83:
- pop();
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteUserValue(spriteId));
- else
- push(0);
- break;
- case 84:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteImageDim(spriteId, x, y);
- push(x);
- } else {
- push(0);
- }
- break;
- case 85:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpritePosition(spriteId, x, y);
- push(x);
- } else {
- push(0);
- }
- break;
- case 86:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpritePosition(spriteId, x, y);
- push(y);
- } else {
- push(0);
- }
- break;
- default:
- error("o100_getSpriteInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v100he::o100_getVideoData() {
- // Uses Bink video
- byte subOp = fetchScriptByte();
- subOp -= 26;
-
- switch (subOp) {
- case 0:
- pop();
- break;
- case 13:
- pop();
- break;
- case 14:
- pop();
- break;
- case 28:
- pop();
- pop();
- break;
- case 47:
- pop();
- break;
- case 58:
- pop();
- break;
- default:
- error("o100_getVideoData: unhandled case %d", subOp);
- }
-
- push(-1);
- debug(1,"o100_getVideoData stub (%d)", subOp);
-}
-
-void ScummEngine_v100he::decodeParseString(int m, int n) {
- Actor *a;
- int i, colors, size;
- int args[31];
- byte name[1024];
-
- byte b = fetchScriptByte();
-
- switch (b) {
- case 6: // SO_AT
- _string[m].ypos = pop();
- _string[m].xpos = pop();
- _string[m].overhead = false;
- break;
- case 12: // SO_CENTER
- _string[m].center = true;
- _string[m].overhead = false;
- break;
- case 18: // SO_CLIPPED
- _string[m].right = pop();
- break;
- case 20: // SO_COLOR
- _string[m].color = pop();
- break;
- case 21:
- colors = pop();
- if (colors == 1) {
- _string[m].color = pop();
- } else {
- push(colors);
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- _string[m].color = _charsetColorMap[0];
- }
- break;
- case 35:
- decodeScriptString(name, true);
- printString(m, name);
- break;
- case 46: // SO_LEFT
- _string[m].center = false;
- _string[m].overhead = false;
- break;
- case 51: // SO_MUMBLE
- _string[m].no_talk_anim = true;
- break;
- case 56: // SO_OVERHEAD
- _string[m].overhead = true;
- _string[m].no_talk_anim = false;
- break;
- case 78:
- {
- byte *dataPtr = getResourceAddress(rtTalkie, pop());
- byte *text = findWrappedBlock(MKID('TEXT'), dataPtr, 0, 0);
- size = getResourceDataSize(text);
- memcpy(name, text, size);
- printString(m, name);
- }
- break;
- case 79: // SO_TEXTSTRING
- printString(m, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
- break;
- case 91:
- _string[m].loadDefault();
- if (n) {
- _actorToPrintStrFor = pop();
- if (_actorToPrintStrFor != 0xFF) {
- a = derefActor(_actorToPrintStrFor, "decodeParseString");
- _string[0].color = a->_talkColor;
- }
- }
- break;
- case 92:
- _string[m].saveDefault();
- break;
- default:
- error("decodeParseString: default case %d", b);
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp
deleted file mode 100644
index 880628f53e..0000000000
--- a/scumm/script_v2.cpp
+++ /dev/null
@@ -1,1629 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern.h"
-#include "scumm/object.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v2, x)
-
-void ScummEngine_v2::setupOpcodes() {
- static const OpcodeEntryV2 opcodes[256] = {
- /* 00 */
- OPCODE(o5_stopObjectCode),
- OPCODE(o2_putActor),
- OPCODE(o5_startMusic),
- OPCODE(o5_getActorRoom),
- /* 04 */
- OPCODE(o2_isGreaterEqual),
- OPCODE(o2_drawObject),
- OPCODE(o2_getActorElevation),
- OPCODE(o2_setState08),
- /* 08 */
- OPCODE(o5_isNotEqual),
- OPCODE(o5_faceActor),
- OPCODE(o2_assignVarWordIndirect),
- OPCODE(o2_setObjPreposition),
- /* 0C */
- OPCODE(o2_resourceRoutines),
- OPCODE(o5_walkActorToActor),
- OPCODE(o2_putActorAtObject),
- OPCODE(o2_ifNotState08),
- /* 10 */
- OPCODE(o5_getObjectOwner),
- OPCODE(o2_animateActor),
- OPCODE(o2_panCameraTo),
- OPCODE(o2_actorOps),
- /* 14 */
- OPCODE(o5_print),
- OPCODE(o2_actorFromPos),
- OPCODE(o5_getRandomNr),
- OPCODE(o2_clearState02),
- /* 18 */
- OPCODE(o5_jumpRelative),
- OPCODE(o2_doSentence),
- OPCODE(o5_move),
- OPCODE(o2_setBitVar),
- /* 1C */
- OPCODE(o5_startSound),
- OPCODE(o2_ifClassOfIs),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState02),
- /* 20 */
- OPCODE(o5_stopMusic),
- OPCODE(o2_putActor),
- OPCODE(o5_saveLoadGame),
- OPCODE(o2_getActorY),
- /* 24 */
- OPCODE(o2_loadRoomWithEgo),
- OPCODE(o2_drawObject),
- OPCODE(o5_setVarRange),
- OPCODE(o2_setState04),
- /* 28 */
- OPCODE(o5_equalZero),
- OPCODE(o2_setOwnerOf),
- OPCODE(o2_addIndirect),
- OPCODE(o5_delayVariable),
- /* 2C */
- OPCODE(o2_assignVarByte),
- OPCODE(o5_putActorInRoom),
- OPCODE(o2_delay),
- OPCODE(o2_ifNotState04),
- /* 30 */
- OPCODE(o2_setBoxFlags),
- OPCODE(o2_getBitVar),
- OPCODE(o2_setCameraAt),
- OPCODE(o2_roomOps),
- /* 34 */
- OPCODE(o5_getDist),
- OPCODE(o2_findObject),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_setState01),
- /* 38 */
- OPCODE(o2_isLessEqual),
- OPCODE(o2_doSentence),
- OPCODE(o2_subtract),
- OPCODE(o2_waitForActor),
- /* 3C */
- OPCODE(o5_stopSound),
- OPCODE(o2_setActorElevation),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState01),
- /* 40 */
- OPCODE(o2_cutscene),
- OPCODE(o2_putActor),
- OPCODE(o2_startScript),
- OPCODE(o2_getActorX),
- /* 44 */
- OPCODE(o2_isLess),
- OPCODE(o2_drawObject),
- OPCODE(o5_increment),
- OPCODE(o2_clearState08),
- /* 48 */
- OPCODE(o5_isEqual),
- OPCODE(o5_faceActor),
- OPCODE(o2_chainScript),
- OPCODE(o2_setObjPreposition),
- /* 4C */
- OPCODE(o2_waitForSentence),
- OPCODE(o5_walkActorToActor),
- OPCODE(o2_putActorAtObject),
- OPCODE(o2_ifState08),
- /* 50 */
- OPCODE(o2_pickupObject),
- OPCODE(o2_animateActor),
- OPCODE(o5_actorFollowCamera),
- OPCODE(o2_actorOps),
- /* 54 */
- OPCODE(o5_setObjectName),
- OPCODE(o2_actorFromPos),
- OPCODE(o5_getActorMoving),
- OPCODE(o2_setState02),
- /* 58 */
- OPCODE(o2_beginOverride),
- OPCODE(o2_doSentence),
- OPCODE(o2_add),
- OPCODE(o2_setBitVar),
- /* 5C */
- OPCODE(o2_dummy),
- OPCODE(o2_ifClassOfIs),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState02),
- /* 60 */
- OPCODE(o2_cursorCommand),
- OPCODE(o2_putActor),
- OPCODE(o2_stopScript),
- OPCODE(o5_getActorFacing),
- /* 64 */
- OPCODE(o2_loadRoomWithEgo),
- OPCODE(o2_drawObject),
- OPCODE(o5_getClosestObjActor),
- OPCODE(o2_clearState04),
- /* 68 */
- OPCODE(o5_isScriptRunning),
- OPCODE(o2_setOwnerOf),
- OPCODE(o2_subIndirect),
- OPCODE(o2_dummy),
- /* 6C */
- OPCODE(o2_getObjPreposition),
- OPCODE(o5_putActorInRoom),
- OPCODE(o2_dummy),
- OPCODE(o2_ifState04),
- /* 70 */
- OPCODE(o2_lights),
- OPCODE(o5_getActorCostume),
- OPCODE(o5_loadRoom),
- OPCODE(o2_roomOps),
- /* 74 */
- OPCODE(o5_getDist),
- OPCODE(o2_findObject),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_clearState01),
- /* 78 */
- OPCODE(o2_isGreater),
- OPCODE(o2_doSentence),
- OPCODE(o2_verbOps),
- OPCODE(o2_getActorWalkBox),
- /* 7C */
- OPCODE(o5_isSoundRunning),
- OPCODE(o2_setActorElevation),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState01),
- /* 80 */
- OPCODE(o5_breakHere),
- OPCODE(o2_putActor),
- OPCODE(o5_startMusic),
- OPCODE(o5_getActorRoom),
- /* 84 */
- OPCODE(o2_isGreaterEqual),
- OPCODE(o2_drawObject),
- OPCODE(o2_getActorElevation),
- OPCODE(o2_setState08),
- /* 88 */
- OPCODE(o5_isNotEqual),
- OPCODE(o5_faceActor),
- OPCODE(o2_assignVarWordIndirect),
- OPCODE(o2_setObjPreposition),
- /* 8C */
- OPCODE(o2_resourceRoutines),
- OPCODE(o5_walkActorToActor),
- OPCODE(o2_putActorAtObject),
- OPCODE(o2_ifNotState08),
- /* 90 */
- OPCODE(o5_getObjectOwner),
- OPCODE(o2_animateActor),
- OPCODE(o2_panCameraTo),
- OPCODE(o2_actorOps),
- /* 94 */
- OPCODE(o5_print),
- OPCODE(o2_actorFromPos),
- OPCODE(o5_getRandomNr),
- OPCODE(o2_clearState02),
- /* 98 */
- OPCODE(o2_restart),
- OPCODE(o2_doSentence),
- OPCODE(o5_move),
- OPCODE(o2_setBitVar),
- /* 9C */
- OPCODE(o5_startSound),
- OPCODE(o2_ifClassOfIs),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState02),
- /* A0 */
- OPCODE(o5_stopObjectCode),
- OPCODE(o2_putActor),
- OPCODE(o5_saveLoadGame),
- OPCODE(o2_getActorY),
- /* A4 */
- OPCODE(o2_loadRoomWithEgo),
- OPCODE(o2_drawObject),
- OPCODE(o5_setVarRange),
- OPCODE(o2_setState04),
- /* A8 */
- OPCODE(o5_notEqualZero),
- OPCODE(o2_setOwnerOf),
- OPCODE(o2_addIndirect),
- OPCODE(o2_switchCostumeSet),
- /* AC */
- OPCODE(o2_drawSentence),
- OPCODE(o5_putActorInRoom),
- OPCODE(o2_waitForMessage),
- OPCODE(o2_ifNotState04),
- /* B0 */
- OPCODE(o2_setBoxFlags),
- OPCODE(o2_getBitVar),
- OPCODE(o2_setCameraAt),
- OPCODE(o2_roomOps),
- /* B4 */
- OPCODE(o5_getDist),
- OPCODE(o2_findObject),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_setState01),
- /* B8 */
- OPCODE(o2_isLessEqual),
- OPCODE(o2_doSentence),
- OPCODE(o2_subtract),
- OPCODE(o2_waitForActor),
- /* BC */
- OPCODE(o5_stopSound),
- OPCODE(o2_setActorElevation),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState01),
- /* C0 */
- OPCODE(o2_endCutscene),
- OPCODE(o2_putActor),
- OPCODE(o2_startScript),
- OPCODE(o2_getActorX),
- /* C4 */
- OPCODE(o2_isLess),
- OPCODE(o2_drawObject),
- OPCODE(o5_decrement),
- OPCODE(o2_clearState08),
- /* C8 */
- OPCODE(o5_isEqual),
- OPCODE(o5_faceActor),
- OPCODE(o2_chainScript),
- OPCODE(o2_setObjPreposition),
- /* CC */
- OPCODE(o5_pseudoRoom),
- OPCODE(o5_walkActorToActor),
- OPCODE(o2_putActorAtObject),
- OPCODE(o2_ifState08),
- /* D0 */
- OPCODE(o2_pickupObject),
- OPCODE(o2_animateActor),
- OPCODE(o5_actorFollowCamera),
- OPCODE(o2_actorOps),
- /* D4 */
- OPCODE(o5_setObjectName),
- OPCODE(o2_actorFromPos),
- OPCODE(o5_getActorMoving),
- OPCODE(o2_setState02),
- /* D8 */
- OPCODE(o5_printEgo),
- OPCODE(o2_doSentence),
- OPCODE(o2_add),
- OPCODE(o2_setBitVar),
- /* DC */
- OPCODE(o2_dummy),
- OPCODE(o2_ifClassOfIs),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifNotState02),
- /* E0 */
- OPCODE(o2_cursorCommand),
- OPCODE(o2_putActor),
- OPCODE(o2_stopScript),
- OPCODE(o5_getActorFacing),
- /* E4 */
- OPCODE(o2_loadRoomWithEgo),
- OPCODE(o2_drawObject),
- OPCODE(o5_getClosestObjActor),
- OPCODE(o2_clearState04),
- /* E8 */
- OPCODE(o5_isScriptRunning),
- OPCODE(o2_setOwnerOf),
- OPCODE(o2_subIndirect),
- OPCODE(o2_dummy),
- /* EC */
- OPCODE(o2_getObjPreposition),
- OPCODE(o5_putActorInRoom),
- OPCODE(o2_dummy),
- OPCODE(o2_ifState04),
- /* F0 */
- OPCODE(o2_lights),
- OPCODE(o5_getActorCostume),
- OPCODE(o5_loadRoom),
- OPCODE(o2_roomOps),
- /* F4 */
- OPCODE(o5_getDist),
- OPCODE(o2_findObject),
- OPCODE(o2_walkActorToObject),
- OPCODE(o2_clearState01),
- /* F8 */
- OPCODE(o2_isGreater),
- OPCODE(o2_doSentence),
- OPCODE(o2_verbOps),
- OPCODE(o2_getActorWalkBox),
- /* FC */
- OPCODE(o5_isSoundRunning),
- OPCODE(o2_setActorElevation),
- OPCODE(o2_walkActorTo),
- OPCODE(o2_ifState01)
- };
-
- _opcodesV2 = opcodes;
-}
-
-#define SENTENCE_SCRIPT 2
-
-#define PARAM_1 0x80
-#define PARAM_2 0x40
-#define PARAM_3 0x20
-
-void ScummEngine_v2::executeOpcode(byte i) {
- OpcodeProcV2 op = _opcodesV2[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v2::getOpcodeDesc(byte i) {
- return _opcodesV2[i].desc;
-}
-
-int ScummEngine_v2::getVar() {
- return readVar(fetchScriptByte());
-}
-
-void ScummEngine_v2::decodeParseString() {
- byte buffer[512];
- byte *ptr = buffer;
- byte c;
- bool insertSpace = false;
-
- while ((c = fetchScriptByte())) {
-
- insertSpace = (c & 0x80) != 0;
- c &= 0x7f;
-
- if (c < 8) {
- // Special codes as seen in CHARSET_1 etc. My guess is that they
- // have a similar function as the corresponding embedded stuff in modern
- // games. Hence for now we convert them to the modern format.
- // This might allow us to reuse the existing code.
- *ptr++ = 0xFF;
- *ptr++ = c;
- if (c > 3) {
- *ptr++ = fetchScriptByte();
- *ptr++ = 0;
- }
- } else
- *ptr++ = c;
-
- if (insertSpace)
- *ptr++ = ' ';
-
- }
- *ptr = 0;
-
- int textSlot = 0;
- _string[textSlot].xpos = 0;
- _string[textSlot].ypos = 0;
- if (_platform == Common::kPlatformNES)
- _string[textSlot].right = 256;
- else
- _string[textSlot].right = 320;
- _string[textSlot].center = false;
- _string[textSlot].overhead = false;
-
- if (_gameId == GID_MANIAC && _actorToPrintStrFor == 0xFF) {
- if (_platform == Common::kPlatformC64) {
- _string[textSlot].color = 14;
- } else if (_demoMode) {
- _string[textSlot].color = (_version == 2) ? 15 : 1;
- }
- }
-
- actorTalk(buffer);
-}
-
-int ScummEngine_v2::readVar(uint var) {
- if (var >= 14 && var <= 16)
- var = _scummVars[var];
-
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(r)");
- debugC(DEBUG_VARS, "readvar(%d) = %d", var, _scummVars[var]);
- return _scummVars[var];
-}
-
-void ScummEngine_v2::writeVar(uint var, int value) {
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(r)");
- debugC(DEBUG_VARS, "writeVar(%d) = %d", var, value);
-
- if (VAR_CUTSCENEEXIT_KEY != 0xFF && var == VAR_CUTSCENEEXIT_KEY) {
- // Remap the cutscene exit key in earlier games
- if (value == 4 || value == 13 || value == 64)
- value = 27;
- }
-
- _scummVars[var] = value;
-
- // HACK: Ender's hack around a bug in Maniac. If you take the last dime from
- // Weird Ed's piggybank, this disables the New Kid option and runs the Jail
- // cutscene. Script 116 sets var[175] to 1, which disables New Kid in
- // script 164. Unfortunatly, when New Kid is reenabled (var[175] = 0) in
- // script 89, script 164 isn't reran to redraw it. Why? Dunno. Hack? Yes.
- if ((var == 175) && (_gameId == GID_MANIAC) && (vm.slot[_currentScript].number == 89))
- runScript(164, 0, 0, 0);
-}
-
-void ScummEngine_v2::getResultPosIndirect() {
- _resultVarNumber = _scummVars[fetchScriptByte()];
-}
-
-void ScummEngine_v2::getResultPos() {
- _resultVarNumber = fetchScriptByte();
-}
-
-void ScummEngine_v2::setStateCommon(byte type) {
- int obj = getVarOrDirectWord(PARAM_1);
- putState(obj, getState(obj) | type);
-}
-
-void ScummEngine_v2::clearStateCommon(byte type) {
- int obj = getVarOrDirectWord(PARAM_1);
- putState(obj, getState(obj) & ~type);
-}
-
-void ScummEngine_v2::o2_setState08() {
- int obj = getVarOrDirectWord(PARAM_1);
- putState(obj, getState(obj) | 0x08);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
-}
-
-void ScummEngine_v2::o2_clearState08() {
- int obj = getVarOrDirectWord(PARAM_1);
- putState(obj, getState(obj) & ~0x08);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
-}
-
-void ScummEngine_v2::o2_setState04() {
- setStateCommon(0x04);
-}
-
-void ScummEngine_v2::o2_clearState04() {
- clearStateCommon(0x04);
-}
-
-void ScummEngine_v2::o2_setState02() {
- setStateCommon(0x02);
-}
-
-void ScummEngine_v2::o2_clearState02() {
- clearStateCommon(0x02);
-}
-
-void ScummEngine_v2::o2_setState01() {
- setStateCommon(0x01);
-}
-
-void ScummEngine_v2::o2_clearState01() {
- clearStateCommon(0x01);
-}
-
-void ScummEngine_v2::o2_assignVarWordIndirect() {
- getResultPosIndirect();
- setResult(getVarOrDirectWord(PARAM_1));
-}
-
-void ScummEngine_v2::o2_assignVarByte() {
- getResultPos();
- setResult(fetchScriptByte());
-}
-
-void ScummEngine_v2::o2_setObjPreposition() {
- int obj = getVarOrDirectWord(PARAM_1);
- int unk = fetchScriptByte();
-
- if (_platform == Common::kPlatformNES)
- return;
-
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- // FIXME: this might not work properly the moment we save and restore the game.
- byte *ptr = getOBCDFromObject(obj) + 12;
- *ptr &= 0x1F;
- *ptr |= unk << 5;
- }
-}
-
-void ScummEngine_v2::o2_getObjPreposition() {
- getResultPos();
- int obj = getVarOrDirectWord(PARAM_1);
-
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- byte *ptr = getOBCDFromObject(obj) + 12;
- setResult(*ptr >> 5);
- } else {
- setResult(0xFF);
- }
-}
-
-void ScummEngine_v2::o2_setBitVar() {
- int var = fetchScriptWord();
- byte a = getVarOrDirectByte(PARAM_1);
-
- int bit_var = var + a;
- int bit_offset = bit_var & 0x0f;
- bit_var >>= 4;
-
- if (getVarOrDirectByte(PARAM_2))
- _scummVars[bit_var] |= (1 << bit_offset);
- else
- _scummVars[bit_var] &= ~(1 << bit_offset);
-
-}
-
-void ScummEngine_v2::o2_getBitVar() {
- getResultPos();
- int var = fetchScriptWord();
- byte a = getVarOrDirectByte(PARAM_1);
-
- int bit_var = var + a;
- int bit_offset = bit_var & 0x0f;
- bit_var >>= 4;
-
- setResult((_scummVars[bit_var] & (1 << bit_offset)) ? 1 : 0);
-}
-
-void ScummEngine_v2::ifStateCommon(byte type) {
- int obj = getVarOrDirectWord(PARAM_1);
-
- if ((getState(obj) & type) == 0)
- o5_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void ScummEngine_v2::ifNotStateCommon(byte type) {
- int obj = getVarOrDirectWord(PARAM_1);
-
- if ((getState(obj) & type) != 0)
- o5_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void ScummEngine_v2::o2_ifState08() {
- ifStateCommon(0x08);
-}
-
-void ScummEngine_v2::o2_ifNotState08() {
- ifNotStateCommon(0x08);
-}
-
-void ScummEngine_v2::o2_ifState04() {
- ifStateCommon(0x04);
-}
-
-void ScummEngine_v2::o2_ifNotState04() {
- ifNotStateCommon(0x04);
-}
-
-void ScummEngine_v2::o2_ifState02() {
- ifStateCommon(0x02);
-}
-
-void ScummEngine_v2::o2_ifNotState02() {
- ifNotStateCommon(0x02);
-}
-
-void ScummEngine_v2::o2_ifState01() {
- ifStateCommon(0x01);
-}
-
-void ScummEngine_v2::o2_ifNotState01() {
- ifNotStateCommon(0x01);
-}
-
-void ScummEngine_v2::o2_addIndirect() {
- int a;
- getResultPosIndirect();
- a = getVarOrDirectWord(PARAM_1);
- _scummVars[_resultVarNumber] += a;
-}
-
-void ScummEngine_v2::o2_subIndirect() {
- int a;
- getResultPosIndirect();
- a = getVarOrDirectWord(PARAM_1);
- _scummVars[_resultVarNumber] -= a;
-}
-
-void ScummEngine_v2::o2_add() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- _scummVars[_resultVarNumber] += a;
-}
-
-void ScummEngine_v2::o2_subtract() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- _scummVars[_resultVarNumber] -= a;
-}
-
-void ScummEngine_v2::o2_waitForActor() {
- Actor *a = derefActor(getVarOrDirectByte(PARAM_1), "o2_waitForActor");
- if (a->_moving) {
- _scriptPointer -= 2;
- o5_breakHere();
- }
-}
-
-void ScummEngine_v2::o2_waitForMessage() {
-
- if (VAR(VAR_HAVE_MSG)) {
- _scriptPointer--;
- o5_breakHere();
- }
-}
-
-void ScummEngine_v2::o2_waitForSentence() {
- if (!_sentenceNum && !isScriptInUse(SENTENCE_SCRIPT))
- return;
-
- _scriptPointer--;
- o5_breakHere();
-}
-
-void ScummEngine_v2::o2_actorOps() {
- int act = getVarOrDirectByte(PARAM_1);
- int arg = getVarOrDirectByte(PARAM_2);
- Actor *a;
- int i;
-
- _opcode = fetchScriptByte();
- if (act == 0 && _opcode == 5) {
- // This case happens in the Zak/MM bootscripts, to set the default talk color (9).
- _string[0].color = arg;
- return;
- }
-
- a = derefActor(act, "actorOps");
-
- switch (_opcode) {
- case 1: // SO_SOUND
- a->_sound[0] = arg;
- break;
- case 2: // SO_PALETTE
- if (_version == 1)
- i = act;
- else
- i = fetchScriptByte();
-
- a->setPalette(i, arg);
- break;
- case 3: // SO_ACTOR_NAME
- loadPtrToResource(rtActorName, a->_number, NULL);
- break;
- case 4: // SO_COSTUME
- a->setActorCostume(arg);
- break;
- case 5: // SO_TALK_COLOR
- if (_gameId == GID_MANIAC && _version == 2 && _demoMode && arg == 1)
- a->_talkColor = 15;
- else
- a->_talkColor = arg;
- break;
- default:
- error("o2_actorOps: opcode %d not yet supported", _opcode);
- }
-}
-
-void ScummEngine_v2::o2_restart() {
- restart();
-}
-
-void ScummEngine_v2::o2_drawObject() {
- int obj, idx, i;
- ObjectData *od;
- uint16 x, y, w, h;
- int xpos, ypos;
-
- obj = getVarOrDirectWord(PARAM_1);
- xpos = getVarOrDirectByte(PARAM_2);
- ypos = getVarOrDirectByte(PARAM_3);
-
- idx = getObjectIndex(obj);
- if (idx == -1)
- return;
-
- od = &_objs[idx];
- if (xpos != 0xFF) {
- od->walk_x += (xpos * 8) - od->x_pos;
- od->x_pos = xpos * 8;
- od->walk_y += (ypos * 8) - od->y_pos;
- od->y_pos = ypos * 8;
- }
- addObjectToDrawQue(idx);
-
- x = od->x_pos;
- y = od->y_pos;
- w = od->width;
- h = od->height;
-
- i = _numLocalObjects;
- while (i--) {
- if (_objs[i].obj_nr && _objs[i].x_pos == x && _objs[i].y_pos == y && _objs[i].width == w && _objs[i].height == h)
- putState(_objs[i].obj_nr, getState(_objs[i].obj_nr) & ~0x08);
- }
-
- putState(obj, getState(od->obj_nr) | 0x08);
-}
-
-void ScummEngine_v2::o2_resourceRoutines() {
- const ResTypes resTypes[] = {
- rtNumTypes, // Invalid
- rtNumTypes, // Invalid
- rtCostume,
- rtRoom,
- rtNumTypes, // Invalid
- rtScript,
- rtSound
- };
- int resid = getVarOrDirectByte(PARAM_1);
- int opcode = fetchScriptByte();
-
- ResTypes type = rtNumTypes;
- if (0 <= (opcode >> 4) && (opcode >> 4) < (int)ARRAYSIZE(resTypes))
- type = resTypes[opcode >> 4];
-
- if ((opcode & 0x0f) == 0 || type == rtNumTypes)
- return;
-
- // HACK V2 Maniac Mansion tries to load an invalid sound resource in demo script.
- if (_gameId == GID_MANIAC && _version == 2 && vm.slot[_currentScript].number == 9 && type == rtSound && resid == 1)
- return;
-
- if ((opcode & 0x0f) == 1) {
- ensureResourceLoaded(type, resid);
- } else {
- if (opcode & 1)
- res.lock(type, resid);
- else
- res.unlock(type, resid);
- }
-}
-
-void ScummEngine_v2::o2_verbOps() {
- int verb = fetchScriptByte();
- int slot, state;
-
- switch (verb) {
- case 0: // SO_DELETE_VERBS
- slot = getVarOrDirectByte(PARAM_1) + 1;
- assert(0 < slot && slot < _numVerbs);
-
- //printf("o2_verbOps delete slot = %d\n", slot);
- killVerb(slot);
- break;
-
- case 0xFF: // Verb On/Off
- verb = fetchScriptByte();
- state = fetchScriptByte();
- slot = getVerbSlot(verb, 0);
-
- //printf("o2_verbOps Verb On/Off: verb = %d, slot = %d, state = %d\n", verb, slot, state);
-
- _verbs[slot].curmode = state;
-
- break;
-
- default: { // New Verb
- int x = fetchScriptByte() * 8;
- int y = fetchScriptByte() * 8;
- slot = getVarOrDirectByte(PARAM_1) + 1;
- int prep = fetchScriptByte(); // Only used in V1?
- // V1 Maniac verbs are relative to the 'verb area' - under the sentence
- if (_platform == Common::kPlatformNES)
- x += 8;
- else if ((_gameId == GID_MANIAC) && (_version == 1))
- y += 8;
-
- //printf("o2_verbOps: verb = %d, slot = %d, x = %d, y = %d, unk = %d, name = %s\n",
- // verb, slot, x, y, prep, _scriptPointer);
-
- VerbSlot *vs;
- assert(0 < slot && slot < _numVerbs);
-
- vs = &_verbs[slot];
- vs->verbid = verb;
- if (_platform == Common::kPlatformNES) {
- vs->color = 1;
- vs->hicolor = 1;
- vs->dimcolor = 1;
- } else if (_version == 1) {
- vs->color = (_gameId == GID_MANIAC && _demoMode) ? 16 : 5;
- vs->hicolor = 7;
- vs->dimcolor = 11;
- } else {
- vs->color = (_gameId == GID_MANIAC && _demoMode) ? 13 : 2;
- vs->hicolor = 14;
- vs->dimcolor = 8;
- }
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 1;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- vs->prep = prep;
-
- vs->curRect.left = x;
- vs->curRect.top = y;
-
- // FIXME: again, this map depends on the language of the game.
- // E.g. a german keyboard has 'z' and 'y' swapped, while a french
- // keyboard starts with "awert", etc.
- const char keyboard[] = {
- 'q','w','e','r','t',
- 'a','s','d','f','g',
- 'z','x','c','v','b'
- };
- if (1 <= slot && slot <= ARRAYSIZE(keyboard))
- vs->key = keyboard[slot - 1];
-
- // It follows the verb name
- loadPtrToResource(rtVerb, slot, NULL);
- }
- break;
- }
-
- // Force redraw of the modified verb slot
- drawVerb(slot, 0);
- verbMouseOver(0);
-}
-
-void ScummEngine_v2::o2_doSentence() {
- int a;
- SentenceTab *st;
-
- a = getVarOrDirectByte(PARAM_1);
- if (a == 0xFC) {
- _sentenceNum = 0;
- stopScript(SENTENCE_SCRIPT);
- return;
- }
- if (a == 0xFB) {
- resetSentence();
- return;
- }
-
- st = &_sentence[_sentenceNum++];
-
- st->verb = a;
- st->objectA = getVarOrDirectWord(PARAM_2);
- st->objectB = getVarOrDirectWord(PARAM_3);
- st->preposition = (st->objectB != 0);
- st->freezeCount = 0;
-
- // Execute or print the sentence
- _opcode = fetchScriptByte();
- switch (_opcode) {
- case 0:
- // Do nothing (besides setting up the sentence above)
- break;
- case 1:
- // Execute the sentence
- _sentenceNum--;
-
- if (st->verb == 254) {
- ScummEngine::stopObjectScript(st->objectA);
- } else {
- bool isBackgroundScript;
- bool isSpecialVerb;
- if (st->verb != 253 && st->verb != 250) {
- VAR(VAR_ACTIVE_VERB) = st->verb;
- VAR(VAR_ACTIVE_OBJECT1) = st->objectA;
- VAR(VAR_ACTIVE_OBJECT2) = st->objectB;
-
- isBackgroundScript = false;
- isSpecialVerb = false;
- } else {
- isBackgroundScript = (st->verb == 250);
- isSpecialVerb = true;
- st->verb = 253;
- }
-
- // Check if an object script for this object is already running. If
- // so, reuse its script slot. Note that we abuse two script flags:
- // freezeResistant and recursive. We use them to track two
- // script flags used in V1/V2 games. The main reason we do it this
- // ugly evil way is to avoid having to introduce yet another save
- // game revision.
- int slot = -1;
- ScriptSlot *ss;
- int i;
-
- ss = vm.slot;
- for (i = 0; i < NUM_SCRIPT_SLOT; i++, ss++) {
- if (st->objectA == ss->number &&
- ss->freezeResistant == isBackgroundScript &&
- ss->recursive == isSpecialVerb &&
- (ss->where == WIO_ROOM || ss->where == WIO_INVENTORY || ss->where == WIO_FLOBJECT)) {
- slot = i;
- break;
- }
- }
-
- runObjectScript(st->objectA, st->verb, isBackgroundScript, isSpecialVerb, NULL, slot);
- }
- break;
- case 2:
- // Print the sentence
- _sentenceNum--;
-
- VAR(VAR_SENTENCE_VERB) = st->verb;
- VAR(VAR_SENTENCE_OBJECT1) = st->objectA;
- VAR(VAR_SENTENCE_OBJECT2) = st->objectB;
-
- o2_drawSentence();
- break;
- default:
- error("o2_doSentence: unknown subopcode %d", _opcode);
- }
-}
-
-void ScummEngine_v2::o2_drawSentence() {
- Common::Rect sentenceline;
- static char sentence[256];
- const byte *temp;
- int slot = getVerbSlot(VAR(VAR_SENTENCE_VERB), 0);
-
- if (!((_userState & 32) || (_platform == Common::kPlatformNES && _userState & 0xe0)))
- return;
-
- if (getResourceAddress(rtVerb, slot))
- strcpy(sentence, (char*)getResourceAddress(rtVerb, slot));
- else
- return;
-
- if (VAR(VAR_SENTENCE_OBJECT1) > 0) {
- temp = getObjOrActorName(VAR(VAR_SENTENCE_OBJECT1));
- if (temp) {
- strcat(sentence, " ");
- strcat(sentence, (const char*)temp);
- }
-
- // For V1 games, the engine must compute the preposition.
- // In all other Scumm versions, this is done by the sentence script.
- if ((_gameId == GID_MANIAC && _version == 1 && !(_platform == Common::kPlatformNES)) && (VAR(VAR_SENTENCE_PREPOSITION) == 0)) {
- if (_verbs[slot].prep == 0xFF) {
- byte *ptr = getOBCDFromObject(VAR(VAR_SENTENCE_OBJECT1));
- assert(ptr);
- VAR(VAR_SENTENCE_PREPOSITION) = (*(ptr + 12) >> 5);
- } else
- VAR(VAR_SENTENCE_PREPOSITION) = _verbs[slot].prep;
- }
- }
-
- if (0 < VAR(VAR_SENTENCE_PREPOSITION) && VAR(VAR_SENTENCE_PREPOSITION) <= 4) {
- // The prepositions, like the fonts, were hard code in the engine. Thus
- // we have to do that, too, and provde localized versions for all the
- // languages MM/Zak are available in.
- //
- // The order here matches the one defined in gameDetector.h
- const char *prepositions[][5] = {
- { " ", " in", " with", " on", " to" }, // English
- { " ", " mit", " mit", " mit", " zu" }, // German
- { " ", " dans", " avec", " sur", " <" }, // French
- { " ", " in", " con", " su", " a" }, // Italian
- { " ", " in", " with", " on", " to" }, // Portugese
- { " ", " en", " con", " en", " a" }, // Spanish
- { " ", " in", " with", " on", " to" }, // Japanese
- { " ", " in", " with", " on", " to" }, // Chinese
- { " ", " in", " with", " on", " to" } // Korean
- };
- int lang = (_language <= 8) ? _language : 0; // Default to english
- if (_platform == Common::kPlatformNES) {
- strcat(sentence, (const char *)(getResourceAddress(rtCostume, 78) + VAR(VAR_SENTENCE_PREPOSITION) * 8 + 2));
- } else
- strcat(sentence, prepositions[lang][VAR(VAR_SENTENCE_PREPOSITION)]);
- }
-
- if (VAR(VAR_SENTENCE_OBJECT2) > 0) {
- temp = getObjOrActorName(VAR(VAR_SENTENCE_OBJECT2));
- if (temp) {
- strcat(sentence, " ");
- strcat(sentence, (const char*)temp);
- }
- }
-
- _string[2].charset = 1;
- _string[2].ypos = virtscr[kVerbVirtScreen].topline;
- _string[2].xpos = 0;
- if (_platform == Common::kPlatformNES) {
- _string[2].xpos = 16;
- _string[2].color = 0;
- } else if (_version == 1)
- _string[2].color = 16;
- else
- _string[2].color = 13;
-
- byte string[80];
- char *ptr = sentence;
- int i = 0, len = 0;
-
- // Maximum length of printable characters
- int maxChars = (_platform == Common::kPlatformNES) ? 60: 40;
- while (*ptr) {
- if (*ptr != '@')
- len++;
- if (len > maxChars) {
- break;
- }
-
- string[i++] = *ptr++;
-
- if (_platform == Common::kPlatformNES && len == 30) {
- string[i++] = 0xFF;
- string[i++] = 8;
- }
- }
- string[i] = 0;
-
- if (_platform == Common::kPlatformNES) {
- sentenceline.top = virtscr[kVerbVirtScreen].topline;
- sentenceline.bottom = virtscr[kVerbVirtScreen].topline + 16;
- sentenceline.left = 16;
- sentenceline.right = 255;
- } else {
- sentenceline.top = virtscr[kVerbVirtScreen].topline;
- sentenceline.bottom = virtscr[kVerbVirtScreen].topline + 8;
- sentenceline.left = 0;
- sentenceline.right = 319;
- }
- restoreBG(sentenceline);
-
- drawString(2, (byte*)string);
-}
-
-void ScummEngine_v2::o2_ifClassOfIs() {
- int obj = getVarOrDirectWord(PARAM_1);
- int clsop = getVarOrDirectByte(PARAM_2);
- byte *obcd = getOBCDFromObject(obj);
-
- if (obcd == 0) {
- o5_jumpRelative();
- return;
- }
-
- byte cls = *(obcd + 6);
- if ((cls & clsop) != clsop) {
- o5_jumpRelative();
- return;
- }
- ignoreScriptWord();
-}
-
-void ScummEngine_v2::o2_walkActorTo() {
- int x, y;
- Actor *a;
-
- int act = getVarOrDirectByte(PARAM_1);
-
- // WORKAROUND bug #1252606
- if (_gameId == GID_ZAK && _version == 1 && vm.slot[_currentScript].number == 115 && act == 249) {
- act = VAR(VAR_EGO);
- }
-
- a = derefActor(act, "o2_walkActorTo");
-
- x = getVarOrDirectByte(PARAM_2) * 8;
- y = getVarOrDirectByte(PARAM_3) * 2;
-
- a->startWalkActor(x, y, -1);
-}
-
-void ScummEngine_v2::o2_putActor() {
- int act = getVarOrDirectByte(PARAM_1);
- int x, y;
- Actor *a;
-
- a = derefActor(act, "o2_putActor");
-
- x = getVarOrDirectByte(PARAM_2) * 8;
- y = getVarOrDirectByte(PARAM_3) * 2;
-
- a->putActor(x, y, a->_room);
-}
-
-void ScummEngine_v2::o2_startScript() {
- int script = getVarOrDirectByte(PARAM_1);
-
- if (!_copyProtection) {
- // The enhanced version of Zak McKracken included in the
- // SelectWare Classic Collection bundle used CD check instead
- // of the usual key code check at airports.
- if ((_gameId == GID_ZAK) && (script == 15) && (_roomResource == 45))
- return;
- }
-
- runScript(script, 0, 0, 0);
-}
-
-void ScummEngine_v2::o2_stopScript() {
- int script;
-
- script = getVarOrDirectByte(PARAM_1);
-
- if ((_gameId == GID_ZAK) && (_roomResource == 7) && (vm.slot[_currentScript].number == 10001)) {
- // FIXME: Nasty hack for bug #771499
- // Don't let the exit script for room 7 stop the buy script (24),
- // switching to the number selection keypad (script 15)
- if ((script == 24) && isScriptRunning(15))
- return;
- }
-
- if (script == 0)
- script = vm.slot[_currentScript].number;
-
- if (_currentScript != 0 && vm.slot[_currentScript].number == script)
- stopObjectCode();
- else
- stopScript(script);
-}
-
-void ScummEngine_v2::o2_panCameraTo() {
- panCameraTo(getVarOrDirectByte(PARAM_1) * 8, 0);
-}
-
-void ScummEngine_v2::o2_walkActorToObject() {
- int obj;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o2_walkActorToObject");
- obj = getVarOrDirectWord(PARAM_2);
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- int x, y, dir;
- getObjectXYPos(obj, x, y, dir);
- a->startWalkActor(x, y, dir);
- }
-}
-
-void ScummEngine_v2::o2_putActorAtObject() {
- int obj, x, y;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o2_putActorAtObject");
-
- obj = getVarOrDirectWord(PARAM_2);
- if (whereIsObject(obj) != WIO_NOT_FOUND)
- getObjectXYPos(obj, x, y);
- else {
- x = 240;
- y = 120;
- }
-
- a->putActor(x, y, a->_room);
-}
-
-void ScummEngine_v2::o2_getActorElevation() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o2_getActorElevation");
- setResult(a->getElevation() / 2);
-}
-
-void ScummEngine_v2::o2_setActorElevation() {
- int act = getVarOrDirectByte(PARAM_1);
- int elevation = (int8)getVarOrDirectByte(PARAM_2);
-
- Actor *a = derefActor(act, "o2_setActorElevation");
- a->setElevation(elevation * 2);
-}
-
-void ScummEngine_v2::o2_animateActor() {
- int act = getVarOrDirectByte(PARAM_1);
- int anim = getVarOrDirectByte(PARAM_2);
-
- Actor *a = derefActor(act, "o2_animateActor");
- a->animateActor(anim);
-}
-
-void ScummEngine_v2::o2_actorFromPos() {
- int x, y;
- getResultPos();
- x = getVarOrDirectByte(PARAM_1) * 8;
- y = getVarOrDirectByte(PARAM_2) * 2;
- setResult(getActorFromPos(x, y));
-}
-
-void ScummEngine_v2::o2_findObject() {
- int obj;
- getResultPos();
- int x = getVarOrDirectByte(PARAM_1) * 8;
- int y = getVarOrDirectByte(PARAM_2) * 2;
- obj = findObject(x, y);
- if (obj == 0 && (_platform == Common::kPlatformNES) && (_userState & 0x40)) {
- if (_mouseOverBoxV2 >= 0 && _mouseOverBoxV2 < 4)
- obj = findInventory(VAR(VAR_EGO), _mouseOverBoxV2 + _inventoryOffset + 1);
- }
- setResult(obj);
-}
-
-void ScummEngine_v2::o2_getActorX() {
- int a;
- getResultPos();
-
- a = getVarOrDirectByte(PARAM_1);
- setResult(getObjX(a) / 8);
-}
-
-void ScummEngine_v2::o2_getActorY() {
- int a;
- getResultPos();
-
- a = getVarOrDirectByte(PARAM_1);
- setResult(getObjY(a) / 2);
-}
-
-void ScummEngine_v2::o2_isGreater() {
- uint16 a = getVar();
- uint16 b = getVarOrDirectWord(PARAM_1);
- if (b > a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v2::o2_isGreaterEqual() {
- uint16 a = getVar();
- uint16 b = getVarOrDirectWord(PARAM_1);
- if (b >= a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v2::o2_isLess() {
- uint16 a = getVar();
- uint16 b = getVarOrDirectWord(PARAM_1);
-
- if (b < a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v2::o2_isLessEqual() {
- uint16 a = getVar();
- uint16 b = getVarOrDirectWord(PARAM_1);
- if (b <= a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v2::o2_lights() {
- int a, b, c;
-
- a = getVarOrDirectByte(PARAM_1);
- b = fetchScriptByte();
- c = fetchScriptByte();
-
- if (c == 0) {
- if (_gameId == GID_MANIAC && _version == 1 && !(_platform == Common::kPlatformNES)) {
- // Convert older light mode values into
- // equivalent values.of later games
- // 0 Darkness
- // 1 Flashlight
- // 2 Lighted area
- if (a == 2)
- VAR(VAR_CURRENT_LIGHTS) = 11;
- else if (a == 1)
- VAR(VAR_CURRENT_LIGHTS) = 4;
- else
- VAR(VAR_CURRENT_LIGHTS) = 0;
- } else
- VAR(VAR_CURRENT_LIGHTS) = a;
- } else if (c == 1) {
- _flashlight.xStrips = a;
- _flashlight.yStrips = b;
- }
- _fullRedraw = true;
-}
-
-void ScummEngine_v2::o2_loadRoomWithEgo() {
- Actor *a;
- int obj, room, x, y, x2, y2, dir;
-
- obj = getVarOrDirectWord(PARAM_1);
- room = getVarOrDirectByte(PARAM_2);
-
- a = derefActor(VAR(VAR_EGO), "o2_loadRoomWithEgo");
-
- a->putActor(0, 0, room);
- _egoPositioned = false;
-
- x = (int8)fetchScriptByte() * 8;
- y = (int8)fetchScriptByte() * 2;
-
- startScene(a->_room, a, obj);
-
- getObjectXYPos(obj, x2, y2, dir);
- a->putActor(x2, y2, _currentRoom);
- a->setDirection(dir + 180);
-
- camera._dest.x = camera._cur.x = a->_pos.x;
- setCameraAt(a->_pos.x, a->_pos.y);
- setCameraFollows(a);
-
- _fullRedraw = true;
-
- resetSentence();
-
- if (x >= 0 && y >= 0) {
- a->startWalkActor(x, y, -1);
- }
- runScript(5, 0, 0, 0);
-}
-
-void ScummEngine_v2::o2_setOwnerOf() {
- int obj, owner;
-
- obj = getVarOrDirectWord(PARAM_1);
- owner = getVarOrDirectByte(PARAM_2);
-
- setOwnerOf(obj, owner);
-}
-
-void ScummEngine_v2::o2_delay() {
- int delay = fetchScriptByte();
- delay |= fetchScriptByte() << 8;
- delay |= fetchScriptByte() << 16;
- delay = 0xFFFFFF - delay;
-
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = ssPaused;
- o5_breakHere();
-}
-
-void ScummEngine_v2::o2_setBoxFlags() {
- int a, b;
-
- a = getVarOrDirectByte(PARAM_1);
- b = fetchScriptByte();
- setBoxFlags(a, b);
-}
-
-void ScummEngine_v2::o2_setCameraAt() {
- setCameraAtEx(getVarOrDirectByte(PARAM_1) * 8);
-}
-
-void ScummEngine_v2::o2_roomOps() {
- int a = getVarOrDirectByte(PARAM_1);
- int b = getVarOrDirectByte(PARAM_2);
-
- _opcode = fetchScriptByte();
- switch (_opcode & 0x1F) {
- case 1: // SO_ROOM_SCROLL
- a *= 8;
- b *= 8;
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
- case 2: // SO_ROOM_COLOR
- if (_version == 1) {
- // V1 zak needs to know when room color is changed
- _roomPalette[0] = 255;
- _roomPalette[1] = a;
- _roomPalette[2] = b;
- } else {
- _roomPalette[b] = a;
- }
- _fullRedraw = true;
- break;
- }
-}
-
-void ScummEngine_v2::o2_cutscene() {
- vm.cutSceneData[0] = _userState | (_userPut ? 16 : 0);
- vm.cutSceneData[1] = (int16)VAR(VAR_CURSORSTATE);
- vm.cutSceneData[2] = _currentRoom;
- vm.cutSceneData[3] = camera._mode;
-
- VAR(VAR_CURSORSTATE) = 200;
-
- // FIXME allows quotes script (173) to start during introudction of
- // demo mode of V1 Maniac Mansion. setUserState was halting script
- // 173 before it started.
- if (!(_gameId == GID_MANIAC && _demoMode))
- // Hide inventory, freeze scripts, hide cursor
- setUserState(15);
-
- _sentenceNum = 0;
- stopScript(SENTENCE_SCRIPT);
- resetSentence();
-
- vm.cutScenePtr[0] = 0;
-}
-
-void ScummEngine_v2::o2_endCutscene() {
- vm.cutSceneStackPointer = 0;
-
- VAR(VAR_OVERRIDE) = 0;
- vm.cutSceneScript[0] = 0;
- vm.cutScenePtr[0] = 0;
-
- VAR(VAR_CURSORSTATE) = vm.cutSceneData[1];
-
- // Reset user state to values before cutscene
- setUserState(vm.cutSceneData[0] | 7);
-
- if ((_gameId == GID_MANIAC) && !(_platform == Common::kPlatformNES)) {
- camera._mode = (byte) vm.cutSceneData[3];
- if (camera._mode == kFollowActorCameraMode) {
- actorFollowCamera(VAR(VAR_EGO));
- } else if (vm.cutSceneData[2] != _currentRoom) {
- startScene(vm.cutSceneData[2], 0, 0);
- }
- } else {
- actorFollowCamera(VAR(VAR_EGO));
- }
-}
-
-void ScummEngine_v2::o2_beginOverride() {
- vm.cutScenePtr[0] = _scriptPointer - _scriptOrgPointer;
- vm.cutSceneScript[0] = _currentScript;
-
- // Skip the jump instruction following the override instruction
- fetchScriptByte();
- fetchScriptWord();
-}
-
-void ScummEngine_v2::o2_chainScript() {
- int data = getVarOrDirectByte(PARAM_1);
- stopScript(vm.slot[_currentScript].number);
- _currentScript = 0xFF;
- runScript(data, 0, 0, 0);
-}
-
-void ScummEngine_v2::o2_pickupObject() {
- int obj = getVarOrDirectWord(PARAM_1);
-
- if (obj < 1) {
- error("pickupObject received invalid index %d (script %d)", obj, vm.slot[_currentScript].number);
- }
-
- if (getObjectIndex(obj) == -1)
- return;
-
- if (whereIsObject(obj) == WIO_INVENTORY) /* Don't take an */
- return; /* object twice */
-
- addObjectToInventory(obj, _roomResource);
- markObjectRectAsDirty(obj);
- putOwner(obj, VAR(VAR_EGO));
- putState(obj, getState(obj) | 0xA);
- clearDrawObjectQueue();
-
- runInventoryScript(1);
- if (_platform == Common::kPlatformNES)
- _sound->addSoundToQueue(51); // play 'pickup' sound
-}
-
-void ScummEngine_v2::o2_cursorCommand() { // TODO: Define the magic numbers
- uint16 cmd = getVarOrDirectWord(PARAM_1);
- byte state = cmd >> 8;
-
- if (cmd & 0xFF) {
- VAR(VAR_CURSORSTATE) = cmd & 0xFF;
- }
-
- setUserState(state);
-}
-
-void ScummEngine_v2::setUserState(byte state) {
- if (state & 4) { // Userface
- if (_platform == Common::kPlatformNES)
- _userState = (_userState & ~0xE0) | (state & 0xE0);
- else
- _userState = state & (32 | 64 | 128);
- }
-
- if (state & 1) { // Freeze
- if (state & 8)
- freezeScripts(0);
- else
- unfreezeScripts();
- }
-
- if (state & 2) { // Cursor Show/Hide
- if (_platform == Common::kPlatformNES)
- _userState = (_userState & ~0x10) | (state & 0x10);
- if (state & 16) {
- _userPut = 1;
- _cursor.state = 1;
- } else {
- _userPut = 0;
- _cursor.state = 0;
- }
- }
-
- // Hide all verbs and inventory
- Common::Rect rect;
- rect.top = virtscr[kVerbVirtScreen].topline;
- rect.bottom = virtscr[kVerbVirtScreen].topline + 8 * 88;
- if (_platform == Common::kPlatformNES) {
- rect.left = 16;
- rect.right = 255;
- } else {
- rect.left = 0;
- rect.right = 319;
- }
- restoreBG(rect);
-
- // Draw all verbs and inventory
- redrawVerbs();
- runInventoryScript(1);
-}
-
-void ScummEngine_v2::o2_getActorWalkBox() {
- Actor *a;
- getResultPos();
- a = derefActor(getVarOrDirectByte(PARAM_1), "o2_getActorWalkbox");
- setResult(a->_walkbox);
-}
-
-void ScummEngine_v2::o2_dummy() {
- // Opcode 238 is used in maniac and zak but has no purpose
- if (_opcode != 238)
- warning("o2_dummy invoked (opcode %d)", _opcode);
-}
-
-void ScummEngine_v2::o2_switchCostumeSet() {
- // NES version of maniac uses this to switch between the two
- // groups of costumes it has
- if (_platform == Common::kPlatformNES)
- NES_loadCostumeSet(fetchScriptByte());
- else if (_platform == Common::kPlatformC64)
- fetchScriptByte();
- else
- o2_dummy();
-}
-
-void ScummEngine_v2::resetSentence() {
- VAR(VAR_SENTENCE_VERB) = VAR(VAR_BACKUP_VERB);
- VAR(VAR_SENTENCE_OBJECT1) = 0;
- VAR(VAR_SENTENCE_OBJECT2) = 0;
- VAR(VAR_SENTENCE_PREPOSITION) = 0;
-}
-
-void ScummEngine_v2::runInventoryScript(int i) {
- redrawV2Inventory();
-}
-
-#undef PARAM_1
-#undef PARAM_2
-#undef PARAM_3
-
-} // End of namespace Scumm
diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp
deleted file mode 100644
index 7a048d0a01..0000000000
--- a/scumm/script_v5.cpp
+++ /dev/null
@@ -1,2898 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern.h"
-#include "scumm/object.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-#include "common/savefile.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v5, x)
-
-void ScummEngine_v5::setupOpcodes() {
- static const OpcodeEntryV5 opcodes[256] = {
- /* 00 */
- OPCODE(o5_stopObjectCode),
- OPCODE(o5_putActor),
- OPCODE(o5_startMusic),
- OPCODE(o5_getActorRoom),
- /* 04 */
- OPCODE(o5_isGreaterEqual),
- OPCODE(o5_drawObject),
- OPCODE(o5_getActorElevation),
- OPCODE(o5_setState),
- /* 08 */
- OPCODE(o5_isNotEqual),
- OPCODE(o5_faceActor),
- OPCODE(o5_startScript),
- OPCODE(o5_getVerbEntrypoint),
- /* 0C */
- OPCODE(o5_resourceRoutines),
- OPCODE(o5_walkActorToActor),
- OPCODE(o5_putActorAtObject),
- OPCODE(o5_getObjectState),
- /* 10 */
- OPCODE(o5_getObjectOwner),
- OPCODE(o5_animateActor),
- OPCODE(o5_panCameraTo),
- OPCODE(o5_actorOps),
- /* 14 */
- OPCODE(o5_print),
- OPCODE(o5_actorFromPos),
- OPCODE(o5_getRandomNr),
- OPCODE(o5_and),
- /* 18 */
- OPCODE(o5_jumpRelative),
- OPCODE(o5_doSentence),
- OPCODE(o5_move),
- OPCODE(o5_multiply),
- /* 1C */
- OPCODE(o5_startSound),
- OPCODE(o5_ifClassOfIs),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_isActorInBox),
- /* 20 */
- OPCODE(o5_stopMusic),
- OPCODE(o5_putActor),
- OPCODE(o5_getAnimCounter),
- OPCODE(o5_getActorY),
- /* 24 */
- OPCODE(o5_loadRoomWithEgo),
- OPCODE(o5_pickupObject),
- OPCODE(o5_setVarRange),
- OPCODE(o5_stringOps),
- /* 28 */
- OPCODE(o5_equalZero),
- OPCODE(o5_setOwnerOf),
- OPCODE(o5_startScript),
- OPCODE(o5_delayVariable),
- /* 2C */
- OPCODE(o5_cursorCommand),
- OPCODE(o5_putActorInRoom),
- OPCODE(o5_delay),
- OPCODE(o5_ifNotState),
- /* 30 */
- OPCODE(o5_matrixOps),
- OPCODE(o5_getInventoryCount),
- OPCODE(o5_setCameraAt),
- OPCODE(o5_roomOps),
- /* 34 */
- OPCODE(o5_getDist),
- OPCODE(o5_findObject),
- OPCODE(o5_walkActorToObject),
- OPCODE(o5_startObject),
- /* 38 */
- OPCODE(o5_lessOrEqual),
- OPCODE(o5_doSentence),
- OPCODE(o5_subtract),
- OPCODE(o5_getActorScale),
- /* 3C */
- OPCODE(o5_stopSound),
- OPCODE(o5_findInventory),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_drawBox),
- /* 40 */
- OPCODE(o5_cutscene),
- OPCODE(o5_putActor),
- OPCODE(o5_chainScript),
- OPCODE(o5_getActorX),
- /* 44 */
- OPCODE(o5_isLess),
- OPCODE(o5_drawObject),
- OPCODE(o5_increment),
- OPCODE(o5_setState),
- /* 48 */
- OPCODE(o5_isEqual),
- OPCODE(o5_faceActor),
- OPCODE(o5_startScript),
- OPCODE(o5_getVerbEntrypoint),
- /* 4C */
- OPCODE(o5_soundKludge),
- OPCODE(o5_walkActorToActor),
- OPCODE(o5_putActorAtObject),
- OPCODE(o5_ifState),
- /* 50 */
- OPCODE(o5_pickupObjectOld),
- OPCODE(o5_animateActor),
- OPCODE(o5_actorFollowCamera),
- OPCODE(o5_actorOps),
- /* 54 */
- OPCODE(o5_setObjectName),
- OPCODE(o5_actorFromPos),
- OPCODE(o5_getActorMoving),
- OPCODE(o5_or),
- /* 58 */
- OPCODE(o5_beginOverride),
- OPCODE(o5_doSentence),
- OPCODE(o5_add),
- OPCODE(o5_divide),
- /* 5C */
- OPCODE(o5_oldRoomEffect),
- OPCODE(o5_setClass),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_isActorInBox),
- /* 60 */
- OPCODE(o5_freezeScripts),
- OPCODE(o5_putActor),
- OPCODE(o5_stopScript),
- OPCODE(o5_getActorFacing),
- /* 64 */
- OPCODE(o5_loadRoomWithEgo),
- OPCODE(o5_pickupObject),
- OPCODE(o5_getClosestObjActor),
- OPCODE(o5_getStringWidth),
- /* 68 */
- OPCODE(o5_isScriptRunning),
- OPCODE(o5_setOwnerOf),
- OPCODE(o5_startScript),
- OPCODE(o5_debug),
- /* 6C */
- OPCODE(o5_getActorWidth),
- OPCODE(o5_putActorInRoom),
- OPCODE(o5_stopObjectScript),
- OPCODE(o5_ifNotState),
- /* 70 */
- OPCODE(o5_lights),
- OPCODE(o5_getActorCostume),
- OPCODE(o5_loadRoom),
- OPCODE(o5_roomOps),
- /* 74 */
- OPCODE(o5_getDist),
- OPCODE(o5_findObject),
- OPCODE(o5_walkActorToObject),
- OPCODE(o5_startObject),
- /* 78 */
- OPCODE(o5_isGreater),
- OPCODE(o5_doSentence),
- OPCODE(o5_verbOps),
- OPCODE(o5_getActorWalkBox),
- /* 7C */
- OPCODE(o5_isSoundRunning),
- OPCODE(o5_findInventory),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_drawBox),
- /* 80 */
- OPCODE(o5_breakHere),
- OPCODE(o5_putActor),
- OPCODE(o5_startMusic),
- OPCODE(o5_getActorRoom),
- /* 84 */
- OPCODE(o5_isGreaterEqual),
- OPCODE(o5_drawObject),
- OPCODE(o5_getActorElevation),
- OPCODE(o5_setState),
- /* 88 */
- OPCODE(o5_isNotEqual),
- OPCODE(o5_faceActor),
- OPCODE(o5_startScript),
- OPCODE(o5_getVerbEntrypoint),
- /* 8C */
- OPCODE(o5_resourceRoutines),
- OPCODE(o5_walkActorToActor),
- OPCODE(o5_putActorAtObject),
- OPCODE(o5_getObjectState),
- /* 90 */
- OPCODE(o5_getObjectOwner),
- OPCODE(o5_animateActor),
- OPCODE(o5_panCameraTo),
- OPCODE(o5_actorOps),
- /* 94 */
- OPCODE(o5_print),
- OPCODE(o5_actorFromPos),
- OPCODE(o5_getRandomNr),
- OPCODE(o5_and),
- /* 98 */
- OPCODE(o5_systemOps),
- OPCODE(o5_doSentence),
- OPCODE(o5_move),
- OPCODE(o5_multiply),
- /* 9C */
- OPCODE(o5_startSound),
- OPCODE(o5_ifClassOfIs),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_isActorInBox),
- /* A0 */
- OPCODE(o5_stopObjectCode),
- OPCODE(o5_putActor),
- OPCODE(o5_getAnimCounter),
- OPCODE(o5_getActorY),
- /* A4 */
- OPCODE(o5_loadRoomWithEgo),
- OPCODE(o5_pickupObject),
- OPCODE(o5_setVarRange),
- OPCODE(o5_saveLoadVars),
- /* A8 */
- OPCODE(o5_notEqualZero),
- OPCODE(o5_setOwnerOf),
- OPCODE(o5_startScript),
- OPCODE(o5_saveRestoreVerbs),
- /* AC */
- OPCODE(o5_expression),
- OPCODE(o5_putActorInRoom),
- OPCODE(o5_wait),
- OPCODE(o5_ifNotState),
- /* B0 */
- OPCODE(o5_matrixOps),
- OPCODE(o5_getInventoryCount),
- OPCODE(o5_setCameraAt),
- OPCODE(o5_roomOps),
- /* B4 */
- OPCODE(o5_getDist),
- OPCODE(o5_findObject),
- OPCODE(o5_walkActorToObject),
- OPCODE(o5_startObject),
- /* B8 */
- OPCODE(o5_lessOrEqual),
- OPCODE(o5_doSentence),
- OPCODE(o5_subtract),
- OPCODE(o5_getActorScale),
- /* BC */
- OPCODE(o5_stopSound),
- OPCODE(o5_findInventory),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_drawBox),
- /* C0 */
- OPCODE(o5_endCutscene),
- OPCODE(o5_putActor),
- OPCODE(o5_chainScript),
- OPCODE(o5_getActorX),
- /* C4 */
- OPCODE(o5_isLess),
- OPCODE(o5_drawObject),
- OPCODE(o5_decrement),
- OPCODE(o5_setState),
- /* C8 */
- OPCODE(o5_isEqual),
- OPCODE(o5_faceActor),
- OPCODE(o5_startScript),
- OPCODE(o5_getVerbEntrypoint),
- /* CC */
- OPCODE(o5_pseudoRoom),
- OPCODE(o5_walkActorToActor),
- OPCODE(o5_putActorAtObject),
- OPCODE(o5_ifState),
- /* D0 */
- OPCODE(o5_pickupObjectOld),
- OPCODE(o5_animateActor),
- OPCODE(o5_actorFollowCamera),
- OPCODE(o5_actorOps),
- /* D4 */
- OPCODE(o5_setObjectName),
- OPCODE(o5_actorFromPos),
- OPCODE(o5_getActorMoving),
- OPCODE(o5_or),
- /* D8 */
- OPCODE(o5_printEgo),
- OPCODE(o5_doSentence),
- OPCODE(o5_add),
- OPCODE(o5_divide),
- /* DC */
- OPCODE(o5_oldRoomEffect),
- OPCODE(o5_setClass),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_isActorInBox),
- /* E0 */
- OPCODE(o5_freezeScripts),
- OPCODE(o5_putActor),
- OPCODE(o5_stopScript),
- OPCODE(o5_getActorFacing),
- /* E4 */
- OPCODE(o5_loadRoomWithEgo),
- OPCODE(o5_pickupObject),
- OPCODE(o5_getClosestObjActor),
- OPCODE(o5_getStringWidth),
- /* E8 */
- OPCODE(o5_isScriptRunning),
- OPCODE(o5_setOwnerOf),
- OPCODE(o5_startScript),
- OPCODE(o5_debug),
- /* EC */
- OPCODE(o5_getActorWidth),
- OPCODE(o5_putActorInRoom),
- OPCODE(o5_stopObjectScript),
- OPCODE(o5_ifNotState),
- /* F0 */
- OPCODE(o5_lights),
- OPCODE(o5_getActorCostume),
- OPCODE(o5_loadRoom),
- OPCODE(o5_roomOps),
- /* F4 */
- OPCODE(o5_getDist),
- OPCODE(o5_findObject),
- OPCODE(o5_walkActorToObject),
- OPCODE(o5_startObject),
- /* F8 */
- OPCODE(o5_isGreater),
- OPCODE(o5_doSentence),
- OPCODE(o5_verbOps),
- OPCODE(o5_getActorWalkBox),
- /* FC */
- OPCODE(o5_isSoundRunning),
- OPCODE(o5_findInventory),
- OPCODE(o5_walkActorTo),
- OPCODE(o5_drawBox)
- };
-
- _opcodesV5 = opcodes;
-}
-
-#define PARAM_1 0x80
-#define PARAM_2 0x40
-#define PARAM_3 0x20
-
-void ScummEngine_v5::executeOpcode(byte i) {
- OpcodeProcV5 op = _opcodesV5[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v5::getOpcodeDesc(byte i) {
- return _opcodesV5[i].desc;
-}
-
-int ScummEngine_v5::getVar() {
- return readVar(fetchScriptWord());
-}
-
-int ScummEngine_v5::getVarOrDirectByte(byte mask) {
- if (_opcode & mask)
- return getVar();
- return fetchScriptByte();
-}
-
-int ScummEngine_v5::getVarOrDirectWord(byte mask) {
- if (_opcode & mask)
- return getVar();
- return (int16)fetchScriptWord();
-}
-
-void ScummEngine_v5::o5_actorFollowCamera() {
- actorFollowCamera(getVarOrDirectByte(0x80));
-}
-
-void ScummEngine_v5::o5_actorFromPos() {
- int x, y;
- getResultPos();
- x = getVarOrDirectWord(PARAM_1);
- y = getVarOrDirectWord(PARAM_2);
- setResult(getActorFromPos(x, y));
-}
-
-void ScummEngine_v5::o5_actorOps() {
- static const byte convertTable[20] =
- { 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20 };
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_actorOps");
- int i, j;
-
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- if (_features & GF_SMALL_HEADER)
- _opcode = (_opcode & 0xE0) | convertTable[(_opcode & 0x1F) - 1];
-
- switch (_opcode & 0x1F) {
- case 0: /* dummy case */
- getVarOrDirectByte(PARAM_1);
- break;
- case 1: // SO_COSTUME
- a->setActorCostume(getVarOrDirectByte(PARAM_1));
- break;
- case 2: // SO_STEP_DIST
- i = getVarOrDirectByte(PARAM_1);
- j = getVarOrDirectByte(PARAM_2);
- a->setActorWalkSpeed(i, j);
- break;
- case 3: // SO_SOUND
- a->_sound[0] = getVarOrDirectByte(PARAM_1);
- break;
- case 4: // SO_WALK_ANIMATION
- a->_walkFrame = getVarOrDirectByte(PARAM_1);
- break;
- case 5: // SO_TALK_ANIMATION
- a->_talkStartFrame = getVarOrDirectByte(PARAM_1);
- a->_talkStopFrame = getVarOrDirectByte(PARAM_2);
- break;
- case 6: // SO_STAND_ANIMATION
- a->_standFrame = getVarOrDirectByte(PARAM_1);
- break;
- case 7: // SO_ANIMATION
- getVarOrDirectByte(PARAM_1);
- getVarOrDirectByte(PARAM_2);
- getVarOrDirectByte(PARAM_3);
- break;
- case 8: // SO_DEFAULT
- a->initActor(0);
- break;
- case 9: // SO_ELEVATION
- a->setElevation(getVarOrDirectWord(PARAM_1));
- break;
- case 10: // SO_ANIMATION_DEFAULT
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 11: // SO_PALETTE
- i = getVarOrDirectByte(PARAM_1);
- j = getVarOrDirectByte(PARAM_2);
- checkRange(31, 0, i, "Illegal palette slot %d");
- a->setPalette(i, j);
- break;
- case 12: // SO_TALK_COLOR
-
- // Zak256 (and possibly other games) uses actor 0 to
- // indicate that it's the default talk color that is
- // to be changed.
-
- if (act == 0)
- _string[0].color = getVarOrDirectByte(PARAM_1);
- else
- a->_talkColor = getVarOrDirectByte(PARAM_1);
- break;
- case 13: // SO_ACTOR_NAME
- loadPtrToResource(rtActorName, a->_number, NULL);
- break;
- case 14: // SO_INIT_ANIMATION
- a->_initFrame = getVarOrDirectByte(PARAM_1);
- break;
- case 15: // SO_PALETTE_LIST
- error("o5_actorOps:unk not implemented");
-#if 0
- int args[16] =
- {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- };
- getWordVararg(args);
- for (i = 0; i < 16; i++)
- if (args[i] != 0xFF)
- a->_palette[i] = args[i];
-#endif
- break;
- case 16: // SO_ACTOR_WIDTH
- a->_width = getVarOrDirectByte(PARAM_1);
- break;
- case 17: // SO_ACTOR_SCALE
- if (_version == 4) {
- i = j = getVarOrDirectByte(PARAM_1);
- } else {
- i = getVarOrDirectByte(PARAM_1);
- j = getVarOrDirectByte(PARAM_2);
- }
-
- a->_boxscale = i;
- a->setScale(i, j);
- break;
- case 18: // SO_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 19: // SO_ALWAYS_ZCLIP
- a->_forceClip = getVarOrDirectByte(PARAM_1);
- break;
- case 20: // SO_IGNORE_BOXES
- case 21: // SO_FOLLOW_BOXES
- a->_ignoreBoxes = !(_opcode & 1);
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
-
- case 22: // SO_ANIMATION_SPEED
- a->setAnimSpeed(getVarOrDirectByte(PARAM_1));
- break;
- case 23: // SO_SHADOW
- a->_shadowMode = getVarOrDirectByte(PARAM_1);
- break;
- default:
- error("o5_actorOps: default case %d", _opcode & 0x1F);
- }
- }
-}
-
-void ScummEngine_v5::o5_setClass() {
- int obj = getVarOrDirectWord(PARAM_1);
- int newClass;
-
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- newClass = getVarOrDirectWord(PARAM_1);
- if (newClass == 0) {
- // Class '0' means: clean all class data
- _classData[obj] = 0;
- if ((_features & GF_SMALL_HEADER) && obj <= _numActors) {
- Actor *a = derefActor(obj, "o5_setClass");
- a->_ignoreBoxes = false;
- a->_forceClip = 0;
- }
- } else
- putClass(obj, newClass, (newClass & 0x80) ? true : false);
- }
-}
-
-void ScummEngine_v5::o5_add() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
-
- // WORKAROUND bug #770065: This works around a script bug in LoomCD. To
- // understand the reasoning behind this, compare script 210 and 218 in
- // room 20. Apparently they made a mistake when converting the absolute
- // delays into relative ones.
- if (_gameId == GID_LOOM && _version == 4 && vm.slot[_currentScript].number == 210 && _currentRoom == 20 && _resultVarNumber == 0x4000) {
- switch (a) {
- // Fix for the Var[250] == 11 case
- case 138:
- a = 145;
- break;
- case 324:
- a = 324 - 138;
- break;
- // Fixes for the Var[250] == 14 case
- case 130:
- a = 170;
- break;
- case 342:
- a = 342 - 130 + 15; // Small extra adjustment for the "OUCH"
- break;
- case 384:
- a -= 342;
- break;
- case 564:
- a -= 384;
- break;
- }
- }
-
- setResult(readVar(_resultVarNumber) + a);
-}
-
-void ScummEngine_v5::o5_and() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- setResult(readVar(_resultVarNumber) & a);
-}
-
-void ScummEngine_v5::o5_animateActor() {
- int act = getVarOrDirectByte(PARAM_1);
- int anim = getVarOrDirectByte(PARAM_2);
-
- // WORKAROUND bug #820357: This seems to be yet another script bug which
- // the original engine let slip by. For details, refer to the tracker item.
- if (_gameId == GID_INDY4 && vm.slot[_currentScript].number == 206 && _currentRoom == 17 && (act == 31 || act == 86)) {
- return;
- }
-
- Actor *a = derefActor(act, "o5_animateActor");
- a->animateActor(anim);
-}
-
-void ScummEngine_v5::o5_breakHere() {
- updateScriptPtr();
- _currentScript = 0xFF;
-}
-
-void ScummEngine_v5::o5_chainScript() {
- int vars[16];
- int script;
- int cur;
-
- script = getVarOrDirectByte(PARAM_1);
-
- getWordVararg(vars);
-
- cur = _currentScript;
-
- // WORKAROUND bug #743314: Work around a bug in script 33 in Indy3 VGA.
- // That script is used for the fist fights in the Zeppelin. It uses
- // Local[5], even though that is never set to any value. But script 33 is
- // called via chainScript by script 32, and in there Local[5] is defined
- // to the actor ID of the opposing soldier. So, we copy that value over
- // to the Local[5] variable of script 33.
- if (_gameId == GID_INDY3 && vm.slot[cur].number == 32 && script == 33) {
- vars[5] = vm.localvar[cur][5];
- }
-
- vm.slot[cur].number = 0;
- vm.slot[cur].status = ssDead;
- _currentScript = 0xFF;
-
- runScript(script, vm.slot[cur].freezeResistant, vm.slot[cur].recursive, vars);
-}
-
-void ScummEngine_v5::o5_cursorCommand() {
- int i, j, k;
- int table[16];
- switch ((_opcode = fetchScriptByte()) & 0x1F) {
- case 1: // SO_CURSOR_ON
- _cursor.state = 1;
- verbMouseOver(0);
- break;
- case 2: // SO_CURSOR_OFF
- _cursor.state = 0;
- verbMouseOver(0);
- break;
- case 3: // SO_USERPUT_ON
- _userPut = 1;
- break;
- case 4: // SO_USERPUT_OFF
- _userPut = 0;
- break;
- case 5: // SO_CURSOR_SOFT_ON
- _cursor.state++;
- verbMouseOver(0);
- break;
- case 6: // SO_CURSOR_SOFT_OFF
- _cursor.state--;
- verbMouseOver(0);
- break;
- case 7: // SO_USERPUT_SOFT_ON
- _userPut++;
- break;
- case 8: // SO_USERPUT_SOFT_OFF
- _userPut--;
- break;
- case 10: // SO_CURSOR_IMAGE
- i = getVarOrDirectByte(PARAM_1); // Cursor number
- j = getVarOrDirectByte(PARAM_2); // Charset letter to use
- redefineBuiltinCursorFromChar(i, j);
- break;
- case 11: // SO_CURSOR_HOTSPOT
- i = getVarOrDirectByte(PARAM_1);
- j = getVarOrDirectByte(PARAM_2);
- k = getVarOrDirectByte(PARAM_3);
- redefineBuiltinCursorHotspot(i, j, k);
- break;
- case 12: // SO_CURSOR_SET
- i = getVarOrDirectByte(PARAM_1);
- if (i >= 0 && i <= 3)
- _currentCursor = i;
- else
- error("SO_CURSOR_SET: unsupported cursor id %d", i);
- break;
- case 13: // SO_CHARSET_SET
- initCharset(getVarOrDirectByte(PARAM_1));
- break;
- case 14: /* unk */
- if (_version == 3) {
- /*int a = */ getVarOrDirectByte(PARAM_1);
- /*int b = */ getVarOrDirectByte(PARAM_2);
- // This is some kind of "init charset" opcode. However, we don't have to do anything
- // in here, as our initCharset automatically calls loadCharset for GF_SMALL_HEADER,
- // games if needed.
- } else {
- getWordVararg(table);
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)table[i];
- }
- break;
- }
-
- if (_version >= 4) {
- VAR(VAR_CURSORSTATE) = _cursor.state;
- VAR(VAR_USERPUT) = _userPut;
- }
-}
-
-void ScummEngine_v5::o5_cutscene() {
- int args[16];
- getWordVararg(args);
- beginCutscene(args);
-}
-
-void ScummEngine_v5::o5_endCutscene() {
- endCutscene();
-}
-
-void ScummEngine_v5::o5_debug() {
- int a = getVarOrDirectWord(PARAM_1);
- debugC(DEBUG_GENERAL, "o5_debug(%d)", a);
-}
-
-void ScummEngine_v5::o5_decrement() {
- getResultPos();
- setResult(readVar(_resultVarNumber) - 1);
-}
-
-void ScummEngine_v5::o5_delay() {
- int delay = fetchScriptByte();
- delay |= fetchScriptByte() << 8;
- delay |= fetchScriptByte() << 16;
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = ssPaused;
- o5_breakHere();
-}
-
-void ScummEngine_v5::o5_delayVariable() {
- vm.slot[_currentScript].delay = getVar();
- vm.slot[_currentScript].status = ssPaused;
- o5_breakHere();
-}
-
-void ScummEngine_v5::o5_divide() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- if (a == 0) {
- error("Divide by zero");
- setResult(0);
- } else
- setResult(readVar(_resultVarNumber) / a);
-}
-
-void ScummEngine_v5::o5_doSentence() {
- int verb;
- SentenceTab *st;
-
- verb = getVarOrDirectByte(PARAM_1);
- if (verb == 0xFE) {
- _sentenceNum = 0;
- stopScript(VAR(VAR_SENTENCE_SCRIPT));
- clearClickedStatus();
- return;
- }
-
- st = &_sentence[_sentenceNum++];
-
- st->verb = verb;
- st->objectA = getVarOrDirectWord(PARAM_2);
- st->objectB = getVarOrDirectWord(PARAM_3);
- st->preposition = (st->objectB != 0);
- st->freezeCount = 0;
-}
-
-void ScummEngine_v5::o5_drawBox() {
- int x, y, x2, y2, color;
-
- x = getVarOrDirectWord(PARAM_1);
- y = getVarOrDirectWord(PARAM_2);
-
- _opcode = fetchScriptByte();
- x2 = getVarOrDirectWord(PARAM_1);
- y2 = getVarOrDirectWord(PARAM_2);
- color = getVarOrDirectByte(PARAM_3);
-
- drawBox(x, y, x2, y2, color);
-}
-
-void ScummEngine_v5::o5_drawObject() {
- int state, obj, idx, i;
- ObjectData *od;
- uint16 x, y, w, h;
- int xpos, ypos;
-
- state = 1;
- xpos = ypos = 255;
- obj = getVarOrDirectWord(PARAM_1);
-
- if (_features & GF_SMALL_HEADER) {
- xpos = getVarOrDirectWord(PARAM_2);
- ypos = getVarOrDirectWord(PARAM_3);
- } else {
- _opcode = fetchScriptByte();
- switch (_opcode & 0x1F) {
- case 1: /* draw at */
- xpos = getVarOrDirectWord(PARAM_1);
- ypos = getVarOrDirectWord(PARAM_2);
- break;
- case 2: /* set state */
- state = getVarOrDirectWord(PARAM_1);
- break;
- case 0x1F: /* neither */
- break;
- default:
- error("o5_drawObject: unknown subopcode %d", _opcode & 0x1F);
- }
- }
-
- idx = getObjectIndex(obj);
- if (idx == -1)
- return;
-
- od = &_objs[idx];
- if (xpos != 0xFF) {
- od->walk_x += (xpos * 8) - od->x_pos;
- od->x_pos = xpos * 8;
- od->walk_y += (ypos * 8) - od->y_pos;
- od->y_pos = ypos * 8;
- }
- addObjectToDrawQue(idx);
-
- x = od->x_pos;
- y = od->y_pos;
- w = od->width;
- h = od->height;
-
- i = _numLocalObjects - 1;
- do {
- if (_objs[i].obj_nr && _objs[i].x_pos == x && _objs[i].y_pos == y && _objs[i].width == w && _objs[i].height == h)
- putState(_objs[i].obj_nr, 0);
- } while (--i);
-
- putState(obj, state);
-}
-
-void ScummEngine_v5::o5_getStringWidth() {
- int string, width = 0;
- byte *ptr;
-
- getResultPos();
- string = getVarOrDirectByte(PARAM_1);
- ptr = getResourceAddress(rtString, string);
- assert(ptr);
-
- width = _charset->getStringWidth(0, ptr);
-
- setResult(width);
- debug(0, "o5_getStringWidth, result %d", width);
-}
-
-void ScummEngine_v5::o5_saveLoadVars() {
- if (fetchScriptByte() == 1)
- saveVars();
- else
- loadVars();
-}
-
-void ScummEngine_v5::saveVars() {
- int a, b;
-
- while ((_opcode = fetchScriptByte()) != 0) {
- switch (_opcode & 0x1F) {
- case 0x01: // write a range of variables
- getResultPos();
- a = _resultVarNumber;
- getResultPos();
- b = _resultVarNumber;
- debug(0, "stub saveVars: vars %d -> %d", a, b);
- break;
- case 0x02: // write a range of string variables
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- debug(0, "stub saveVars: strings %d -> %d", a, b);
- break;
- case 0x03: // open file
- a = resStrLen(_scriptPointer);
- debug(0, "stub saveVars to %s", _scriptPointer);
- _scriptPointer += a + 1;
- break;
- case 0x04:
- return;
- break;
- case 0x1F: // close file
- debug(0, "stub saveVars close file");
- return;
- break;
- }
- }
-}
-
-void ScummEngine_v5::loadVars() {
- int a, b;
-
-// Common::hexdump(_scriptPointer, 64);
- while ((_opcode = fetchScriptByte()) != 0) {
- switch (_opcode & 0x1F) {
- case 0x01: // read a range of variables
- getResultPos();
- a = _resultVarNumber;
- getResultPos();
- b = _resultVarNumber;
- debug(0, "stub loadVars: vars %d -> %d", a, b);
- break;
- case 0x02: // read a range of string variables
- a = getVarOrDirectByte(0x80);
- b = getVarOrDirectByte(0x40);
- debug(0, "stub loadVars: strings %d -> %d", a, b);
- break;
- case 0x03: // open file
- a = resStrLen(_scriptPointer);
- debug(0, "stub loadVars from %s", _scriptPointer);
- _scriptPointer += a + 1;
- break;
- case 0x04:
- return;
- break;
- case 0x1F: // close file
- debug(0, "stub loadVars close file");
- return;
- break;
- }
- }
-}
-
-void ScummEngine_v5::o5_expression() {
- int dst, i;
-
- _scummStackPos = 0;
- getResultPos();
- dst = _resultVarNumber;
-
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- switch (_opcode & 0x1F) {
- case 1: /* varordirect */
- push(getVarOrDirectWord(PARAM_1));
- break;
- case 2: /* add */
- i = pop();
- push(i + pop());
- break;
- case 3: /* sub */
- i = pop();
- push(pop() - i);
- break;
- case 4: /* mul */
- i = pop();
- push(i * pop());
- break;
- case 5: /* div */
- i = pop();
- if (i == 0)
- error("Divide by zero");
- push(pop() / i);
- break;
- case 6: /* normal opcode */
- _opcode = fetchScriptByte();
- executeOpcode(_opcode);
- push(_scummVars[0]);
- break;
- }
- }
-
- _resultVarNumber = dst;
- setResult(pop());
-}
-
-void ScummEngine_v5::o5_faceActor() {
- int act = getVarOrDirectByte(PARAM_1);
- int obj = getVarOrDirectWord(PARAM_2);
- Actor *a = derefActor(act, "o5_faceActor");
- a->faceToObject(obj);
-}
-
-void ScummEngine_v5::o5_findInventory() {
- getResultPos();
- int x = getVarOrDirectByte(PARAM_1);
- int y = getVarOrDirectByte(PARAM_2);
- setResult(findInventory(x, y));
-}
-
-void ScummEngine_v5::o5_findObject() {
- getResultPos();
- int x = getVarOrDirectByte(PARAM_1);
- int y = getVarOrDirectByte(PARAM_2);
- setResult(findObject(x, y));
-}
-
-void ScummEngine_v5::o5_freezeScripts() {
- int scr = getVarOrDirectByte(PARAM_1);
-
- if (scr != 0)
- freezeScripts(scr);
- else
- unfreezeScripts();
-}
-
-void ScummEngine_v5::o5_getActorCostume() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getActorCostume");
- setResult(a->_costume);
-}
-
-void ScummEngine_v5::o5_getActorElevation() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getActorElevation");
- setResult(a->getElevation());
-}
-
-void ScummEngine_v5::o5_getActorFacing() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getActorFacing");
- setResult(newDirToOldDir(a->getFacing()));
-}
-
-void ScummEngine_v5::o5_getActorMoving() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getActorMoving");
- setResult(a->_moving);
-}
-
-void ScummEngine_v5::o5_getActorRoom() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- // WORKAROUND bug #746349. This is a really odd bug in either the script
- // or in our script engine. Might be a good idea to investigate this
- // further by e.g. looking at the FOA engine a bit closer.
- if (_gameId == GID_INDY4 && _roomResource == 94 && vm.slot[_currentScript].number == 206 && !isValidActor(act)) {
- setResult(0);
- return;
- }
-
- Actor *a = derefActor(act, "o5_getActorRoom");
- setResult(a->_room);
-}
-
-void ScummEngine_v5::o5_getActorScale() {
- Actor *a;
-
- // INDY3 uses this opcode for waitForActor
- if (_gameId == GID_INDY3) {
- const byte *oldaddr = _scriptPointer - 1;
- a = derefActor(getVarOrDirectByte(PARAM_1), "o5_getActorScale (wait)");
- if (a->_moving) {
- _scriptPointer = oldaddr;
- o5_breakHere();
- }
- return;
- }
-
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- a = derefActor(act, "o5_getActorScale");
- setResult(a->_scalex);
-}
-
-void ScummEngine_v5::o5_getActorWalkBox() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getActorWalkBox");
- setResult(a->_walkbox);
-}
-
-void ScummEngine_v5::o5_getActorWidth() {
- getResultPos();
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getActorWidth");
- setResult(a->_width);
-}
-
-void ScummEngine_v5::o5_getActorX() {
- int a;
- getResultPos();
-
- if ((_gameId == GID_INDY3) && !(_platform == Common::kPlatformMacintosh))
- a = getVarOrDirectByte(PARAM_1);
- else
- a = getVarOrDirectWord(PARAM_1);
-
- setResult(getObjX(a));
-}
-
-void ScummEngine_v5::o5_getActorY() {
- int a;
- getResultPos();
-
- if ((_gameId == GID_INDY3) && !(_platform == Common::kPlatformMacintosh)) {
- a = getVarOrDirectByte(PARAM_1);
-
- // WORKAROUND bug #636433 (can't get into Zeppelin)
- if (_roomResource == 36) {
- setResult(getObjY(a) - 1);
- return;
- }
- } else
- a = getVarOrDirectWord(PARAM_1);
-
- setResult(getObjY(a));
-}
-
-void ScummEngine_v5::o5_saveLoadGame() {
- getResultPos();
- byte a = getVarOrDirectByte(PARAM_1);
- byte slot = (a & 0x1F) + 1;
- byte result = 0;
-
- if ((_gameId == GID_MANIAC) && (_version == 1)) {
- // Convert older load/save screen
- // 1 Load
- // 2 Save
- slot = 1;
- if (a == 1)
- _opcode = 0x40;
- else if ((a == 2) || (_platform == Common::kPlatformNES))
- _opcode = 0x80;
- } else {
- _opcode = a & 0xE0;
- }
-
- switch (_opcode) {
- case 0x00: // num slots available
- result = 100;
- break;
- case 0x20: // drive
- if (_gameId == GID_INDY3) {
- // 0 = hard drive
- // 1 = disk drive
- result = 0;
- } else {
- // set current drive
- result = 1;
- }
- break;
- case 0x40: // load
- if (loadState(slot, _saveTemporaryState))
- result = 3; // sucess
- else
- result = 5; // failed to load
- break;
- case 0x80: // save
- if (saveState(slot, _saveTemporaryState))
- result = 0;
- else
- result = 2;
- break;
- case 0xC0: // test if save exists
- bool avail_saves[100];
- char filename[256];
-
- listSavegames(avail_saves, ARRAYSIZE(avail_saves));
- makeSavegameName(filename, slot, false);
- if (avail_saves[slot] && (_saveFileMan->openForLoading(filename)))
- result = 6; // save file exists
- else
- result = 7; // save file does not exist
- break;
- default:
- error("o5_saveLoadGame: unknown subopcode %d", _opcode);
- }
-
- setResult(result);
-}
-
-void ScummEngine_v5::o5_getAnimCounter() {
- if (_version == 3) {
- o5_saveLoadGame();
- return;
- }
-
- getResultPos();
-
- int act = getVarOrDirectByte(PARAM_1);
- Actor *a = derefActor(act, "o5_getAnimCounter");
- setResult(a->_cost.animCounter);
-}
-
-void ScummEngine_v5::o5_getClosestObjActor() {
- int obj;
- int act;
- int dist;
-
- // This code can't detect any actors farther away than 255 units
- // (pixels in newer games, characters in older ones.) But this is
- // perfectly OK, as it is exactly how the original behaved.
-
- int closest_obj = 0xFF, closest_dist = 0xFF;
-
- getResultPos();
-
- act = getVarOrDirectWord(PARAM_1);
- obj = VAR(VAR_ACTOR_RANGE_MAX);
-
- do {
- dist = getObjActToObjActDist(act, obj);
- if (dist < closest_dist) {
- closest_dist = dist;
- closest_obj = obj;
- }
- } while (--obj >= VAR(VAR_ACTOR_RANGE_MIN));
-
- setResult(closest_obj);
-}
-
-void ScummEngine_v5::o5_getDist() {
- int o1, o2;
- int r;
- getResultPos();
- o1 = getVarOrDirectWord(PARAM_1);
- o2 = getVarOrDirectWord(PARAM_2);
- r = getObjActToObjActDist(o1, o2);
-
- // FIXME: MI2 race workaround, see bug #597022. We never quite figured out
- // what the real cause of this, or if it maybe occurs in the original, too...
- if (_gameId == GID_MONKEY2 && vm.slot[_currentScript].number == 40 && r < 60)
- r = 60;
-
- // WORKAROUND bug #795937
- if ((_gameId == GID_MONKEY_EGA || _gameId == GID_PASS) && o1 == 1 && o2 == 307 && vm.slot[_currentScript].number == 205 && r == 2)
- r = 3;
-
- setResult(r);
-}
-
-void ScummEngine_v5::o5_getInventoryCount() {
- getResultPos();
- setResult(getInventoryCount(getVarOrDirectByte(PARAM_1)));
-}
-
-void ScummEngine_v5::o5_getObjectOwner() {
- getResultPos();
- setResult(getOwner(getVarOrDirectWord(PARAM_1)));
-}
-
-void ScummEngine_v5::o5_getObjectState() {
- if (_features & GF_SMALL_HEADER) {
- o5_ifState();
- } else {
- getResultPos();
- setResult(getState(getVarOrDirectWord(PARAM_1)));
- }
-}
-
-void ScummEngine_v5::o5_ifState() {
- int a = getVarOrDirectWord(PARAM_1);
- int b = getVarOrDirectByte(PARAM_2);
-
- if (getState(a) != b)
- o5_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void ScummEngine_v5::o5_ifNotState() {
- int a = getVarOrDirectWord(PARAM_1);
- int b = getVarOrDirectByte(PARAM_2);
-
- if (getState(a) == b)
- o5_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void ScummEngine_v5::o5_getRandomNr() {
- getResultPos();
- setResult(_rnd.getRandomNumber(getVarOrDirectByte(PARAM_1)));
-}
-
-void ScummEngine_v5::o5_isScriptRunning() {
- getResultPos();
- setResult(isScriptRunning(getVarOrDirectByte(PARAM_1)));
-}
-
-void ScummEngine_v5::o5_getVerbEntrypoint() {
- int a, b;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
-
- setResult(getVerbEntrypoint(a, b));
-}
-
-void ScummEngine_v5::o5_ifClassOfIs() {
- int act, cls, b = 0;
- bool cond = true;
-
- act = getVarOrDirectWord(PARAM_1);
-
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- cls = getVarOrDirectWord(PARAM_1);
-
- if (!cls) // FIXME: Ender can't remember why this is here,
- b = false; // but it fixes an oddball zak256 crash
- else
- b = getClass(act, cls);
-
- if (cls & 0x80 && !b || !(cls & 0x80) && b)
- cond = false;
- }
- if (cond)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_increment() {
- getResultPos();
- setResult(readVar(_resultVarNumber) + 1);
-}
-
-void ScummEngine_v5::o5_isActorInBox() {
- int act = getVarOrDirectByte(PARAM_1);
- int box = getVarOrDirectByte(PARAM_2);
- Actor *a = derefActor(act, "o5_isActorInBox");
-
- if (!checkXYInBoxBounds(box, a->_pos.x, a->_pos.y))
- o5_jumpRelative();
- else
- ignoreScriptWord();
-}
-
-void ScummEngine_v5::o5_isEqual() {
- int16 a, b;
- int var;
-
- if (_version <= 2)
- var = fetchScriptByte();
- else
- var = fetchScriptWord();
- a = readVar(var);
- b = getVarOrDirectWord(PARAM_1);
-
- // HACK: See bug report #602348. The sound effects for Largo's screams
- // are only played on type 5 soundcards. However, there is at least one
- // other sound effect (the bartender spitting) which is only played on
- // type 3 soundcards.
-
- if (_gameId == GID_MONKEY2 && var == VAR_SOUNDCARD && b == 5)
- b = a;
-
- // HACK: To allow demo script of Maniac Mansion V2
- // The camera x position is only 100, instead of 180, after game title name scrolls.
- if (_gameId == GID_MANIAC && _version == 2 && _demoMode && isScriptRunning(173) && b == 180)
- b = 100;
-
- if (b == a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-
-}
-
-void ScummEngine_v5::o5_isGreater() {
- int16 a = getVar();
- int16 b = getVarOrDirectWord(PARAM_1);
- if (b > a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_isGreaterEqual() {
- int16 a = getVar();
- int16 b = getVarOrDirectWord(PARAM_1);
- if (b >= a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_isLess() {
- int16 a = getVar();
- int16 b = getVarOrDirectWord(PARAM_1);
- if (b < a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_lessOrEqual() {
- int16 a = getVar();
- int16 b = getVarOrDirectWord(PARAM_1);
-
- // WORKAROUND bug #820507 : Work around a bug in Indy3Town.
- if (_gameId == GID_INDY3 && (_platform == Common::kPlatformFMTowns) &&
- (vm.slot[_currentScript].number == 200 || vm.slot[_currentScript].number == 203) &&
- _currentRoom == 70 && b == -256) {
- o5_jumpRelative();
- return;
- }
-
- if (b <= a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_isNotEqual() {
- int16 a = getVar();
- int16 b = getVarOrDirectWord(PARAM_1);
- if (b != a)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_notEqualZero() {
- int a = getVar();
- if (a != 0)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_equalZero() {
- int a = getVar();
- if (a == 0)
- ignoreScriptWord();
- else
- o5_jumpRelative();
-}
-
-void ScummEngine_v5::o5_jumpRelative() {
- // Note that calling fetchScriptWord() will also modify _scriptPointer,
- // so *don't* do this: _scriptPointer += (int16)fetchScriptWord();
- //
- // I'm not enough of a language lawyer to say for certain that this is
- // undefined, but I do know that GCC 4.0 doesn't think it means what
- // we want it to mean.
-
- int16 offset = (int16)fetchScriptWord();
- _scriptPointer += offset;
-}
-
-void ScummEngine_v5::o5_lights() {
- int a, b, c;
-
- a = getVarOrDirectByte(PARAM_1);
- b = fetchScriptByte();
- c = fetchScriptByte();
-
- if (c == 0)
- VAR(VAR_CURRENT_LIGHTS) = a;
- else if (c == 1) {
- _flashlight.xStrips = a;
- _flashlight.yStrips = b;
- }
- _fullRedraw = true;
-}
-
-void ScummEngine_v5::o5_loadRoom() {
- int room;
-
- room = getVarOrDirectByte(PARAM_1);
-
- if (!_copyProtection) {
- // Skip copy protection scheme
- if (_gameId == GID_INDY3 && (_features & GF_OLD_BUNDLE) && room == 92) {
- VAR(57) = 1;
- return;
- }
- }
-
- // For small header games, we only call startScene if the room
- // actually changed. This avoid unwanted (wrong) fades in Zak256
- // and others. OTOH, it seems to cause a problem in newer games.
- if (!(_features & GF_SMALL_HEADER) || room != _currentRoom)
- startScene(room, 0, 0);
-
- _fullRedraw = true;
-}
-
-void ScummEngine_v5::o5_loadRoomWithEgo() {
- Actor *a;
- int obj, room, x, y;
- int x2, y2, dir, oldDir;
-
- obj = getVarOrDirectWord(PARAM_1);
- room = getVarOrDirectByte(PARAM_2);
-
- a = derefActor(VAR(VAR_EGO), "o5_loadRoomWithEgo");
-
- a->putActor(a->_pos.x, a->_pos.y, room);
- oldDir = a->getFacing();
- _egoPositioned = false;
-
- x = (int16)fetchScriptWord();
- y = (int16)fetchScriptWord();
-
- VAR(VAR_WALKTO_OBJ) = obj;
- startScene(a->_room, a, obj);
- VAR(VAR_WALKTO_OBJ) = 0;
-
- if (_version <= 4) {
- if (whereIsObject(obj) != WIO_ROOM)
- error("o5_loadRoomWithEgo: Object %d is not in room %d", obj, _currentRoom);
- if (!_egoPositioned) {
- getObjectXYPos(obj, x2, y2, dir);
- a->putActor(x2, y2, _currentRoom);
- if (a->getFacing() == oldDir)
- a->setDirection(dir + 180);
- }
- a->_moving = 0;
- }
-
- // This is based on disassembly
- camera._cur.x = camera._dest.x = a->_pos.x;
- setCameraFollows(a);
-
- _fullRedraw = true;
-
- if (x != -1) {
- a->startWalkActor(x, y, -1);
- }
-}
-
-void ScummEngine_v5::o5_matrixOps() {
- int a, b;
-
- if (_version == 3) {
- a = getVarOrDirectByte(PARAM_1);
- b = fetchScriptByte();
- setBoxFlags(a, b);
- return;
- }
-
- _opcode = fetchScriptByte();
- switch (_opcode & 0x1F) {
- case 1:
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- setBoxFlags(a, b);
- break;
- case 2:
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- setBoxScale(a, b);
- break;
- case 3:
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- setBoxScale(a, (b - 1) | 0x8000);
- break;
- case 4:
- createBoxMatrix();
- break;
- }
-}
-
-void ScummEngine_v5::o5_move() {
- getResultPos();
- setResult(getVarOrDirectWord(PARAM_1));
-}
-
-void ScummEngine_v5::o5_multiply() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- setResult(readVar(_resultVarNumber) * a);
-}
-
-void ScummEngine_v5::o5_or() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- setResult(readVar(_resultVarNumber) | a);
-}
-
-void ScummEngine_v5::o5_beginOverride() {
- if (fetchScriptByte() != 0)
- beginOverride();
- else
- endOverride();
-}
-
-void ScummEngine_v5::o5_panCameraTo() {
- panCameraTo(getVarOrDirectWord(PARAM_1), 0);
-}
-
-void ScummEngine_v5::o5_pickupObject() {
- int obj, room;
- if (_version == 3 || _version == 4) {
- o5_drawObject();
- return;
- }
-
- obj = getVarOrDirectWord(PARAM_1);
- room = getVarOrDirectByte(PARAM_2);
- if (room == 0)
- room = _roomResource;
- addObjectToInventory(obj, room);
- putOwner(obj, VAR(VAR_EGO));
- putClass(obj, kObjectClassUntouchable, 1);
- putState(obj, 1);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
- runInventoryScript(1);
-}
-
-void ScummEngine_v5::o5_print() {
- _actorToPrintStrFor = getVarOrDirectByte(PARAM_1);
- decodeParseString();
-}
-
-void ScummEngine_v5::o5_printEgo() {
- _actorToPrintStrFor = (byte)VAR(VAR_EGO);
- decodeParseString();
-}
-
-void ScummEngine_v5::o5_pseudoRoom() {
- int i = fetchScriptByte(), j;
- while ((j = fetchScriptByte()) != 0) {
- if (j >= 0x80) {
- _resourceMapper[j & 0x7F] = i;
- }
- }
-}
-
-void ScummEngine_v5::o5_putActor() {
- int x, y;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o5_putActor");
- x = getVarOrDirectWord(PARAM_2);
- y = getVarOrDirectWord(PARAM_3);
- a->putActor(x, y, a->_room);
-}
-
-void ScummEngine_v5::o5_putActorAtObject() {
- int obj, x, y;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o5_putActorAtObject");
- obj = getVarOrDirectWord(PARAM_2);
- if (whereIsObject(obj) != WIO_NOT_FOUND)
- getObjectXYPos(obj, x, y);
- else {
- x = 240;
- y = 120;
- }
- a->putActor(x, y, a->_room);
-}
-
-void ScummEngine_v5::o5_putActorInRoom() {
- Actor *a;
- int act = getVarOrDirectByte(PARAM_1);
- int room = getVarOrDirectByte(PARAM_2);
-
- a = derefActor(act, "o5_putActorInRoom");
-
- if (a->_visible && _currentRoom != room && getTalkingActor() == a->_number) {
- stopTalk();
- }
- a->_room = room;
- if (!room)
- a->putActor(0, 0, 0);
-}
-
-void ScummEngine_v5::o5_systemOps() {
- byte subOp = fetchScriptByte();
- switch (subOp) {
- case 1: // SO_RESTART
- restart();
- break;
- case 2: // SO_PAUSE
- pauseGame();
- break;
- case 3: // SO_QUIT
- shutDown();
- break;
- default:
- error("o5_systemOps: unknown subopcode %d", subOp);
- }
-}
-
-void ScummEngine_v5::o5_resourceRoutines() {
- const ResTypes resType[4] = { rtScript, rtSound, rtCostume, rtRoom };
- int resid = 0;
- int foo, bar;
-
- _opcode = fetchScriptByte();
- if (_opcode != 17)
- resid = getVarOrDirectByte(PARAM_1);
- if (!(_platform == Common::kPlatformFMTowns)) {
- // FIXME - this probably can be removed eventually, I don't think the following
- // check will ever be triggered, but then I could be wrong and it's better
- // to play it safe.
- if ((_opcode & 0x3F) != (_opcode & 0x1F))
- error("Oops, this shouldn't happen: o5_resourceRoutines opcode %d", _opcode);
- }
-
- int op = _opcode & 0x3F;
-
- switch (op) {
- case 1: // SO_LOAD_SCRIPT
- case 2: // SO_LOAD_SOUND
- case 3: // SO_LOAD_COSTUME
- ensureResourceLoaded(resType[op - 1], resid);
- break;
- case 4: // SO_LOAD_ROOM
- if (_version == 3) {
- ensureResourceLoaded(rtRoom, resid);
- if (resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
-
- if (_currentRoom != resid) {
- res.setResourceCounter(rtRoom, resid, 1);
- }
- } else
- ensureResourceLoaded(rtRoom, resid);
- break;
-
- case 5: // SO_NUKE_SCRIPT
- case 6: // SO_NUKE_SOUND
- case 7: // SO_NUKE_COSTUME
- case 8: // SO_NUKE_ROOM
- if (_gameId == GID_ZAK && (_platform == Common::kPlatformFMTowns))
- error("o5_resourceRoutines %d should not occur in Zak256", op);
- else
- res.setResourceCounter(resType[op-5], resid, 0x7F);
- break;
- case 9: // SO_LOCK_SCRIPT
- if (resid >= _numGlobalScripts)
- break;
- res.lock(rtScript, resid);
- break;
- case 10: // SO_LOCK_SOUND
- res.lock(rtSound, resid);
- break;
- case 11: // SO_LOCK_COSTUME
- res.lock(rtCostume, resid);
- break;
- case 12: // SO_LOCK_ROOM
- if (resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
- res.lock(rtRoom, resid);
- break;
-
- case 13: // SO_UNLOCK_SCRIPT
- if (resid >= _numGlobalScripts)
- break;
- res.unlock(rtScript, resid);
- break;
- case 14: // SO_UNLOCK_SOUND
- res.unlock(rtSound, resid);
- break;
- case 15: // SO_UNLOCK_COSTUME
- res.unlock(rtCostume, resid);
- break;
- case 16: // SO_UNLOCK_ROOM
- if (resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
- res.unlock(rtRoom, resid);
- break;
-
- case 17: // SO_CLEAR_HEAP
- //heapClear(0);
- //unkHeapProc2(0, 0);
- break;
- case 18: // SO_LOAD_CHARSET
- loadCharset(resid);
- break;
- case 19: // SO_NUKE_CHARSET
- nukeCharset(resid);
- break;
- case 20: // SO_LOAD_OBJECT
- loadFlObject(getVarOrDirectWord(PARAM_2), resid);
- break;
-
- // TODO: For the following see also Hibarnatus' information on bug #805691.
- case 32:
- // TODO (apparently never used in FM-TOWNS)
- debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
- break;
- case 33:
- // TODO (apparently never used in FM-TOWNS)
- debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
- break;
- case 35:
- // TODO: Might be used to set CD volume in FM-TOWNS Loom
- foo = getVarOrDirectByte(PARAM_2);
- debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
- break;
- case 36:
- // TODO: Sets the loudness of a sound resource. Used in Indy3 and Zak.
- foo = getVarOrDirectByte(PARAM_2);
- bar = fetchScriptByte();
- debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
- break;
- case 37:
- // TODO: Sets the pitch of a sound resource (pitch = foo - center semitones.
- // "center" is at 0x32 in the sfx resource (always 0x3C in zak256, but sometimes different in Indy3).
- foo = getVarOrDirectByte(PARAM_2);
- debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
- break;
-
- default:
- error("o5_resourceRoutines: default case %d", op);
- }
-}
-
-void ScummEngine_v5::o5_roomOps() {
- int a = 0, b = 0, c, d, e;
-
- if (_version == 3) {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- }
-
- _opcode = fetchScriptByte();
- switch (_opcode & 0x1F) {
- case 1: // SO_ROOM_SCROLL
- if (_version != 3) {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- }
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
- case 2: // SO_ROOM_COLOR
- if (_features & GF_SMALL_HEADER) {
- if (_version != 3) {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- }
- checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)");
- _roomPalette[b] = a;
- _fullRedraw = true;
- } else {
- error("room-color is no longer a valid command");
- }
- break;
-
- case 3: // SO_ROOM_SCREEN
- if (_version != 3) {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- }
- initScreens(a, b);
- break;
- case 4: // SO_ROOM_PALETTE
- if (_features & GF_SMALL_HEADER) {
- if (_version != 3) {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- }
- checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)");
- _shadowPalette[b] = a;
- setDirtyColors(b, b);
- } else {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- c = getVarOrDirectWord(PARAM_3);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(PARAM_1);
- setPalColor(d, a, b, c); /* index, r, g, b */
- }
- break;
- case 5: // SO_ROOM_SHAKE_ON
- setShake(1);
- break;
- case 6: // SO_ROOM_SHAKE_OFF
- setShake(0);
- break;
- case 7: // SO_ROOM_SCALE
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- _opcode = fetchScriptByte();
- c = getVarOrDirectByte(PARAM_1);
- d = getVarOrDirectByte(PARAM_2);
- _opcode = fetchScriptByte();
- e = getVarOrDirectByte(PARAM_2);
- setScaleSlot(e - 1, 0, b, a, 0, d, c);
- break;
- case 8: // SO_ROOM_INTENSITY
- if (_features & GF_SMALL_HEADER) {
- if (_version != 3) {
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- }
- c = getVarOrDirectWord(PARAM_3);
- } else {
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- c = getVarOrDirectByte(PARAM_3);
- }
- darkenPalette(a, a, a, b, c);
- break;
- case 9: // SO_ROOM_SAVEGAME
- _saveLoadFlag = getVarOrDirectByte(PARAM_1);
- _saveLoadSlot = getVarOrDirectByte(PARAM_2);
- _saveLoadSlot = 99; /* use this slot */
- _saveTemporaryState = true;
- break;
- case 10: // SO_ROOM_FADE
- a = getVarOrDirectWord(PARAM_1);
- if (a) {
- if (_platform == Common::kPlatformFMTowns) {
- switch (a) {
- case 8: // compose kMainVirtScreen over a screen buffer
- case 9: // call 0x110:0x20 _ax=0x601 _edx=2
- case 10: // call 0x110:0x20 _ax=0x601 _edx=3
- case 11: // clear screen 0x1C:0x45000 sizeof(640 * 320)
- case 12: // call 0x110:0x20 _ax=0x601 _edx=0
- case 13: // call 0x110:0x20 _ax=0x601 _edx=1
- case 16: // enable clearing of a screen buffer in drawBitmap()
- case 17: // disable clearing of a screen buffer in drawBitmap()
- case 18: // clear a screen buffer
- case 19: // enable palette operations (palManipulate(), cyclePalette() etc.)
- case 20: // disable palette operations
- case 21: // disable clearing of screen 0x1C:0x5000 sizeof(640 * 320) in initScreens()
- case 22: // enable clearing of screen 0x1C:0x5000 sizeof(640 * 320) in initScreens()
- case 30:
- debug(0, "o5_roomOps: unhandled FM-TOWNS fadeEffect %d", a);
- return;
- break;
- }
- }
- _switchRoomEffect = (byte)(a & 0xFF);
- _switchRoomEffect2 = (byte)(a >> 8);
- } else {
- fadeIn(_newEffect);
- }
- break;
- case 11: // SO_RGB_ROOM_INTENSITY
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- c = getVarOrDirectWord(PARAM_3);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(PARAM_1);
- e = getVarOrDirectByte(PARAM_2);
- darkenPalette(a, b, c, d, e);
- break;
- case 12: // SO_ROOM_SHADOW
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectWord(PARAM_2);
- c = getVarOrDirectWord(PARAM_3);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(PARAM_1);
- e = getVarOrDirectByte(PARAM_2);
- setupShadowPalette(a, b, c, d, e, 0, 256);
- break;
-
- case 13: // SO_SAVE_STRING
- {
- Common::OutSaveFile *file;
- char filename[256], *s;
-
- a = getVarOrDirectByte(PARAM_1);
- s = filename;
- while ((*s++ = fetchScriptByte()));
-
- file = _saveFileMan->openForSaving(filename);
- if (file != NULL) {
- byte *ptr;
- ptr = getResourceAddress(rtString, a);
- file->write(ptr, resStrLen(ptr) + 1);
- delete file;
- VAR(VAR_SOUNDRESULT) = 0;
- }
- break;
- }
- case 14: // SO_LOAD_STRING
- {
- Common::InSaveFile *file;
- char filename[256], *s;
-
- a = getVarOrDirectByte(PARAM_1);
- s = filename;
- while ((*s++ = fetchScriptByte()));
-
- file = _saveFileMan->openForLoading(filename);
- if (file != NULL) {
- byte *ptr;
- int len = 256, cnt = 0;
- ptr = (byte *)malloc(len);
- while (ptr) {
- int r = file->read(ptr + cnt, len - cnt);
- if ((cnt += r) < len) break;
- ptr = (byte *)realloc(ptr, len *= 2);
- }
- ptr[cnt] = '\0';
- loadPtrToResource(rtString, a, ptr);
- free(ptr);
- delete file;
- }
- break;
- }
- case 15: // SO_ROOM_TRANSFORM
- a = getVarOrDirectByte(PARAM_1);
- _opcode = fetchScriptByte();
- b = getVarOrDirectByte(PARAM_1);
- c = getVarOrDirectByte(PARAM_2);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(PARAM_1);
- palManipulateInit(a, b, c, d);
- break;
-
- case 16: // SO_CYCLE_SPEED
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- checkRange(16, 1, a, "o5_roomOps: 16: color cycle out of range (%d)");
- _colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0;
- break;
- default:
- error("o5_roomOps: unknown subopcode %d", _opcode & 0x1F);
- }
-}
-
-void ScummEngine_v5::o5_saveRestoreVerbs() {
- int a, b, c, slot, slot2;
-
- _opcode = fetchScriptByte();
-
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- c = getVarOrDirectByte(PARAM_3);
-
- switch (_opcode) {
- case 1: // SO_SAVE_VERBS
- while (a <= b) {
- slot = getVerbSlot(a, 0);
- if (slot && _verbs[slot].saveid == 0) {
- _verbs[slot].saveid = c;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 2: // SO_RESTORE_VERBS
- while (a <= b) {
- slot = getVerbSlot(a, c);
- if (slot) {
- slot2 = getVerbSlot(a, 0);
- if (slot2)
- killVerb(slot2);
- slot = getVerbSlot(a, c);
- _verbs[slot].saveid = 0;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 3: // SO_DELETE_VERBS
- while (a <= b) {
- slot = getVerbSlot(a, c);
- if (slot)
- killVerb(slot);
- a++;
- }
- break;
- default:
- error("o5_saveRestoreVerbs: unknown subopcode %d", _opcode);
- }
-}
-
-void ScummEngine_v5::o5_setCameraAt() {
- setCameraAtEx(getVarOrDirectWord(PARAM_1));
-}
-
-void ScummEngine_v5::o5_setObjectName() {
- int obj = getVarOrDirectWord(PARAM_1);
- setObjectName(obj);
-}
-
-void ScummEngine_v5::o5_setOwnerOf() {
- int obj, owner;
-
- obj = getVarOrDirectWord(0x80);
- owner = getVarOrDirectByte(0x40);
-
- setOwnerOf(obj, owner);
-}
-
-void ScummEngine_v5::o5_setState() {
- int obj, state;
- obj = getVarOrDirectWord(PARAM_1);
- state = getVarOrDirectByte(PARAM_2);
- putState(obj, state);
- markObjectRectAsDirty(obj);
- if (_bgNeedsRedraw)
- clearDrawObjectQueue();
-}
-
-void ScummEngine_v5::o5_setVarRange() {
- int a, b;
-
- getResultPos();
- a = fetchScriptByte();
- do {
- if (_opcode & 0x80)
- b = fetchScriptWordSigned();
- else
- b = fetchScriptByte();
-
- setResult(b);
- _resultVarNumber++;
- } while (--a);
-
- // Macintosh verison of indy3ega used different interface, so adjust values.
- if (_gameId == GID_INDY3 && _platform == Common::kPlatformMacintosh) {
- VAR(68) = 0;
- VAR(69) = 0;
- VAR(70) = 168;
- VAR(71) = 0;
- VAR(72) = 168;
- VAR(73) = 0;
- VAR(74) = 168;
- VAR(75) = 0;
- VAR(76) = 176;
- VAR(77) = 176;
- VAR(78) = 184;
- VAR(79) = 184;
- VAR(80) = 192;
- VAR(81) = 192;
- }
-}
-
-void ScummEngine_v5::o5_startMusic() {
- if (_platform == Common::kPlatformFMTowns && _version == 3) {
- // In FM-TOWNS games this is some kind of Audio CD status query function.
- // See also bug #762589 (thanks to Hibernatus for providing the information).
- getResultPos();
- int b = getVarOrDirectByte(PARAM_1);
- int result = 0;
- switch (b) {
- case 0:
- result = _sound->pollCD() == 0;
- break;
- case 0xFC:
- // TODO: Unpause (resume) audio track. We'll have to extend Sound and OSystem for this.
- break;
- case 0xFD:
- // TODO: Pause audio track. We'll have to extend Sound and OSystem for this.
- break;
- case 0xFE:
- result = _sound->getCurrentCDSound();
- break;
- case 0xFF:
- // TODO: Might return current CD volume in FM-TOWNS Loom. See also bug #805691.
- break;
- default:
- // TODO: return track length in seconds. We'll have to extend Sound and OSystem for this.
- // To check scummvm returns the right track length you
- // can look at the global script #9 (0x888A in 49.LFL).
- break;
- }
- debugC(DEBUG_GENERAL,"o5_startMusic(%d)", b);
- setResult(result);
- } else {
- _sound->addSoundToQueue(getVarOrDirectByte(PARAM_1));
- }
-}
-
-void ScummEngine_v5::o5_startSound() {
- const byte *oldaddr = _scriptPointer - 1;
- int sound = getVarOrDirectByte(PARAM_1);
-
- // WORKAROUND: In the scene where Largo is talking to Mad Marty, the
- // Woodtick music often resumes before Largo's theme has finished. As
- // far as I can tell, this is a script bug.
-
- if (_gameId == GID_MONKEY2 && sound == 110 && _sound->isSoundRunning(151)) {
- debug(1, "Delaying Woodtick music until Largo's theme has finished\n");
- _scriptPointer = oldaddr;
- o5_breakHere();
- return;
- }
-
- if (VAR_MUSIC_TIMER != 0xFF)
- VAR(VAR_MUSIC_TIMER) = 0;
- _sound->addSoundToQueue(sound);
-}
-
-void ScummEngine_v5::o5_stopMusic() {
- _sound->stopAllSounds();
-}
-
-void ScummEngine_v5::o5_stopSound() {
- _sound->stopSound(getVarOrDirectByte(PARAM_1));
-}
-
-void ScummEngine_v5::o5_isSoundRunning() {
- int snd;
- getResultPos();
- snd = getVarOrDirectByte(PARAM_1);
- if (snd)
- snd = _sound->isSoundRunning(snd);
- setResult(snd);
-}
-
-void ScummEngine_v5::o5_soundKludge() {
- int items[16];
-
- if (_features & GF_SMALL_HEADER) { // Is WaitForSentence in SCUMM V3
- if (_sentenceNum) {
- if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- } else if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
-
- _scriptPointer--;
- o5_breakHere();
- return;
- }
-
- int num = getWordVararg(items);
- _sound->soundKludge(items, num);
-}
-
-void ScummEngine_v5::o5_startObject() {
- int obj, script;
- int data[16];
-
- obj = getVarOrDirectWord(PARAM_1);
- script = getVarOrDirectByte(PARAM_2);
-
- getWordVararg(data);
- runObjectScript(obj, script, 0, 0, data);
-}
-
-void ScummEngine_v5::o5_startScript() {
- int op, script;
- int data[16];
-
- op = _opcode;
- script = getVarOrDirectByte(PARAM_1);
-
- getWordVararg(data);
-
- // FIXME: Script 171 loads a complete room resource, instead of the actual script.
- // Causing invalid opcode cases, see bug #1290485
- if (_gameId == GID_ZAK && (_platform == Common::kPlatformFMTowns) && script == 171)
- return;
-
- if (!_copyProtection) {
- // Method used by original games to skip copy protection scheme
- if (_gameId == GID_LOOM && _version == 3 && _currentRoom == 69 && script == 201)
- script = 205;
- else if ((_gameId == GID_MONKEY_VGA || _gameId == GID_MONKEY_EGA) && script == 152)
- return;
- }
-
- runScript(script, (op & 0x20) != 0, (op & 0x40) != 0, data);
-}
-
-void ScummEngine_v5::o5_stopObjectCode() {
- stopObjectCode();
-}
-
-void ScummEngine_v5::o5_stopObjectScript() {
- stopObjectScript(getVarOrDirectWord(PARAM_1));
-}
-
-void ScummEngine_v5::o5_stopScript() {
- int script;
-
- script = getVarOrDirectByte(PARAM_1);
-
- if (!script)
- stopObjectCode();
- else
- stopScript(script);
-}
-
-void ScummEngine_v5::o5_stringOps() {
- int a, b, c, i;
- byte *ptr;
-
- _opcode = fetchScriptByte();
- switch (_opcode & 0x1F) {
- case 1: /* loadstring */
- loadPtrToResource(rtString, getVarOrDirectByte(PARAM_1), NULL);
- break;
- case 2: /* copystring */
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- res.nukeResource(rtString, a);
- ptr = getResourceAddress(rtString, b);
- if (ptr)
- loadPtrToResource(rtString, a, ptr);
- break;
- case 3: /* set string char */
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- c = getVarOrDirectByte(PARAM_3);
- ptr = getResourceAddress(rtString, a);
- if (!(_gameId == GID_LOOM && _version == 4)) { /* FIXME - LOOM256 */
- if (ptr == NULL)
- error("String %d does not exist", a);
- ptr[b] = c;
- }
-
- break;
-
- case 4: /* get string char */
- getResultPos();
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- ptr = getResourceAddress(rtString, a);
- if (ptr == NULL)
- error("String %d does not exist", a);
- setResult(ptr[b]);
- break;
-
- case 5: /* create empty string */
- a = getVarOrDirectByte(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- res.nukeResource(rtString, a);
- if (b) {
- ptr = res.createResource(rtString, a, b);
- if (ptr) {
- for (i = 0; i < b; i++)
- ptr[i] = 0;
- }
- }
- break;
- }
-}
-
-void ScummEngine_v5::o5_subtract() {
- int a;
- getResultPos();
- a = getVarOrDirectWord(PARAM_1);
- setResult(readVar(_resultVarNumber) - a);
-}
-
-void ScummEngine_v5::o5_verbOps() {
- int verb, slot;
- VerbSlot *vs;
- int a, b;
- byte *ptr;
-
- verb = getVarOrDirectByte(PARAM_1);
-
- slot = getVerbSlot(verb, 0);
- checkRange(_numVerbs - 1, 0, slot, "Illegal new verb slot %d");
-
- vs = &_verbs[slot];
- vs->verbid = verb;
-
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- switch (_opcode & 0x1F) {
- case 1: // SO_VERB_IMAGE
- a = getVarOrDirectWord(PARAM_1);
- if (slot) {
- setVerbObject(_roomResource, a, slot);
- vs->type = kImageVerbType;
- }
- break;
- case 2: // SO_VERB_NAME
- loadPtrToResource(rtVerb, slot, NULL);
- if (slot == 0)
- res.nukeResource(rtVerb, slot);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 3: // SO_VERB_COLOR
- vs->color = getVarOrDirectByte(PARAM_1);
- break;
- case 4: // SO_VERB_HICOLOR
- vs->hicolor = getVarOrDirectByte(PARAM_1);
- break;
- case 5: // SO_VERB_AT
- vs->curRect.left = getVarOrDirectWord(PARAM_1);
- vs->curRect.top = getVarOrDirectWord(PARAM_2);
- // Macintosh verison of indy3ega used different interface, so adjust values.
- if ((_platform == Common::kPlatformMacintosh) && (_gameId == GID_INDY3)) {
- switch (verb) {
- case 1:
- case 2:
- case 9:
- vs->curRect.left += 16;
- break;
- case 10:
- case 11:
- case 12:
- vs->curRect.left += 36;
- break;
- case 4:
- case 5:
- case 8:
- vs->curRect.left += 60;
- break;
- case 13:
- case 32:
- case 33:
- case 34:
- vs->curRect.left += 90;
- break;
- case 107:
- vs->curRect.left -= 54;
- vs->curRect.top += 16;
- break;
- case 108:
- vs->curRect.left -= 54;
- vs->curRect.top += 8;
- break;
- }
- } else if (_gameId == GID_LOOM && _version == 4) {
- // FIXME: hack loom notes into right spot
- if ((verb >= 90) && (verb <= 97)) { // Notes
- switch (verb) {
- case 90:
- case 91:
- vs->curRect.top -= 7;
- break;
- case 92:
- vs->curRect.top -= 6;
- break;
- case 93:
- vs->curRect.top -= 4;
- break;
- case 94:
- vs->curRect.top -= 3;
- break;
- case 95:
- vs->curRect.top -= 1;
- break;
- case 97:
- vs->curRect.top -= 5;
- }
- }
- }
- break;
- case 6: // SO_VERB_ON
- vs->curmode = 1;
- break;
- case 7: // SO_VERB_OFF
- vs->curmode = 0;
- break;
- case 8: // SO_VERB_DELETE
- killVerb(slot);
- break;
- case 9: // SO_VERB_NEW
- slot = getVerbSlot(verb, 0);
- if (slot == 0) {
- for (slot = 1; slot < _numVerbs; slot++) {
- if (_verbs[slot].verbid == 0)
- break;
- }
- if (slot == _numVerbs)
- error("Too many verbs");
- }
- vs = &_verbs[slot];
- vs->verbid = verb;
- vs->color = 2;
- vs->hicolor = (_version == 3) ? 14 : 0;
- vs->dimcolor = 8;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
-
- case 16: // SO_VERB_DIMCOLOR
- vs->dimcolor = getVarOrDirectByte(PARAM_1);
- break;
- case 17: // SO_VERB_DIM
- vs->curmode = 2;
- break;
- case 18: // SO_VERB_KEY
- vs->key = getVarOrDirectByte(PARAM_1);
- break;
- case 19: // SO_VERB_CENTER
- vs->center = 1;
- break;
- case 20: // SO_VERB_NAME_STR
- ptr = getResourceAddress(rtString, getVarOrDirectWord(PARAM_1));
- if (!ptr)
- res.nukeResource(rtVerb, slot);
- else {
- loadPtrToResource(rtVerb, slot, ptr);
- }
- if (slot == 0)
- res.nukeResource(rtVerb, slot);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 22: /* assign object */
- a = getVarOrDirectWord(PARAM_1);
- b = getVarOrDirectByte(PARAM_2);
- if (slot && vs->imgindex != a) {
- setVerbObject(b, a, slot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 23: /* set back color */
- vs->bkcolor = getVarOrDirectByte(PARAM_1);
- break;
- default:
- error("o5_verbOps: unknown subopcode %d", _opcode & 0x1F);
- }
- }
-
- // Force redraw of the modified verb slot
- drawVerb(slot, 0);
- verbMouseOver(0);
-}
-
-void ScummEngine_v5::o5_wait() {
- const byte *oldaddr = _scriptPointer - 1;
-
- if ((_gameId == GID_INDY3) && !(_platform == Common::kPlatformMacintosh)) {
- _opcode = 2;
- } else
- _opcode = fetchScriptByte();
-
- switch (_opcode & 0x1F) {
- case 1: // SO_WAIT_FOR_ACTOR
- {
- Actor *a = derefActorSafe(getVarOrDirectByte(PARAM_1), "o5_wait");
- if (a && a->isInCurrentRoom() && a->_moving)
- break;
- return;
- }
- case 2: // SO_WAIT_FOR_MESSAGE
- if (VAR(VAR_HAVE_MSG))
- break;
- return;
- case 3: // SO_WAIT_FOR_CAMERA
- if (camera._cur.x / 8 != camera._dest.x / 8)
- break;
- return;
- case 4: // SO_WAIT_FOR_SENTENCE
- if (_sentenceNum) {
- if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- }
- if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- default:
- error("o5_wait: unknown subopcode %d", _opcode & 0x1F);
- return;
- }
-
- _scriptPointer = oldaddr;
- o5_breakHere();
-}
-
-void ScummEngine_v5::o5_walkActorTo() {
- int x, y;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o5_walkActorTo");
- x = getVarOrDirectWord(PARAM_2);
- y = getVarOrDirectWord(PARAM_3);
- a->startWalkActor(x, y, -1);
-}
-
-void ScummEngine_v5::o5_walkActorToActor() {
- int x, y;
- Actor *a, *a2;
- int nr = getVarOrDirectByte(PARAM_1);
- int nr2 = getVarOrDirectByte(PARAM_2);
- int dist = fetchScriptByte();
-
- if (nr == 106 && _gameId == GID_INDY4) {
- printf("Bypassing Indy4 bug\n");
- return;
- }
-
- if (_gameId == GID_LOOM && _version == 4 && nr == 1 && nr2 == 0 &&
- dist == 255 && vm.slot[_currentScript].number == 98) {
- // WORKAROUND bug #743615: LoomCD script 98 contains this:
- // walkActorToActor(1,0,255)
- // Once again this is either a script bug, or there is some hidden
- // or unknown meaning to this odd walk request...
- return;
- }
-
- if (_gameId == GID_INDY4 && nr == 1 && nr2 == 106 &&
- dist == 255 && vm.slot[_currentScript].number == 210) {
- // WORKAROUND bug: Work around an invalid actor bug when using the
- // camel in Fate of Atlantis, the "wits" path. The room-65-210 script
- // contains this:
- // walkActorToActor(1,106,255)
- // Once again this is either a script bug, or there is some hidden
- // or unknown meaning to this odd walk request...
- return;
- }
-
- a = derefActor(nr, "o5_walkActorToActor");
- if (!a->isInCurrentRoom())
- return;
-
- a2 = derefActor(nr2, "o5_walkActorToActor(2)");
- if (!a2->isInCurrentRoom())
- return;
-
- if (_version <= 2)
- dist *= 8;
- else if (dist == 0xFF) {
- dist = a->_scalex * a->_width / 0xFF;
- dist += (a2->_scalex * a2->_width / 0xFF) / 2;
- }
- x = a2->_pos.x;
- y = a2->_pos.y;
- if (x < a->_pos.x)
- x += dist;
- else
- x -= dist;
-
- if (_version <= 3) {
- AdjustBoxResult abr = a->adjustXYToBeInBox(x, y);
- x = abr.x;
- y = abr.y;
- }
- a->startWalkActor(x, y, -1);
-}
-
-void ScummEngine_v5::o5_walkActorToObject() {
- int obj;
- Actor *a;
-
- a = derefActor(getVarOrDirectByte(PARAM_1), "o5_walkActorToObject");
- obj = getVarOrDirectWord(PARAM_2);
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- int x, y, dir;
- getObjectXYPos(obj, x, y, dir);
- a->startWalkActor(x, y, dir);
- }
-}
-
-int ScummEngine_v5::getWordVararg(int *ptr) {
- int i;
-
- for (i = 0; i < 16; i++)
- ptr[i] = 0;
-
- i = 0;
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- ptr[i++] = getVarOrDirectWord(PARAM_1);
- }
- return i;
-}
-
-void ScummEngine_v5::decodeParseString() {
- int textSlot;
-
- switch (_actorToPrintStrFor) {
- case 252:
- textSlot = 3;
- break;
- case 253:
- textSlot = 2;
- break;
- case 254:
- textSlot = 1;
- break;
- default:
- textSlot = 0;
- }
-
- _string[textSlot].loadDefault();
-
- while ((_opcode = fetchScriptByte()) != 0xFF) {
- switch (_opcode & 0xF) {
- case 0: // SO_AT
- _string[textSlot].xpos = getVarOrDirectWord(PARAM_1);
- _string[textSlot].ypos = getVarOrDirectWord(PARAM_2);
- _string[textSlot].overhead = false;
- break;
- case 1: // SO_COLOR
- _string[textSlot].color = getVarOrDirectByte(PARAM_1);
- break;
- case 2: // SO_CLIPPED
- _string[textSlot].right = getVarOrDirectWord(PARAM_1);
- break;
- case 3: // SO_ERASE
- {
- int w = getVarOrDirectWord(PARAM_1);
- int h = getVarOrDirectWord(PARAM_2);
- // restoreCharsetBg(xpos, xpos + w, ypos, ypos + h)
- error("ScummEngine_v5::decodeParseString: Unhandled case 3: %d, %d", w, h);
- }
- break;
- case 4: // SO_CENTER
- _string[textSlot].center = true;
- _string[textSlot].overhead = false;
- break;
- case 6: // SO_LEFT
- if (_version == 3) {
- _string[textSlot].height = getVarOrDirectWord(PARAM_1);
- } else {
- _string[textSlot].center = false;
- _string[textSlot].overhead = false;
- }
- break;
- case 7: // SO_OVERHEAD
- _string[textSlot].overhead = true;
- break;
- case 8:{ // SO_SAY_VOICE
- int offset = (uint16)getVarOrDirectWord(PARAM_1);
- int delay = (uint16)getVarOrDirectWord(PARAM_2);
-
- if (_gameId == GID_LOOM && _version == 4) {
- if (offset == 0 && delay == 0) {
- VAR(VAR_MUSIC_TIMER) = 0;
- _sound->stopCD();
- } else {
- // Loom specified the offset from the start of the CD;
- // thus we have to subtract the length of the first track
- // (22500 frames) plus the 2 second = 150 frame leadin.
- // I.e. in total 22650 frames.
- offset = (int)(offset * 7.5 - 22500 - 2*75);
-
- // Slightly increase the delay (5 frames = 1/25 of a second).
- // This noticably improves the experience in Loom CD.
- delay = (int)(delay * 7.5 + 5);
-
- _sound->playCDTrack(1, 0, offset, delay);
- }
- } else {
- error("ScummEngine_v5::decodeParseString: Unhandled case 8");
- }
- }
- break;
- case 15: // SO_TEXTSTRING
- // WORKAROUND: This happens when Chaos introduces
- // herself to bishop Mandible. Of all the places to put
- // a typo...
- if (_gameId == GID_LOOM && strcmp((const char *) _scriptPointer, "I am Choas.") == 0)
- printString(textSlot, (const byte *) "I am Chaos.");
- else
- printString(textSlot, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
-
-
- // In SCUMM V1-V3, there were no 'default' values for the text slot
- // values. Hence to achieve correct behaviour, we have to keep the
- // 'default' values in sync with the active values.
- //
- // Note: This is needed for Indy3 (Grail Diary). It's also needed
- // for Loom, or the lines Bobbin speaks during the intro are put
- // at position 0,0.
- //
- // Note: We can't use saveDefault() here because we only want to
- // save the position and color. In particular, we do not want to
- // save the 'center' flag. See bug #933168.
- if (_version <= 3) {
- _string[textSlot]._default.xpos = _string[textSlot].xpos;
- _string[textSlot]._default.ypos = _string[textSlot].ypos;
- _string[textSlot]._default.height = _string[textSlot].height;
- _string[textSlot]._default.color = _string[textSlot].color;
- }
- return;
- default:
- error("ScummEngine_v5::decodeParseString: Unhandled case %d", _opcode & 0xF);
- }
- }
-
- _string[textSlot].saveDefault();
-}
-
-void ScummEngine_v5::o5_oldRoomEffect() {
- int a;
-
- _opcode = fetchScriptByte();
- if ((_opcode & 0x1F) == 3) {
- a = getVarOrDirectWord(PARAM_1);
-
-#if 1
- if (_platform == Common::kPlatformFMTowns && _version == 3) {
- // FIXME / TODO: OK the first thing to note is: at least in Zak256,
- // maybe also in other games, this opcode does a bit more. I added
- // some stubs here, but somebody with a full IDA or more knowledge
- // about this will have to fill in the gaps. At least now we know
- // that something is missing here :-)
-
- if (a == 4) {
- printf("o5_oldRoomEffect ODDBALL: _opcode = 0x%x, a = 0x%x\n", _opcode, a);
- // No idea what byte_2FCCF is, but it's a globale boolean flag.
- // I only add it here as a temporary hack to make the pseudo code compile.
- // Maybe it is just there as a reentry protection guard, given
- // how it is used? It might also correspond to _screenEffectFlag.
- int byte_2FCCF = 0;
-
- // For now, we force a redraw of the screen background. This
- // way the Zak end credits seem to work mostly correct.
- VirtScreen *vs = &virtscr[0];
- restoreBG(Common::Rect(0,vs->topline, vs->w, vs->topline + vs->h));
- vs->setDirtyRange(0, vs->h);
- updateDirtyScreen(kMainVirtScreen);
-
- if (byte_2FCCF) {
- // Here now "sub_1C44" is called, which sets byte_2FCCF to 0 then
- // calls yet another sub (which also reads byte_2FCCF):
-
- byte_2FCCF = 0;
- //call sub_0BB3
-
-
- // Now sub_085C is called. This is quite simply: it sets
- // 0xF000 bytes. starting at 0x40000 to 0. No idea what that
- // buffer is, maybe a screen buffer, though. Note that
- // 0xF000 = 320*192.
- // Maybe this is also the charset mask being cleaned?
-
- // call sub_085C
-
-
- // And then sub_1C54 is called, which is almost identical to
- // the above sub_1C44, only it sets byte_2FCCF to 1:
-
- byte_2FCCF = 1;
- // call sub_0BB3
-
- } else {
- // Here only sub_085C is called (see comment above)
-
- // call sub_085C
- }
- return;
- }
-#endif
-
- }
- if (a) {
- _switchRoomEffect = (byte)(a & 0xFF);
- _switchRoomEffect2 = (byte)(a >> 8);
- } else {
- fadeIn(_newEffect);
- }
- }
-}
-
-void ScummEngine_v5::o5_pickupObjectOld() {
- int obj = getVarOrDirectWord(PARAM_1);
-
- if (obj < 1) {
- error("pickupObjectOld received invalid index %d (script %d)", obj, vm.slot[_currentScript].number);
- }
-
- if (getObjectIndex(obj) == -1)
- return;
-
- if (whereIsObject(obj) == WIO_INVENTORY) /* Don't take an */
- return; /* object twice */
-
- // debug(0, "adding %d from %d to inventoryOld", obj, _currentRoom);
- addObjectToInventory(obj, _roomResource);
- markObjectRectAsDirty(obj);
- putOwner(obj, VAR(VAR_EGO));
- putClass(obj, kObjectClassUntouchable, 1);
- putState(obj, 1);
- clearDrawObjectQueue();
- runInventoryScript(1);
-}
-
-#undef PARAM_1
-#undef PARAM_2
-#undef PARAM_3
-
-} // End of namespace Scumm
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
deleted file mode 100644
index 77709eed21..0000000000
--- a/scumm/script_v6.cpp
+++ /dev/null
@@ -1,3183 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/insane/insane.h"
-#include "scumm/intern.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/smush/smush_player.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-#include "sound/mididrv.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v6, x)
-
-void ScummEngine_v6::setupOpcodes() {
- static const OpcodeEntryV6 opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o6_pushByteVar),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayRead),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayIndexedRead),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o6_invalid),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeByteVar),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayWrite),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayIndexedWrite),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteVarInc),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayInc),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteVarDec),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayDec),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o6_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o6_startObject),
- OPCODE(o6_drawObject),
- OPCODE(o6_drawObjectAt),
- OPCODE(o6_drawBlastObject),
- /* 64 */
- OPCODE(o6_setBlastObjectWindow),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_stopMusic),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o6_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o6_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o6_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_startMusic),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o6_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o6_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o6_getVerbFromXY),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_createBoxMatrix),
- OPCODE(o6_resourceRoutines),
- /* 9C */
- OPCODE(o6_roomOps),
- OPCODE(o6_actorOps),
- OPCODE(o6_verbOps),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o6_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o6_arrayOps),
- OPCODE(o6_saveRestoreVerbs),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o6_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorAnimCounter1),
- /* AC */
- OPCODE(o6_soundKludge),
- OPCODE(o6_isAnyOf),
- OPCODE(o6_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o6_talkActor),
- OPCODE(o6_talkEgo),
- /* BC */
- OPCODE(o6_dimArray),
- OPCODE(o6_dummy),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o6_dim2dimArray),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o6_kernelGetFunctions),
- OPCODE(o6_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o6_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* DC */
- OPCODE(o6_invalid),
- OPCODE(o6_findAllObjects),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E0 */
- OPCODE(o6_invalid),
- OPCODE(o6_getPixel),
- OPCODE(o6_invalid),
- OPCODE(o6_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* EC */
- OPCODE(o6_getActorLayer),
- OPCODE(o6_getObjectNewDir),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F0 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F4 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* FC */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV6 = opcodes;
-}
-
-void ScummEngine_v6::executeOpcode(byte i) {
- OpcodeProcV6 op = _opcodesV6[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v6::getOpcodeDesc(byte i) {
- return _opcodesV6[i].desc;
-}
-
-int ScummEngine_v6::popRoomAndObj(int *room) {
- int obj;
-
- if (_version >= 7) {
- obj = pop();
- *room = getObjectRoom(obj);
- } else {
- *room = pop();
- obj = pop();
- }
-
- return obj;
-}
-
-ScummEngine_v6::ArrayHeader *ScummEngine_v6::defineArray(int array, int type, int dim2, int dim1) {
- int id;
- int size;
- ArrayHeader *ah;
-
- assert(0 <= type && type <= 5);
-
-
- if (_heversion >= 61) {
- if (type == kBitArray || type == kNibbleArray)
- type = kByteArray;
- } else {
- // NOTE: The following code turns all arrays except string arrays into
- // integer arrays. There seems to be no reason for this, and it wastes
- // space. However, we can't just remove this either, as that would
- // break savegame compatibility. So do not touch this unless you are
- // also adding code which updated old savegames, too. And of course
- // readArray() and writeArray() would have to be updated, too...
- if (type != kStringArray)
- type = kIntArray;
- }
-
- nukeArray(array);
-
- id = findFreeArrayId();
-
- if (_version == 8) {
- if (array & 0x40000000) {
- }
-
- if (array & 0x80000000) {
- error("Can't define bit variable as array pointer");
- }
-
- size = (type == kIntArray) ? 4 : 1;
- } else {
- if (array & 0x4000) {
- }
-
- if (array & 0x8000) {
- error("Can't define bit variable as array pointer");
- }
-
- size = (type == kIntArray) ? 2 : 1;
- }
-
- writeVar(array, id);
-
- size *= dim2 + 1;
- size *= dim1 + 1;
-
- ah = (ArrayHeader *)res.createResource(rtString, id, size + sizeof(ArrayHeader));
-
- ah->type = TO_LE_16(type);
- ah->dim1 = TO_LE_16(dim1 + 1);
- ah->dim2 = TO_LE_16(dim2 + 1);
-
- return ah;
-}
-
-void ScummEngine_v6::nukeArray(int a) {
- int data;
-
- data = readVar(a);
-
- if (_heversion >= 80)
- data &= ~0x33539000;
-
- if (data)
- res.nukeResource(rtString, data);
- if (_heversion >= 60)
- _arraySlot[data] = 0;
-
- writeVar(a, 0);
-}
-
-int ScummEngine_v6::findFreeArrayId() {
- byte **addr = res.address[rtString];
- int i;
-
- for (i = 1; i < _numArray; i++) {
- if (!addr[i])
- return i;
- }
- error("Out of array pointers, %d max", _numArray);
- return -1;
-}
-
-#define SWAP16(x) x = SWAP_BYTES_16(x)
-
-ScummEngine_v6::ArrayHeader *ScummEngine_v6::getArray(int array) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- if (!ah)
- return 0;
-
- // Workaround for a long standing bug where we save array headers in native
- // endianness, instead of a fixed endianness. We try to detect savegames
- // which were created on a big endian system and convert them to little
- // endian.
- if ((FROM_LE_16(ah->dim1) & 0xF000) || (FROM_LE_16(ah->dim2) & 0xF000) || (FROM_LE_16(ah->type) & 0xFF00)) {
- SWAP16(ah->dim1);
- SWAP16(ah->dim2);
- SWAP16(ah->type);
- }
-
- return ah;
-}
-
-int ScummEngine_v6::readArray(int array, int idx, int base) {
- ArrayHeader *ah = getArray(array);
-
- if (ah == NULL || ah->data == NULL)
- error("readArray: invalid array %d (%d)", array, readVar(array));
-
- // WORKAROUND bug #645711. This is clearly a script bug, as this script
- // excerpt shows nicely:
- // ...
- // [03A7] (5D) if (isAnyOf(array-447[localvar13][localvar14],[0,4])) {
- // [03BD] (5D) if ((localvar13 != -1) && (localvar14 != -1)) {
- // [03CF] (B6) printDebug.begin()
- // ...
- if (_gameId == GID_FT && array == 447 && _currentRoom == 95 && vm.slot[_currentScript].number == 2010 && idx == -1 && base == -1) {
- return 0;
- }
-
- const int offset = base + idx * FROM_LE_16(ah->dim1);
-
- if (offset < 0 || offset >= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2)) {
- error("readArray: array %d out of bounds: [%d,%d] exceeds [%d,%d]",
- array, base, idx, FROM_LE_16(ah->dim1), FROM_LE_16(ah->dim2));
- }
-
- int val;
- if (FROM_LE_16(ah->type) != kIntArray) {
- val = ah->data[offset];
- } else if (_version == 8) {
- val = (int32)READ_LE_UINT32(ah->data + offset * 4);
- } else {
- val = (int16)READ_LE_UINT16(ah->data + offset * 2);
- }
- return val;
-}
-
-void ScummEngine_v6::writeArray(int array, int idx, int base, int value) {
- ArrayHeader *ah = getArray(array);
- if (!ah)
- return;
-
- const int offset = base + idx * FROM_LE_16(ah->dim1);
-
- if (offset < 0 || offset >= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2)) {
- error("writeArray: array %d out of bounds: [%d,%d] exceeds [%d,%d]",
- array, base, idx, FROM_LE_16(ah->dim1), FROM_LE_16(ah->dim2));
- }
-
- if (FROM_LE_16(ah->type) != kIntArray) {
- ah->data[offset] = value;
- } else if (_version == 8) {
- WRITE_LE_UINT32(ah->data + offset * 4, value);
- } else {
- WRITE_LE_UINT16(ah->data + offset * 2, value);
- }
-}
-
-void ScummEngine_v6::readArrayFromIndexFile() {
- int num;
- int a, b, c;
-
- while ((num = _fileHandle->readUint16LE()) != 0) {
- a = _fileHandle->readUint16LE();
- b = _fileHandle->readUint16LE();
- c = _fileHandle->readUint16LE();
- if (c == kBitArray)
- defineArray(num, kBitArray, a, b);
- else
- defineArray(num, kIntArray, a, b);
- }
-}
-
-int ScummEngine_v6::getStackList(int *args, uint maxnum) {
- uint num, i;
-
- for (i = 0; i < maxnum; i++)
- args[i] = 0;
-
- num = pop();
-
- if (num > maxnum)
- error("Too many items %d in stack list, max %d", num, maxnum);
-
- i = num;
- while (i--) {
- args[i] = pop();
- }
-
- return num;
-}
-
-void ScummEngine_v6::o6_pushByte() {
- push(fetchScriptByte());
-}
-
-void ScummEngine_v6::o6_pushWord() {
- push(fetchScriptWordSigned());
-}
-
-void ScummEngine_v6::o6_pushByteVar() {
- push(readVar(fetchScriptByte()));
-}
-
-void ScummEngine_v6::o6_pushWordVar() {
- push(readVar(fetchScriptWord()));
-}
-
-void ScummEngine_v6::o6_invalid() {
- error("Invalid opcode '%x' at %x", _opcode, _scriptPointer - _scriptOrgPointer);
-}
-
-void ScummEngine_v6::o6_byteArrayRead() {
- int base = pop();
- push(readArray(fetchScriptByte(), 0, base));
-}
-
-void ScummEngine_v6::o6_wordArrayRead() {
- int base = pop();
- push(readArray(fetchScriptWord(), 0, base));
-}
-
-void ScummEngine_v6::o6_byteArrayIndexedRead() {
- int base = pop();
- int idx = pop();
- push(readArray(fetchScriptByte(), idx, base));
-}
-
-void ScummEngine_v6::o6_wordArrayIndexedRead() {
- int base = pop();
- int idx = pop();
- push(readArray(fetchScriptWord(), idx, base));
-}
-
-void ScummEngine_v6::o6_dup() {
- int a = pop();
- push(a);
- push(a);
-}
-
-void ScummEngine_v6::o6_not() {
- push(pop() == 0);
-}
-
-void ScummEngine_v6::o6_eq() {
- push(pop() == pop());
-}
-
-void ScummEngine_v6::o6_neq() {
- push(pop() != pop());
-}
-
-void ScummEngine_v6::o6_gt() {
- int a = pop();
- push(pop() > a);
-}
-
-void ScummEngine_v6::o6_lt() {
- int a = pop();
- push(pop() < a);
-}
-
-void ScummEngine_v6::o6_le() {
- int a = pop();
- push(pop() <= a);
-}
-
-void ScummEngine_v6::o6_ge() {
- int a = pop();
- push(pop() >= a);
-}
-
-void ScummEngine_v6::o6_add() {
- int a = pop();
- push(pop() + a);
-}
-
-void ScummEngine_v6::o6_sub() {
- int a = pop();
- push(pop() - a);
-}
-
-void ScummEngine_v6::o6_mul() {
- int a = pop();
- push(pop() * a);
-}
-
-void ScummEngine_v6::o6_div() {
- int a = pop();
- if (a == 0)
- error("division by zero");
- push(pop() / a);
-}
-
-void ScummEngine_v6::o6_land() {
- int a = pop();
- push(pop() && a);
-}
-
-void ScummEngine_v6::o6_lor() {
- int a = pop();
- push(pop() || a);
-}
-
-void ScummEngine_v6::o6_bor() {
- int a = pop();
- push(pop() | a);
-}
-
-void ScummEngine_v6::o6_band() {
- int a = pop();
- push(pop() & a);
-}
-
-void ScummEngine_v6::o6_pop() {
- pop();
-}
-
-void ScummEngine_v6::o6_writeByteVar() {
- writeVar(fetchScriptByte(), pop());
-}
-
-void ScummEngine_v6::o6_writeWordVar() {
- writeVar(fetchScriptWord(), pop());
-}
-
-void ScummEngine_v6::o6_byteArrayWrite() {
- int a = pop();
- writeArray(fetchScriptByte(), 0, pop(), a);
-}
-
-void ScummEngine_v6::o6_wordArrayWrite() {
- int a = pop();
- writeArray(fetchScriptWord(), 0, pop(), a);
-}
-
-void ScummEngine_v6::o6_byteArrayIndexedWrite() {
- int val = pop();
- int base = pop();
- writeArray(fetchScriptByte(), pop(), base, val);
-}
-
-void ScummEngine_v6::o6_wordArrayIndexedWrite() {
- int val = pop();
- int base = pop();
- writeArray(fetchScriptWord(), pop(), base, val);
-}
-
-void ScummEngine_v6::o6_byteVarInc() {
- int var = fetchScriptByte();
- writeVar(var, readVar(var) + 1);
-}
-
-void ScummEngine_v6::o6_wordVarInc() {
- int var = fetchScriptWord();
- writeVar(var, readVar(var) + 1);
-}
-
-void ScummEngine_v6::o6_byteArrayInc() {
- int var = fetchScriptByte();
- int base = pop();
- writeArray(var, 0, base, readArray(var, 0, base) + 1);
-}
-
-void ScummEngine_v6::o6_wordArrayInc() {
- int var = fetchScriptWord();
- int base = pop();
- writeArray(var, 0, base, readArray(var, 0, base) + 1);
-}
-
-void ScummEngine_v6::o6_byteVarDec() {
- int var = fetchScriptByte();
- writeVar(var, readVar(var) - 1);
-}
-
-void ScummEngine_v6::o6_wordVarDec() {
- int var = fetchScriptWord();
- writeVar(var, readVar(var) - 1);
-}
-
-void ScummEngine_v6::o6_byteArrayDec() {
- int var = fetchScriptByte();
- int base = pop();
- writeArray(var, 0, base, readArray(var, 0, base) - 1);
-}
-
-void ScummEngine_v6::o6_wordArrayDec() {
- int var = fetchScriptWord();
- int base = pop();
- writeArray(var, 0, base, readArray(var, 0, base) - 1);
-}
-
-void ScummEngine_v6::o6_if() {
- if (pop())
- o6_jump();
- else
- fetchScriptWord();
-}
-
-void ScummEngine_v6::o6_ifNot() {
- if (!pop())
- o6_jump();
- else
- fetchScriptWord();
-}
-
-void ScummEngine_v6::o6_jump() {
- int offset = fetchScriptWordSigned();
- _scriptPointer += offset;
-}
-
-void ScummEngine_v6::o6_startScript() {
- int args[25];
- int script, flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = pop();
-
- // WORKAROUND bug #556558: At Dino Bungee National Memorial, the buttons for
- // the Wally and Rex dinosaurs will always restart their speech, instead of
- // stopping and starting their speech. This was a script bug in the original
- // game.
- if (_gameId == GID_SAMNMAX && _roomResource == 59 &&
- vm.slot[_currentScript].number == 201 && script == 48) {
- o6_breakHere();
- }
-
- // WORKAROUND bug #903223: In Puerto Pollo, if you have Guybrush examine
- // the church clock, he'll read out the current time. Nice touch, only that
- // it sounds crap in the german version (and maybe others, too). It seems
- // the original engine of the german version played just a simple fixed
- // text in this spot, for the above reason. Since the data files are
- // unchanged, it must have been an engine hack job. No idea how they did
- // it exactly, but this here is how we do it :-)
- if (_gameId == GID_CMI && script == 204 &&
- _currentRoom == 15 && vm.slot[_currentScript].number == 421 &&
- _language == Common::DE_DEU) {
-
- _actorToPrintStrFor = 1;
- _string[0].loadDefault();
- actorTalk((const byte *)"/VDSO325/Whoa! Look at the time. Gotta scoot.");
-
- return;
- }
-
- runScript(script, (flags & 1) != 0, (flags & 2) != 0, args);
-}
-
-void ScummEngine_v6::o6_jumpToScript() {
- int args[25];
- int script, flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = pop();
- stopObjectCode();
- runScript(script, (flags & 1) != 0, (flags & 2) != 0, args);
-}
-
-void ScummEngine_v6::o6_startScriptQuick() {
- int args[25];
- int script;
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- runScript(script, 0, 0, args);
-}
-
-void ScummEngine_v6::o6_startScriptQuick2() {
- int args[25];
- int script;
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- runScript(script, 0, 1, args);
-}
-
-void ScummEngine_v6::o6_startObject() {
- int args[25];
- int script, entryp;
- int flags;
- getStackList(args, ARRAYSIZE(args));
- entryp = pop();
- script = pop();
- flags = pop();
- runObjectScript(script, entryp, (flags & 1) != 0, (flags & 2) != 0, args);
-}
-
-void ScummEngine_v6::o6_startObjectQuick() {
- int args[25];
- int script, entryp;
- getStackList(args, ARRAYSIZE(args));
- entryp = pop();
- script = pop();
- runObjectScript(script, entryp, 0, 1, args);
-}
-
-void ScummEngine_v6::o6_drawObject() {
- int state = pop();
- int obj = pop();
-
- // This is based on disassembly
- if (state == 0)
- state = 1;
-
- setObjectState(obj, state, -1, -1);
-}
-
-void ScummEngine_v6::o6_drawObjectAt() {
- int y = pop();
- int x = pop();
- int obj = pop();
- setObjectState(obj, 1, x, y);
-}
-
-void ScummEngine_v6::o6_stopObjectCode() {
- stopObjectCode();
-}
-
-void ScummEngine_v6::o6_endCutscene() {
- endCutscene();
-}
-
-void ScummEngine_v6::o6_cutscene() {
- int args[25];
- getStackList(args, ARRAYSIZE(args));
- beginCutscene(args);
-}
-
-void ScummEngine_v6::o6_stopMusic() {
- _sound->stopAllSounds();
-}
-
-void ScummEngine_v6::o6_freezeUnfreeze() {
- int a = pop();
-
- if (a)
- freezeScripts(a);
- else
- unfreezeScripts();
-}
-
-void ScummEngine_v6::o6_cursorCommand() {
- int a, i;
- int args[16];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0x90: // SO_CURSOR_ON Turn cursor on
- _cursor.state = 1;
- verbMouseOver(0);
- break;
- case 0x91: // SO_CURSOR_OFF Turn cursor off
- _cursor.state = 0;
- verbMouseOver(0);
- break;
- case 0x92: // SO_USERPUT_ON
- _userPut = 1;
- break;
- case 0x93: // SO_USERPUT_OFF
- _userPut = 0;
- break;
- case 0x94: // SO_CURSOR_SOFT_ON Turn soft cursor on
- _cursor.state++;
- if (_cursor.state > 1)
- error("Cursor state greater than 1 in script");
- verbMouseOver(0);
- break;
- case 0x95: // SO_CURSOR_SOFT_OFF Turn soft cursor off
- _cursor.state--;
- verbMouseOver(0);
- break;
- case 0x96: // SO_USERPUT_SOFT_ON
- _userPut++;
- break;
- case 0x97: // SO_USERPUT_SOFT_OFF
- _userPut--;
- break;
- case 0x99: // SO_CURSOR_IMAGE Set cursor image
- {
- int room, obj;
- if (_heversion >= 70) {
- obj = pop();
- room = getObjectRoom(obj);
- } else {
- obj = popRoomAndObj(&room);
- }
- setCursorFromImg(obj, room, 1);
- break;
- }
- case 0x9A: // SO_CURSOR_HOTSPOT Set cursor hotspot
- a = pop();
- setCursorHotspot(pop(), a);
- break;
- case 0x9C: // SO_CHARSET_SET
- initCharset(pop());
- break;
- case 0x9D: // SO_CHARSET_COLOR
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- break;
- case 0xD6: // SO_CURSOR_TRANSPARENT Set cursor transparent color
- setCursorTransparency(pop());
- break;
- default:
- error("o6_cursorCommand: default case %x", subOp);
- }
-
- VAR(VAR_CURSORSTATE) = _cursor.state;
- VAR(VAR_USERPUT) = _userPut;
-}
-
-void ScummEngine_v6::o6_breakHere() {
- updateScriptPtr();
- _currentScript = 0xFF;
-}
-
-void ScummEngine_v6::o6_ifClassOfIs() {
- int args[16];
- int num, obj, cls;
- bool b;
- int cond = 1;
-
- num = getStackList(args, ARRAYSIZE(args));
- obj = pop();
-
- if (_heversion >= 80 && num == 0) {
- push(_classData[obj]);
- return;
- }
-
- while (--num >= 0) {
- cls = args[num];
- b = getClass(obj, cls);
- if ((cls & 0x80 && !b) || (!(cls & 0x80) && b))
- cond = 0;
- }
- push(cond);
-}
-
-void ScummEngine_v6::o6_setClass() {
- int args[16];
- int num, obj, cls;
-
- num = getStackList(args, ARRAYSIZE(args));
- obj = pop();
-
- while (--num >= 0) {
- cls = args[num];
- if (cls == 0)
- _classData[num] = 0;
- else if (cls & 0x80)
- putClass(obj, cls, 1);
- else
- putClass(obj, cls, 0);
- }
-}
-
-void ScummEngine_v6::o6_getState() {
- push(getState(pop()));
-}
-
-void ScummEngine_v6::o6_setState() {
- int state = pop();
- int obj = pop();
-
- putState(obj, state);
- markObjectRectAsDirty(obj);
- if (_bgNeedsRedraw)
- clearDrawObjectQueue();
-}
-
-void ScummEngine_v6::o6_setOwner() {
- int owner = pop();
- int obj = pop();
- setOwnerOf(obj, owner);
-}
-
-void ScummEngine_v6::o6_getOwner() {
- push(getOwner(pop()));
-}
-
-void ScummEngine_v6::o6_startSound() {
- int offset = 0;
-
- // In Fatty Bear's Birthday Surprise the piano uses offsets 1 - 23 to
- // indicate which note to play, but only when using the standard piano
- // sound. See also o60_soundOps()
- if (_heversion >= 60 && (_gameId != GID_PUTTDEMO))
- offset = pop();
-
-#ifndef DISABLE_SCUMM_7_8
- if (_features & GF_DIGI_IMUSE)
- _imuseDigital->startSfx(pop(), 64);
- else
-#endif
- _sound->addSoundToQueue(pop(), offset);
-}
-
-void ScummEngine_v6::o6_stopSound() {
- _sound->stopSound(pop());
-}
-
-void ScummEngine_v6::o6_startMusic() {
- if (_features & GF_DIGI_IMUSE)
- error("o6_startMusic() It shouldn't be called here for imuse digital");
-
- _sound->addSoundToQueue(pop());
-}
-
-void ScummEngine_v6::o6_stopObjectScript() {
- stopObjectScript(pop());
-}
-
-void ScummEngine_v6::o6_panCameraTo() {
- if (_version >= 7) {
- int y = pop();
- int x = pop();
- panCameraTo(x, y);
- } else {
- panCameraTo(pop(), 0);
- }
-}
-
-void ScummEngine_v6::o6_actorFollowCamera() {
- if (_version >= 7)
- setCameraFollows(derefActor(pop(), "actorFollowCamera"));
- else
- actorFollowCamera(pop());
-}
-
-void ScummEngine_v6::o6_setCameraAt() {
- if (_version >= 7) {
- int x, y;
-
- camera._follows = 0;
- VAR(VAR_CAMERA_FOLLOWED_ACTOR) = 0;
-
- y = pop();
- x = pop();
-
- setCameraAt(x, y);
- } else {
- setCameraAtEx(pop());
- }
-}
-
-void ScummEngine_v6::o6_loadRoom() {
- int room = pop();
- startScene(room, 0, 0);
- if (_heversion >= 61) {
- setCameraAt(camera._cur.x, 0);
- }
- _fullRedraw = true;
-}
-
-void ScummEngine_v6::o6_stopScript() {
- int script = pop();
- if (script == 0)
- stopObjectCode();
- else
- stopScript(script);
-}
-
-void ScummEngine_v6::o6_walkActorToObj() {
- int act, obj, dist;
- Actor *a, *a2;
- int x, y;
-
- dist = pop();
- obj = pop();
- act = pop();
- a = derefActor(act, "o6_walkActorToObj");
-
- if (obj >= _numActors) {
- int wio = whereIsObject(obj);
-
- if (wio != WIO_FLOBJECT && wio != WIO_ROOM)
- return;
-
- int dir;
- getObjectXYPos(obj, x, y, dir);
- a->startWalkActor(x, y, dir);
- } else {
- a2 = derefActorSafe(obj, "o6_walkActorToObj(2)");
- if (_gameId == GID_SAMNMAX && a2 == 0) {
- // WORKAROUND bug #742676 SAM: Fish Farm. Note quite sure why it
- // happens, whether it's normal or due to a bug in the ScummVM code.
- debug(0, "o6_walkActorToObj: invalid actor %d", obj);
- return;
- }
- if (!a->isInCurrentRoom() || !a2->isInCurrentRoom())
- return;
- if (dist == 0) {
- dist = a2->_scalex * a2->_width / 0xFF;
- dist += dist / 2;
- }
- x = a2->_pos.x;
- y = a2->_pos.y;
- if (x < a->_pos.x)
- x += dist;
- else
- x -= dist;
- a->startWalkActor(x, y, -1);
- }
-}
-
-void ScummEngine_v6::o6_walkActorTo() {
- int x, y;
- y = pop();
- x = pop();
- Actor *a = derefActor(pop(), "o6_walkActorTo");
- a->startWalkActor(x, y, -1);
-}
-
-void ScummEngine_v6::o6_putActorAtXY() {
- int room, x, y, act;
- Actor *a;
-
- room = pop();
- y = pop();
- x = pop();
- act = pop();
- a = derefActor(act, "o6_putActorAtXY");
-
- if (room == 0xFF || room == 0x7FFFFFFF) {
- room = a->_room;
- } else {
- if (a->_visible && _currentRoom != room && getTalkingActor() == a->_number) {
- stopTalk();
- }
- if (room != 0)
- a->_room = room;
- }
- a->putActor(x, y, room);
-}
-
-
-void ScummEngine_v6::o6_putActorAtObject() {
- int room, obj, x, y;
- Actor *a;
-
- obj = popRoomAndObj(&room);
-
- a = derefActor(pop(), "o6_putActorAtObject");
- if (whereIsObject(obj) != WIO_NOT_FOUND) {
- getObjectXYPos(obj, x, y);
- } else {
- x = 160;
- y = 120;
- }
- if (room == 0xFF)
- room = a->_room;
- a->putActor(x, y, room);
-}
-
-void ScummEngine_v6::o6_faceActor() {
- int obj = pop();
- Actor *a = derefActor(pop(), "o6_faceActor");
- a->faceToObject(obj);
-}
-
-void ScummEngine_v6::o6_animateActor() {
- int anim = pop();
- int act = pop();
- if (_gameId == GID_TENTACLE && _roomResource == 57 &&
- vm.slot[_currentScript].number == 19 && act == 593) {
- // WORKAROUND bug #743363: This very odd case (animateActor(593,250))
- // occurs in DOTT, in the cutscene after George cuts down the "cherry
- // tree" and the tree Laverne is trapped in vanishes...
- // Not sure if this means animateActor somehow also must work for objects
- // (593 is the time machine in room 57), or if this is simply a script bug.
- act = 6;
- }
- if (_gameId == GID_SAMNMAX && _roomResource == 35 &&
- vm.slot[_currentScript].number == 202 && act == 4 && anim == 14) {
- // WORKAROUND bug #1223621 (Animation glitch at World of Fish).
- // Before starting animation 14 of the fisherman, make sure he isn't
- // talking anymore. This appears to be a bug in the original game as well.
- if (getTalkingActor() == 4) {
- stopTalk();
- }
- }
- Actor *a = derefActor(act, "o6_animateActor");
- a->animateActor(anim);
-}
-
-void ScummEngine_v6::o6_doSentence() {
- int verb, objectA, objectB, dummy = 0;
-
- objectB = pop();
- if (_version < 8)
- dummy = pop(); // dummy pop (in Sam&Max, seems to be always 0 or 130)
- objectA = pop();
- verb = pop();
-
- doSentence(verb, objectA, objectB);
-}
-
-void ScummEngine_v6::o6_pickupObject() {
- int obj, room;
- int i;
-
- obj = popRoomAndObj(&room);
- if (room == 0)
- room = _roomResource;
-
- for (i = 0; i < _numInventory; i++) {
- if (_inventory[i] == (uint16)obj) {
- putOwner(obj, VAR(VAR_EGO));
- runInventoryScript(obj);
- return;
- }
- }
-
- addObjectToInventory(obj, room);
- putOwner(obj, VAR(VAR_EGO));
- putClass(obj, kObjectClassUntouchable, 1);
- putState(obj, 1);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
- runInventoryScript(obj);
-}
-
-void ScummEngine_v6::o6_loadRoomWithEgo() {
- Actor *a;
- int obj, room, x, y;
-
- y = pop();
- x = pop();
-
- obj = popRoomAndObj(&room);
-
- a = derefActor(VAR(VAR_EGO), "o6_loadRoomWithEgo");
- a->putActor(0, 0, room);
- _egoPositioned = false;
-
- VAR(VAR_WALKTO_OBJ) = obj;
- startScene(a->_room, a, obj);
- VAR(VAR_WALKTO_OBJ) = 0;
-
- if (_version == 6) {
- camera._cur.x = camera._dest.x = a->_pos.x;
- setCameraFollows(a);
- }
-
- _fullRedraw = true;
-
- if (x != -1 && x != 0x7FFFFFFF) {
- a->startWalkActor(x, y, -1);
- }
-}
-
-void ScummEngine_v6::o6_getRandomNumber() {
- int rnd;
- rnd = _rnd.getRandomNumber(pop());
- if (VAR_RANDOM_NR != 0xFF)
- VAR(VAR_RANDOM_NR) = rnd;
- push(rnd);
-}
-
-void ScummEngine_v6::o6_getRandomNumberRange() {
- int max = pop();
- int min = pop();
- int rnd = _rnd.getRandomNumberRng(min, max);
- if (VAR_RANDOM_NR != 0xFF)
- VAR(VAR_RANDOM_NR) = rnd;
- push(rnd);
-}
-
-void ScummEngine_v6::o6_isScriptRunning() {
- push(isScriptRunning(pop()));
-}
-
-void ScummEngine_v6::o6_isRoomScriptRunning() {
- push(isRoomScriptRunning(pop()));
-}
-
-void ScummEngine_v6::o6_getActorMoving() {
- Actor *a = derefActor(pop(), "o6_getActorMoving");
- push(a->_moving);
-}
-
-void ScummEngine_v6::o6_getActorRoom() {
- int act = pop();
-
- if (act == 0) {
- // This case occurs at the very least in COMI. That's because in COMI's script 28,
- // there is a check which looks as follows:
- // if (((VAR_TALK_ACTOR != 0) && (VAR_HAVE_MSG == 1)) &&
- // (getActorRoom(VAR_TALK_ACTOR) == VAR_ROOM))
- // Due to the way this is represented in bytecode, the engine cannot
- // short circuit. Hence, even though this would be perfectly fine code
- // in C/C++, here it can (and does) lead to getActorRoom(0) being
- // invoked. We silently ignore this.
- push(0);
- return;
- }
-
- if (act == 255) {
- // This case also occurs in COMI...
- push(0);
- return;
- }
-
- Actor *a = derefActor(act, "o6_getActorRoom");
- push(a->_room);
-}
-
-void ScummEngine_v6::o6_getActorWalkBox() {
- Actor *a = derefActor(pop(), "o6_getActorWalkBox");
- push(a->_ignoreBoxes ? 0 : a->_walkbox);
-}
-
-void ScummEngine_v6::o6_getActorCostume() {
- Actor *a = derefActor(pop(), "o6_getActorCostume");
- push(a->_costume);
-}
-
-void ScummEngine_v6::o6_getActorElevation() {
- Actor *a = derefActor(pop(), "o6_getActorElevation");
- push(a->getElevation());
-}
-
-void ScummEngine_v6::o6_getActorWidth() {
- Actor *a = derefActor(pop(), "o6_getActorWidth");
- push(a->_width);
-}
-
-void ScummEngine_v6::o6_getActorScaleX() {
- Actor *a = derefActor(pop(), "o6_getActorScale");
- push(a->_scalex);
-}
-
-void ScummEngine_v6::o6_getActorAnimCounter1() {
- Actor *a = derefActor(pop(), "o6_getActorAnimCounter");
- push(a->_cost.animCounter);
-}
-
-void ScummEngine_v6::o6_getAnimateVariable() {
- int var = pop();
- Actor *a = derefActor(pop(), "o6_getAnimateVariable");
- push(a->getAnimVar(var));
-}
-
-void ScummEngine_v6::o6_isActorInBox() {
- int box = pop();
- Actor *a = derefActor(pop(), "o6_isActorInBox");
- push(checkXYInBoxBounds(box, a->_pos.x, a->_pos.y));
-}
-
-void ScummEngine_v6::o6_getActorLayer() {
- Actor *a = derefActor(pop(), "getActorLayer");
- push(a->_layer);
-}
-
-void ScummEngine_v6::o6_getObjectX() {
- push(getObjX(pop()));
-}
-
-void ScummEngine_v6::o6_getObjectY() {
- push(getObjY(pop()));
-}
-
-void ScummEngine_v6::o6_getObjectOldDir() {
- push(getObjOldDir(pop()));
-}
-
-void ScummEngine_v6::o6_getObjectNewDir() {
- push(getObjNewDir(pop()));
-}
-
-void ScummEngine_v6::o6_findInventory() {
- int idx = pop();
- int owner = pop();
- push(findInventory(owner, idx));
-}
-
-void ScummEngine_v6::o6_getInventoryCount() {
- push(getInventoryCount(pop()));
-}
-
-void ScummEngine_v6::o6_getVerbFromXY() {
- int y = pop();
- int x = pop();
- int over = findVerbAtPos(x, y);
- if (over)
- over = _verbs[over].verbid;
- push(over);
-}
-
-void ScummEngine_v6::o6_beginOverride() {
- beginOverride();
-}
-
-void ScummEngine_v6::o6_endOverride() {
- endOverride();
-}
-
-void ScummEngine_v6::o6_setObjectName() {
- int obj = pop();
- setObjectName(obj);
-}
-
-void ScummEngine_v6::o6_isSoundRunning() {
- int snd = pop();
-
- if (snd)
- snd = _sound->isSoundRunning(snd);
-
- push(snd);
-}
-
-void ScummEngine_v6::o6_setBoxFlags() {
- int table[65];
- int num, value;
-
- value = pop();
- num = getStackList(table, ARRAYSIZE(table));
-
- while (--num >= 0) {
- setBoxFlags(table[num], value);
- }
-}
-
-void ScummEngine_v6::o6_createBoxMatrix() {
- createBoxMatrix();
-
- if ((_gameId == GID_DIG) || (_gameId == GID_CMI))
- putActors();
-}
-
-void ScummEngine_v6::o6_resourceRoutines() {
- int resid;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 100: // SO_LOAD_SCRIPT
- resid = pop();
- if (_version >= 7)
- if (resid >= _numGlobalScripts)
- break;
- ensureResourceLoaded(rtScript, resid);
- break;
- case 101: // SO_LOAD_SOUND
- resid = pop();
- ensureResourceLoaded(rtSound, resid);
- break;
- case 102: // SO_LOAD_COSTUME
- resid = pop();
- ensureResourceLoaded(rtCostume, resid);
- break;
- case 103: // SO_LOAD_ROOM
- resid = pop();
- ensureResourceLoaded(rtRoom, resid);
- break;
- case 104: // SO_NUKE_SCRIPT
- resid = pop();
- if (_version >= 7)
- if (resid >= _numGlobalScripts)
- break;
- res.setResourceCounter(rtScript, resid, 0x7F);
- break;
- case 105: // SO_NUKE_SOUND
- resid = pop();
- res.setResourceCounter(rtSound, resid, 0x7F);
- break;
- case 106: // SO_NUKE_COSTUME
- resid = pop();
- res.setResourceCounter(rtCostume, resid, 0x7F);
- break;
- case 107: // SO_NUKE_ROOM
- resid = pop();
- res.setResourceCounter(rtRoom, resid, 0x7F);
- break;
- case 108: // SO_LOCK_SCRIPT
- resid = pop();
- if (resid >= _numGlobalScripts)
- break;
- res.lock(rtScript, resid);
- break;
- case 109: // SO_LOCK_SOUND
- resid = pop();
- res.lock(rtSound, resid);
- break;
- case 110: // SO_LOCK_COSTUME
- resid = pop();
- res.lock(rtCostume, resid);
- break;
- case 111: // SO_LOCK_ROOM
- resid = pop();
- if (resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
- res.lock(rtRoom, resid);
- break;
- case 112: // SO_UNLOCK_SCRIPT
- resid = pop();
- if (resid >= _numGlobalScripts)
- break;
- res.unlock(rtScript, resid);
- break;
- case 113: // SO_UNLOCK_SOUND
- resid = pop();
- res.unlock(rtSound, resid);
- break;
- case 114: // SO_UNLOCK_COSTUME
- resid = pop();
- res.unlock(rtCostume, resid);
- break;
- case 115: // SO_UNLOCK_ROOM
- resid = pop();
- if (resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
- res.unlock(rtRoom, resid);
- break;
- case 116: // SO_CLEAR_HEAP
- /* this is actually a scumm message */
- error("clear heap not working yet");
- break;
- case 117: // SO_LOAD_CHARSET
- resid = pop();
- loadCharset(resid);
- break;
- case 118: // SO_NUKE_CHARSET
- resid = pop();
- nukeCharset(resid);
- break;
- case 119: // SO_LOAD_OBJECT
- {
- int room, obj = popRoomAndObj(&room);
- loadFlObject(obj, room);
- break;
- }
- default:
- error("o6_resourceRoutines: default case %d", subOp);
- }
-}
-
-
-void ScummEngine_v6::o6_roomOps() {
- int a, b, c, d, e;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 172: // SO_ROOM_SCROLL
- b = pop();
- a = pop();
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
-
- case 174: // SO_ROOM_SCREEN
- b = pop();
- a = pop();
- initScreens(a, b);
- break;
-
- case 175: // SO_ROOM_PALETTE
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setPalColor(d, a, b, c);
- break;
-
- case 176: // SO_ROOM_SHAKE_ON
- setShake(1);
- break;
-
- case 177: // SO_ROOM_SHAKE_OFF
- setShake(0);
- break;
-
- case 179: // SO_ROOM_INTENSITY
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, a, a, b, c);
- break;
-
- case 180: // SO_ROOM_SAVEGAME
- _saveTemporaryState = true;
- _saveLoadSlot = pop();
- _saveLoadFlag = pop();
- if (_gameId == GID_TENTACLE)
- _saveSound = (_saveLoadSlot != 0);
- break;
-
- case 181: // SO_ROOM_FADE
- a = pop();
- if (a) {
- _switchRoomEffect = (byte)(a & 0xFF);
- _switchRoomEffect2 = (byte)(a >> 8);
- } else {
- fadeIn(_newEffect);
- }
- break;
-
- case 182: // SO_RGB_ROOM_INTENSITY
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, b, c, d, e);
- break;
-
- case 183: // SO_ROOM_SHADOW
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setupShadowPalette(a, b, c, d, e, 0, 256);
- break;
-
- case 184: // SO_SAVE_STRING
- error("save string not implemented");
- break;
-
- case 185: // SO_LOAD_STRING
- error("load string not implemented");
- break;
-
- case 186: // SO_ROOM_TRANSFORM
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- palManipulateInit(a, b, c, d);
- break;
-
- case 187: // SO_CYCLE_SPEED
- b = pop();
- a = pop();
- checkRange(16, 1, a, "o6_roomOps: 187: color cycle out of range (%d)");
- _colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0;
- break;
-
- case 213: // SO_ROOM_NEW_PALETTE
- a = pop();
-
- // This opcode is used when turning off noir mode in Sam & Max,
- // but since our implementation of this feature doesn't change
- // the original palette there's no need to reload it. Doing it
- // this way, we avoid some graphics glitches that the original
- // interpreter had.
-
- if (_gameId == GID_SAMNMAX && vm.slot[_currentScript].number == 64)
- setDirtyColors(0, 255);
- else
- setPalette(a);
- break;
- default:
- error("o6_roomOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v6::o6_actorOps() {
- Actor *a;
- int i, j, k;
- int args[8];
-
- byte subOp = fetchScriptByte();
- if (subOp == 197) {
- _curActor = pop();
- return;
- }
-
- a = derefActorSafe(_curActor, "o6_actorOps");
- if (!a)
- return;
-
- switch (subOp) {
- case 76: // SO_COSTUME
- a->setActorCostume(pop());
- break;
- case 77: // SO_STEP_DIST
- j = pop();
- i = pop();
- a->setActorWalkSpeed(i, j);
- break;
- case 78: // SO_SOUND
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; i++)
- a->_sound[i] = args[i];
- break;
- case 79: // SO_WALK_ANIMATION
- a->_walkFrame = pop();
- break;
- case 80: // SO_TALK_ANIMATION
- a->_talkStopFrame = pop();
- a->_talkStartFrame = pop();
- break;
- case 81: // SO_STAND_ANIMATION
- a->_standFrame = pop();
- break;
- case 82: // SO_ANIMATION
- // dummy case in scumm6
- pop();
- pop();
- pop();
- break;
- case 83: // SO_DEFAULT
- a->initActor(0);
- break;
- case 84: // SO_ELEVATION
- a->setElevation(pop());
- break;
- case 85: // SO_ANIMATION_DEFAULT
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 86: // SO_PALETTE
- j = pop();
- i = pop();
- checkRange(255, 0, i, "Illegal palette slot %d");
- a->setPalette(i, j);
- break;
- case 87: // SO_TALK_COLOR
- a->_talkColor = pop();
- break;
- case 88: // SO_ACTOR_NAME
- loadPtrToResource(rtActorName, a->_number, NULL);
- break;
- case 89: // SO_INIT_ANIMATION
- a->_initFrame = pop();
- break;
- case 91: // SO_ACTOR_WIDTH
- a->_width = pop();
- break;
- case 92: // SO_SCALE
- i = pop();
- a->setScale(i, i);
- break;
- case 93: // SO_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 225: // SO_ALWAYS_ZCLIP
- case 94: // SO_ALWAYS_ZCLIP
- a->_forceClip = pop();
- break;
- case 95: // SO_IGNORE_BOXES
- a->_ignoreBoxes = 1;
- a->_forceClip = (_version >= 7) ? 100 : 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 96: // SO_FOLLOW_BOXES
- a->_ignoreBoxes = 0;
- a->_forceClip = (_version >= 7) ? 100 : 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 97: // SO_ANIMATION_SPEED
- a->setAnimSpeed(pop());
- break;
- case 98: // SO_SHADOW
- a->_shadowMode = pop();
- break;
- case 99: // SO_TEXT_OFFSET
- a->_talkPosY = pop();
- a->_talkPosX = pop();
- break;
- case 198: // SO_ACTOR_VARIABLE
- i = pop();
- a->setAnimVar(pop(), i);
- break;
- case 215: // SO_ACTOR_IGNORE_TURNS_ON
- a->_ignoreTurns = true;
- break;
- case 216: // SO_ACTOR_IGNORE_TURNS_OFF
- a->_ignoreTurns = false;
- break;
- case 217: // SO_ACTOR_NEW
- a->initActor(2);
- break;
- case 227: // SO_ACTOR_DEPTH
- a->_layer = pop();
- break;
- case 228: // SO_ACTOR_WALK_SCRIPT
- a->_walkScript = pop();
- break;
- case 229: // SO_ACTOR_STOP
- a->stopActorMoving();
- a->startAnimActor(a->_standFrame);
- break;
- case 230: /* set direction */
- a->_moving &= ~MF_TURN;
- a->setDirection(pop());
- break;
- case 231: /* turn to direction */
- a->turnToDirection(pop());
- break;
- case 233: // SO_ACTOR_WALK_PAUSE
- a->_moving |= MF_FROZEN;
- break;
- case 234: // SO_ACTOR_WALK_RESUME
- a->_moving &= ~MF_FROZEN;
- break;
- case 235: // SO_ACTOR_TALK_SCRIPT
- a->_talkScript = pop();
- break;
- default:
- error("o6_actorOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v6::o6_verbOps() {
- int slot, a, b;
- VerbSlot *vs;
-
- byte subOp = fetchScriptByte();
- if (subOp == 196) {
- _curVerb = pop();
- _curVerbSlot = getVerbSlot(_curVerb, 0);
- checkRange(_numVerbs - 1, 0, _curVerbSlot, "Illegal new verb slot %d");
- return;
- }
- vs = &_verbs[_curVerbSlot];
- slot = _curVerbSlot;
- switch (subOp) {
- case 124: // SO_VERB_IMAGE
- a = pop();
- if (_curVerbSlot) {
- setVerbObject(_roomResource, a, slot);
- vs->type = kImageVerbType;
- if (_heversion >= 61)
- vs->imgindex = a;
- }
- break;
- case 125: // SO_VERB_NAME
- loadPtrToResource(rtVerb, slot, NULL);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 126: // SO_VERB_COLOR
- vs->color = pop();
- break;
- case 127: // SO_VERB_HICOLOR
- vs->hicolor = pop();
- break;
- case 128: // SO_VERB_AT
- vs->curRect.top = pop();
- vs->curRect.left = pop();
- break;
- case 129: // SO_VERB_ON
- vs->curmode = 1;
- break;
- case 130: // SO_VERB_OFF
- vs->curmode = 0;
- break;
- case 131: // SO_VERB_DELETE
- if (_heversion >= 60) {
- slot = getVerbSlot(pop(), 0);
- }
- killVerb(slot);
- break;
- case 132: // SO_VERB_NEW
- slot = getVerbSlot(_curVerb, 0);
- if (slot == 0) {
- for (slot = 1; slot < _numVerbs; slot++) {
- if (_verbs[slot].verbid == 0)
- break;
- }
- if (slot == _numVerbs)
- error("Too many verbs");
- _curVerbSlot = slot;
- }
- vs = &_verbs[slot];
- vs->verbid = _curVerb;
- vs->color = 2;
- vs->hicolor = 0;
- vs->dimcolor = 8;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
- case 133: // SO_VERB_DIMCOLOR
- vs->dimcolor = pop();
- break;
- case 134: // SO_VERB_DIM
- vs->curmode = 2;
- break;
- case 135: // SO_VERB_KEY
- vs->key = pop();
- break;
- case 136: // SO_VERB_CENTER
- vs->center = 1;
- break;
- case 137: // SO_VERB_NAME_STR
- a = pop();
- if (a == 0) {
- loadPtrToResource(rtVerb, slot, (const byte *)"");
- } else {
- loadPtrToResource(rtVerb, slot, getStringAddress(a));
- }
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 139: // SO_VERB_IMAGE_IN_ROOM
- b = pop();
- a = pop();
-
- if (slot && a != vs->imgindex) {
- setVerbObject(b, a, slot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 140: // SO_VERB_BAKCOLOR
- vs->bkcolor = pop();
- break;
- case 255:
- drawVerb(slot, 0);
- verbMouseOver(0);
- break;
- default:
- error("o6_verbops: default case %d", subOp);
- }
-}
-
-void ScummEngine_v6::o6_getActorFromXY() {
- int y = pop();
- int x = pop();
- int r = getActorFromPos(x, y);
- push(r);
-}
-
-void ScummEngine_v6::o6_findObject() {
- int y = pop();
- int x = pop();
- int r = findObject(x, y);
- push(r);
-}
-
-void ScummEngine_v6::o6_pseudoRoom() {
- int list[100];
- int num, a, value;
-
- num = getStackList(list, ARRAYSIZE(list));
- value = pop();
-
- while (--num >= 0) {
- a = list[num];
- if (a > 0x7F)
- _resourceMapper[a & 0x7F] = value;
- }
-}
-
-void ScummEngine_v6::o6_getVerbEntrypoint() {
- int e = pop();
- int v = pop();
- push(getVerbEntrypoint(v, e));
-}
-
-void ScummEngine_v6::o6_arrayOps() {
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord();
- int b, c, d, len;
- ArrayHeader *ah;
- int list[128];
-
- switch (subOp) {
- case 205: // SO_ASSIGN_STRING
- b = pop();
- len = resStrLen(_scriptPointer);
- ah = defineArray(array, kStringArray, 0, len + 1);
- copyScriptString(ah->data + b);
- break;
- case 208: // SO_ASSIGN_INT_LIST
- b = pop();
- c = pop();
- d = readVar(array);
- if (d == 0) {
- defineArray(array, kIntArray, 0, b + c);
- }
- while (c--) {
- writeArray(array, 0, b + c, pop());
- }
- break;
- case 212: // SO_ASSIGN_2DIM_LIST
- b = pop();
- len = getStackList(list, ARRAYSIZE(list));
- d = readVar(array);
- if (d == 0)
- error("Must DIM a two dimensional array before assigning");
- c = pop();
- while (--len >= 0) {
- writeArray(array, c, b + len, list[len]);
- }
- break;
- default:
- error("o6_arrayOps: default case %d (array %d)", subOp, array);
- }
-}
-
-void ScummEngine_v6::o6_saveRestoreVerbs() {
- int a, b, c;
- int slot, slot2;
-
- c = pop();
- b = pop();
- a = pop();
-
- byte subOp = fetchScriptByte();
- if (_version == 8) {
- subOp = (subOp - 141) + 0xB4;
- }
-
- switch (subOp) {
- case 141: // SO_SAVE_VERBS
- while (a <= b) {
- slot = getVerbSlot(a, 0);
- if (slot && _verbs[slot].saveid == 0) {
- _verbs[slot].saveid = c;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 142: // SO_RESTORE_VERBS
- while (a <= b) {
- slot = getVerbSlot(a, c);
- if (slot) {
- slot2 = getVerbSlot(a, 0);
- if (slot2)
- killVerb(slot2);
- slot = getVerbSlot(a, c);
- _verbs[slot].saveid = 0;
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- a++;
- }
- break;
- case 143: // SO_DELETE_VERBS
- while (a <= b) {
- slot = getVerbSlot(a, c);
- if (slot)
- killVerb(slot);
- a++;
- }
- break;
- default:
- error("o6_saveRestoreVerbs: default case");
- }
-}
-
-void ScummEngine_v6::o6_drawBox() {
- int x, y, x2, y2, color;
- color = pop();
- y2 = pop();
- x2 = pop();
- y = pop();
- x = pop();
- drawBox(x, y, x2, y2, color);
-}
-
-void ScummEngine_v6::o6_wait() {
- int actnum;
- int offs = -2;
- Actor *a;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 168: // SO_WAIT_FOR_ACTOR Wait for actor
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o6_wait:168");
- if (a->isInCurrentRoom() && a->_moving)
- break;
- return;
- case 169: // SO_WAIT_FOR_MESSAGE Wait for message
- if (VAR(VAR_HAVE_MSG))
- break;
- return;
- case 170: // SO_WAIT_FOR_CAMERA Wait for camera
- if (_version >= 7) {
- if (camera._dest != camera._cur)
- break;
- } else {
- if (camera._cur.x / 8 != camera._dest.x / 8)
- break;
- }
-
- return;
- case 171: // SO_WAIT_FOR_SENTENCE
- if (_sentenceNum) {
- if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- }
- if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- case 226: // SO_WAIT_FOR_ANIMATION
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o6_wait:226");
- if (a->isInCurrentRoom() && a->_needRedraw)
- break;
- return;
- case 232: // SO_WAIT_FOR_TURN
- // FIXME: This opcode is really odd. It's used a lot in The Dig.
- // But sometimes it receives the actor ID as params, and sometimes an
- // angle. However in (almost?) all cases, just before calling it, _curActor
- // is set, so we can use it. I tried to add code that detects if an angle
- // is passed, and if so, wait till that angle is reached, but that leads to hangs.
- // It would be very good if somebody could disassmble the original code
- // for this opcode so that we could figure out what's really going on here.
- //
- // For now, if the value passed in is divisible by 45, assume it is an
- // angle, and use _curActor as the actor to wait for.
- offs = fetchScriptWordSigned();
- actnum = pop();
- if (actnum % 45 == 0) {
- actnum = _curActor;
- }
- a = derefActor(actnum, "o6_wait:232b");
- if (a->isInCurrentRoom() && a->_moving & MF_TURN)
- break;
- return;
- default:
- error("o6_wait: default case 0x%x", subOp);
- }
-
- _scriptPointer += offs;
- o6_breakHere();
-}
-
-void ScummEngine_v6::o6_soundKludge() {
- int list[16];
- int num = getStackList(list, ARRAYSIZE(list));
-
- _sound->soundKludge(list, num);
-
- // WORKAROUND for bug #1398195: The room-11-2016 script contains a
- // slight bug causing it to busy-wait for a sound to finish. Even under
- // the best of circumstances, this will cause the game to hang briefly.
- // On platforms where threading is cooperative, it will cause the game
- // to hang indefinitely. We identify the buggy part of the script by
- // looking for a soundKludge() opcode immediately followed by a jump.
-
- if (_gameId == GID_CMI && _roomResource == 11 && vm.slot[_currentScript].number == 2016 && *_scriptPointer == 0x66) {
- debug(3, "Working around script bug in room-11-2016");
- o6_breakHere();
- }
-}
-
-void ScummEngine_v6::o6_isAnyOf() {
- int list[100];
- int num;
- int32 val;
-
- num = getStackList(list, ARRAYSIZE(list));
- val = pop();
-
- while (--num >= 0) {
- if (list[num] == val) {
- push(1);
- return;
- }
- }
-
- push(0);
-}
-
-void ScummEngine_v6::o6_systemOps() {
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 158: // SO_RESTART
- restart();
- break;
- case 159: // SO_PAUSE
- pauseGame();
- break;
- case 160: // SO_QUIT
- shutDown();
- break;
- default:
- error("o6_systemOps invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v6::o6_delay() {
- uint32 delay = (uint16)pop();
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = ssPaused;
- o6_breakHere();
-}
-
-void ScummEngine_v6::o6_delaySeconds() {
- uint32 delay = (uint32)pop();
- delay = delay * 60;
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = ssPaused;
- o6_breakHere();
-}
-
-void ScummEngine_v6::o6_delayMinutes() {
- uint32 delay = (uint16)pop() * 3600;
- vm.slot[_currentScript].delay = delay;
- vm.slot[_currentScript].status = ssPaused;
- o6_breakHere();
-}
-
-void ScummEngine_v6::o6_stopSentence() {
- _sentenceNum = 0;
- stopScript(VAR(VAR_SENTENCE_SCRIPT));
- clearClickedStatus();
-}
-
-void ScummEngine_v6::o6_printLine() {
- _actorToPrintStrFor = 0xFF;
- decodeParseString(0, 0);
-}
-
-void ScummEngine_v6::o6_printText() {
- decodeParseString(1, 0);
-}
-
-void ScummEngine_v6::o6_printDebug() {
- decodeParseString(2, 0);
-}
-
-void ScummEngine_v6::o6_printSystem() {
- decodeParseString(3, 0);
-}
-
-void ScummEngine_v6::o6_printActor() {
- decodeParseString(0, 1);
-}
-
-void ScummEngine_v6::o6_printEgo() {
- push(VAR(VAR_EGO));
- decodeParseString(0, 1);
-}
-
-void ScummEngine_v6::o6_talkActor() {
- _actorToPrintStrFor = pop();
-
- _string[0].loadDefault();
- actorTalk(_scriptPointer);
-
- _scriptPointer += resStrLen(_scriptPointer) + 1;
-}
-
-void ScummEngine_v6::o6_talkEgo() {
- push(VAR(VAR_EGO));
- o6_talkActor();
-}
-
-void ScummEngine_v6::o6_dimArray() {
- int data;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 199: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 200: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 201: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 202: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 203: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- case 204: // SO_UNDIM_ARRAY
- nukeArray(fetchScriptWord());
- return;
- default:
- error("o6_dimArray: default case %d", subOp);
- }
-
- defineArray(fetchScriptWord(), data, 0, pop());
-}
-
-void ScummEngine_v6::o6_dummy() {
- if (_heversion >= 60) {
- stopObjectCode();
- }
-}
-
-void ScummEngine_v6::o6_dim2dimArray() {
- int a, b, data;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 199: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 200: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 201: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 202: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 203: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- default:
- error("o6_dim2dimArray: default case %d", subOp);
- }
-
- b = pop();
- a = pop();
- defineArray(fetchScriptWord(), data, a, b);
-}
-
-void ScummEngine_v6::o6_abs() {
- int a = pop();
- push(ABS(a));
-}
-
-void ScummEngine_v6::o6_distObjectObject() {
- int a, b;
- b = pop();
- a = pop();
- push(getDistanceBetween(true, a, 0, true, b, 0));
-}
-
-void ScummEngine_v6::o6_distObjectPt() {
- int a, b, c;
- c = pop();
- b = pop();
- a = pop();
- push(getDistanceBetween(true, a, 0, false, b, c));
-}
-
-void ScummEngine_v6::o6_distPtPt() {
- int a, b, c, d;
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- push(getDistanceBetween(false, a, b, false, c, d));
-}
-
-void ScummEngine_v6::o6_drawBlastObject() {
- int args[16];
- int a, b, c, d, e;
-
- getStackList(args, ARRAYSIZE(args));
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- enqueueObject(a, b, c, d, e, 0xFF, 0xFF, 1, 0);
-}
-
-// Set BOMP processing window
-void ScummEngine_v6::o6_setBlastObjectWindow() {
- pop();
- pop();
- pop();
- pop();
-
- // None of the scripts of The Dig and Full Throttle use this opcode.
- // Sam & Max only uses it at the beginning of the highway subgame. In
- // the original interpreter pop'ed arguments are just ignored and the
- // clipping blastObject window is defined with (0, 0, 320, 200)...
- // which matches the screen dimensions and thus, doesn't require
- // another clipping operation.
- // So, we just handle this as no-op opcode.
-}
-
-void ScummEngine_v6::o6_kernelSetFunctions() {
- int args[30];
- int num;
- Actor *a;
-
- num = getStackList(args, ARRAYSIZE(args));
-
- if (_version >= 7) {
- switch (args[0]) {
- case 4:
- grabCursor(args[1], args[2], args[3], args[4]);
- break;
-#ifndef DISABLE_SCUMM_7_8
- case 6: {
- if (_smushFrameRate == 0)
- _smushFrameRate = 14;
-
- // SMUSH movie playback
- if (args[1] == 0) {
- assert(getStringAddressVar(VAR_VIDEONAME));
- if (strcmp((char *)getStringAddressVar(VAR_VIDEONAME), "sq3.san") == 0)
- _smushFrameRate = 14;
-
- SmushPlayer *sp = new SmushPlayer(this, _smushFrameRate);
-
- // Correct incorrect smush filename in Macintosh FT demo
- if ((_gameId == GID_FT) && (_features & GF_DEMO) && (_platform == Common::kPlatformMacintosh) &&
- (strcmp((char *)getStringAddressVar(VAR_VIDEONAME), "jumpgorge.san") == 0))
- sp->play("jumpgorg.san");
- else
- sp->play((char *)getStringAddressVar(VAR_VIDEONAME));
- delete sp;
- } else if (_gameId == GID_FT) {
- const int insaneVarNum = ((_features & GF_DEMO) && (_platform == Common::kPlatformPC))
- ? 232 : 233;
-
- _insaneRunning = true;
- _insane->setSmushParams(_smushFrameRate);
- _insane->runScene(insaneVarNum);
- _insaneRunning = false;
- }
- }
- break;
-#endif
- case 12:
- setCursorFromImg(args[1], (uint) - 1, args[2]);
- break;
- case 13:
- derefActor(args[1], "o6_kernelSetFunctions:13")->remapActorPalette(args[2], args[3], args[4], -1);
- break;
- case 14:
- derefActor(args[1], "o6_kernelSetFunctions:14")->remapActorPalette(args[2], args[3], args[4], args[5]);
- break;
- case 15:
- _smushFrameRate = args[1];
- break;
- case 16:
- case 17:
- enqueueText(getStringAddressVar(VAR_STRING2DRAW), args[3], args[4], args[2], args[1], (args[0] == 16));
- break;
- case 20:
- // it's used for turn on/off 'RadioChatter' effect for voice in the dig, but i's not needed
- break;
- case 107:
- a = derefActor(args[1], "o6_kernelSetFunctions: 107");
- a->setScale((unsigned char)args[2], -1);
- break;
- case 108:
- setupShadowPalette(args[1], args[2], args[3], args[4], args[5], args[6]);
- break;
- case 109:
- setupShadowPalette(0, args[1], args[2], args[3], args[4], args[5]);
- break;
- case 114:
- error("o6_kernelSetFunctions: stub114()");
- break;
- case 117:
- freezeScripts(2);
- break;
- case 118:
- enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 3);
- break;
- case 119:
- enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0);
- break;
- case 124:
- _saveSound = args[1];
- break;
- case 215:
- ConfMan.set("subtitles", args[1] != 0);
- break;
- default:
- error("o6_kernelSetFunctions: default case %d (param count %d)", args[0], num);
- break;
- }
- } else {
- switch (args[0]) {
- case 3:
- // Dummy case
- break;
- case 4:
- grabCursor(args[1], args[2], args[3], args[4]);
- break;
- case 5:
- fadeOut(args[1]);
- break;
- case 6:
- _fullRedraw = true;
- redrawBGAreas();
- setActorRedrawFlags();
- processActors();
- fadeIn(args[1]);
- break;
- case 8:
- startManiac();
- break;
- case 9:
- killAllScriptsExceptCurrent();
- break;
- case 104: /* samnmax */
- nukeFlObjects(args[2], args[3]);
- break;
- case 107: /* set actor scale */
- a = derefActor(args[1], "o6_kernelSetFunctions: 107");
- a->setScale((unsigned char)args[2], -1);
- break;
- case 108: /* create proc_special_palette */
- case 109:
- // Case 108 and 109 share the same function
- if (num != 6)
- error("o6_kernelSetFunctions sub op %d: expected 6 params but got %d", args[0], num);
- setupShadowPalette(args[3], args[4], args[5], args[1], args[2], 0, 256);
- break;
- case 110:
- _charset->clearCharsetMask();
- break;
- case 111:
- a = derefActor(args[1], "o6_kernelSetFunctions: 111");
- a->_shadowMode = args[2] + args[3];
- break;
- case 112: /* palette shift? */
- setupShadowPalette(args[3], args[4], args[5], args[1], args[2], args[6], args[7]);
- break;
- case 114:
- // Sam & Max film noir mode
- if (_gameId == GID_SAMNMAX) {
- // At this point ScummVM will already have set
- // variable 0x8000 to indicate that the game is
- // in film noir mode. All we have to do here is
- // to mark the palette as "dirty", because
- // updatePalette() will desaturate the colors
- // as they are uploaded to the backend.
- //
- // This actually works better than the original
- // interpreter, where actors would sometimes
- // still be drawn in color.
- setDirtyColors(0, 255);
- } else
- error("stub o6_kernelSetFunctions_114()");
- break;
- case 117:
- // Sam & Max uses this opcode in script-43, right
- // before a screensaver is selected.
- //
- // Sam & Max uses variable 132 to specify the number of
- // minutes of inactivity (no mouse movements) before
- // starting the screensaver, so setting it to 0 will
- // help in debugging.
- freezeScripts(0x80);
- break;
- case 119:
- enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0);
- break;
- case 120:
- swapPalColors(args[1], args[2]);
- break;
- case 122:
- VAR(VAR_SOUNDRESULT) =
- (short)_imuse->doCommand (num - 1, &args[1]);
- break;
- case 123:
- copyPalColor(args[2], args[1]);
- break;
- case 124:
- _saveSound = args[1];
- break;
- default:
- error("o6_kernelSetFunctions: default case %d (param count %d)", args[0], num);
- break;
- }
- }
-}
-
-void ScummEngine_v6::o6_kernelGetFunctions() {
- int args[30];
- int i;
- int slot;
- Actor *a;
-
- getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 113:
- // This is used for the Sam & Max paint-by-numbers mini-game
- // to find out what color to change. I think that what we have
- // the virtual mouse coordinates, because that's what used
- // everywhere else in the script.
-
- {
- VirtScreen *vs = &virtscr[0];
- if (args[1] < 0 || args[1] >= vs->w || args[2] < 0 || args[2] >= vs->h) {
- // FIXME: Until we know what to do in this case...
- debug(0, "o6_kernelGetFunctions:113: asking for pixel (%d, %d) outside of %dx%d screen", args[1], args[2], vs->w, vs->h);
- push(0);
- } else
- push(*((byte *)vs->pixels + args[1] + args[2] * vs->pitch));
- }
- break;
- case 115:
- push(getSpecialBox(args[1], args[2]));
- break;
- case 116:
- push(checkXYInBoxBounds(args[3], args[1], args[2]));
- break;
- case 206:
- push(remapPaletteColor(args[1], args[2], args[3], -1));
- break;
- case 207:
- i = getObjectIndex(args[1]);
- assert(i);
- push(_objs[i].x_pos);
- break;
- case 208:
- i = getObjectIndex(args[1]);
- assert(i);
- push(_objs[i].y_pos);
- break;
- case 209:
- i = getObjectIndex(args[1]);
- assert(i);
- push(_objs[i].width);
- break;
- case 210:
- i = getObjectIndex(args[1]);
- assert(i);
- push(_objs[i].height);
- break;
- case 211:
- /*
- 13 = thrust
- 336 = thrust
- 328 = thrust
- 27 = abort
- 97 = left
- 331 = left
- 115 = right
- 333 = right
- */
-
- push(getKeyState(args[1]));
- break;
- case 212:
- a = derefActor(args[1], "o6_kernelGetFunctions:212");
- // This is used by walk scripts
- push(a->_frame);
- break;
- case 213:
- slot = getVerbSlot(args[1], 0);
- push(_verbs[slot].curRect.left);
- break;
- case 214:
- slot = getVerbSlot(args[1], 0);
- push(_verbs[slot].curRect.top);
- break;
- case 215:
- if ((_extraBoxFlags[args[1]] & 0x00FF) == 0x00C0) {
- push(_extraBoxFlags[args[1]]);
- } else {
- push(getBoxFlags(args[1]));
- }
- break;
- default:
- error("o6_kernelGetFunctions: default case %d", args[0]);
- }
-}
-
-// FIXME: check either some warning will trigger. I am not sure that those
-// keys are queried in scripts at all
-int ScummEngine::getKeyState(int key) {
- switch (key) {
- case 0x145:
- warning("ScummEngine::getKeyState(%x) 'numlock' is probed", key);
- return 0;
- break;
- case 0x164:
- warning("ScummEngine::getKeyState(%x) 'left shift' is probed", key);
- return 0;
- break;
- case 0x165:
- warning("ScummEngine::getKeyState(%x) 'right shift' is probed", key);
- return 0;
- break;
- case 0x166:
- case 0x167:
- warning("ScummEngine::getKeyState(%x) 'alt' is probed", key);
- return 0;
- break;
- case 0x168:
- warning("ScummEngine::getKeyState(%x) 'left ctrl' is probed", key);
- return 0;
- break;
- case 0x202a:
- warning("ScummEngine::getKeyState(%x) 'gray *' is probed", key);
- return 0;
- break;
- case 0x202d:
- warning("ScummEngine::getKeyState(%x) 'gray -' is probed", key);
- return 0;
- break;
- case 0x147: // Home
- return (_keyDownMap[0x107] || _keyDownMap[0x115]) ? 1 : 0;
- break;
- case 0x148: // Up
- return (_keyDownMap[0x108] || _keyDownMap[0x111] ||
- _keyDownMap[0x38]) ? 1 : 0;
- break;
- case 0x149: // PgUp
- return (_keyDownMap[0x109] || _keyDownMap[0x118]) ? 1 : 0;
- break;
- case 0x14A: // Gray-
- return (_keyDownMap[0x10d] || _keyDownMap[0x2d]) ? 1 : 0;
- break;
- case 0x14B: // Left
- return (_keyDownMap[0x104] || _keyDownMap[0x114] ||
- _keyDownMap[0x34]) ? 1 : 0;
- break;
- case 0x14C: // 5
- return (_keyDownMap[0x105]) ? 1 : 0;
- break;
- case 0x14D: // Right
- return (_keyDownMap[0x106] || _keyDownMap[0x113] ||
- _keyDownMap[0x36]) ? 1 : 0;
- break;
- case 0x14E: // Gray+
- return (_keyDownMap[0x10e] ||
- (_keyDownMap[0x13d] && _keyDownMap[0x12f])) ? 1 : 0;
- break;
- case 0x14F: // End
- return (_keyDownMap[0x101] || _keyDownMap[0x117]) ? 1 : 0;
- break;
- case 0x150: // Down
- return (_keyDownMap[0x102] || _keyDownMap[0x112] ||
- _keyDownMap[0x32]) ? 1 : 0;
- break;
- case 0x151: // PgDn
- return (_keyDownMap[0x103] || _keyDownMap[0x119]) ? 1 : 0;
- break;
- case 0x152: // Ins
- return (_keyDownMap[0x100] || _keyDownMap[0x115]) ? 1 : 0;
- break;
- case 0x153: // Del
- return (_keyDownMap[0x10a] || _keyDownMap[0x7f]) ? 1 : 0;
- break;
- default:
- break;
- }
-
- if (key >= 0x13b && key <= 0x144) { // F1-F10
- key -= 0x13b - 0x11a;
- } else if (key >= 0x154 && key <= 0x15d) { // Shift+F1-F10
- key -= 0x154 - 0x11a; // map it to just F1-F10
-
- warning("ScummEngine::getKeyState(%x) 'Shift-F%d' is probed", key, key-0x153);
- } else if (key > 0x8000) { // Alt
- key -= 0x8000;
- key += 154; // see ScummEngine::parseEvents()
- } else if (key > 0x4000) { // Ctrl
- key -= 0x4000;
- key -= 0x40;
- } else if (key > 0x2000) { // Gray keys
- key -= 0x2000;
- warning("ScummEngine::getKeyState(%x) 'gray key' is probed", key);
- }
-
- return (_keyDownMap[key]) ? 1 : 0;
-}
-
-void ScummEngine_v6::o6_delayFrames() {
- ScriptSlot *ss = &vm.slot[_currentScript];
- if (ss->delayFrameCount == 0) {
- ss->delayFrameCount = pop();
- } else {
- ss->delayFrameCount--;
- }
- if (ss->delayFrameCount) {
- _scriptPointer--;
- o6_breakHere();
- }
-}
-
-void ScummEngine_v6::o6_pickOneOf() {
- int args[100];
- int i, num;
-
- num = getStackList(args, ARRAYSIZE(args));
- i = pop();
- if (i < 0 || i > num)
- error("o6_pickOneOf: %d out of range (0, %d)", i, num - 1);
- push(args[i]);
-}
-
-void ScummEngine_v6::o6_pickOneOfDefault() {
- int args[100];
- int i, num, def;
-
- def = pop();
- num = getStackList(args, ARRAYSIZE(args));
- i = pop();
- if (i < 0 || i >= num)
- i = def;
- else
- i = args[i];
- push(i);
-}
-
-void ScummEngine_v6::o6_stampObject() {
- int object, x, y, state;
-
- state = pop();
- y = pop();
- x = pop();
- object = pop();
- if (_version >= 7 && object < 30) {
- if (state == 0)
- state = 255;
-
- Actor *a = derefActor(object, "o6_stampObject");
- a->_scalex = state;
- a->_scaley = state;
- a->putActor(x, y, _currentRoom);
- a->_drawToBackBuf = true;
- a->drawActorCostume();
- a->_drawToBackBuf = false;
- a->drawActorCostume();
- return;
- }
-
- if (state == 0)
- state = 1;
-
- int objnum = getObjectIndex(object);
- if (objnum == -1)
- return;
-
- if (x != -1) {
- _objs[objnum].x_pos = x * 8;
- _objs[objnum].y_pos = y * 8;
- }
-
- putState(object, state);
- drawObject(objnum, 0);
-}
-
-void ScummEngine_v6::o6_stopTalking() {
- stopTalk();
-}
-
-void ScummEngine_v6::o6_findAllObjects() {
- int room = pop();
- int i = 1;
-
- if (room != _currentRoom)
- error("o6_findAllObjects: current room is not %d", room);
- writeVar(0, 0);
- defineArray(0, kIntArray, 0, _numLocalObjects + 1);
- writeArray(0, 0, 0, _numLocalObjects);
-
- while (i < _numLocalObjects) {
- writeArray(0, 0, i, _objs[i].obj_nr);
- i++;
- }
-
- push(readVar(0));
-}
-
-void ScummEngine_v6::shuffleArray(int num, int minIdx, int maxIdx) {
- int range = maxIdx - minIdx;
- int count = range * 2;
-
- // Shuffle the array 'num'
- while (count--) {
- // Determine two random elements...
- int rand1 = _rnd.getRandomNumber(range) + minIdx;
- int rand2 = _rnd.getRandomNumber(range) + minIdx;
-
- // ...and swap them
- int val1 = readArray(num, 0, rand1);
- int val2 = readArray(num, 0, rand2);
- writeArray(num, 0, rand1, val2);
- writeArray(num, 0, rand2, val1);
- }
-}
-
-void ScummEngine_v6::o6_shuffle() {
- int b = pop();
- int a = pop();
- shuffleArray(fetchScriptWord(), a, b);
-}
-
-void ScummEngine_v6::o6_pickVarRandom() {
- int num;
- int args[100];
- int dim1;
-
- num = getStackList(args, ARRAYSIZE(args));
- int value = fetchScriptWord();
-
- if (readVar(value) == 0) {
- defineArray(value, kIntArray, 0, num);
- if (num > 0) {
- int16 counter = 0;
- do {
- writeArray(value, 0, counter + 1, args[counter]);
- } while (++counter < num);
- }
-
- shuffleArray(value, 1, num);
- writeArray(value, 0, 0, 2);
- push(readArray(value, 0, 1));
- return;
- }
-
- num = readArray(value, 0, 0);
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(value));
- dim1 = FROM_LE_16(ah->dim1) - 1;
-
- if (dim1 < num) {
- int16 var_2 = readArray(value, 0, num - 1);
- shuffleArray(value, 1, dim1);
- if (readArray(value, 0, 1) == var_2) {
- num = 2;
- } else {
- num = 1;
- }
- }
-
- writeArray(value, 0, 0, num + 1);
- push(readArray(value, 0, num));
-}
-
-void ScummEngine_v6::o6_getDateTime() {
- struct tm *t;
- time_t now = time(NULL);
-
- t = localtime(&now);
-
- VAR(VAR_TIMEDATE_YEAR) = t->tm_year;
- VAR(VAR_TIMEDATE_MONTH) = t->tm_mon;
- VAR(VAR_TIMEDATE_DAY) = t->tm_mday;
- VAR(VAR_TIMEDATE_HOUR) = t->tm_hour;
- VAR(VAR_TIMEDATE_MINUTE) = t->tm_min;
-
- if (_version == 8)
- VAR(VAR_TIMEDATE_SECOND) = t->tm_sec;
-}
-
-void ScummEngine_v6::o6_getPixel() {
- // This opcode is used to check fir ground area in the "Asteroid Lander"
- // minigame in "The Dig"
- int x, y;
-
- if (_heversion == 61) {
- x = pop();
- y = pop();
- } else {
- y = pop();
- x = pop();
- }
-
- VirtScreen *vs = findVirtScreen(y);
-
- if (vs == NULL || x > _screenWidth - 1 || x < 0) {
- push(-1);
- return;
- }
-
- byte area = *vs->getPixels(x, y - vs->topline);
- push(area);
-}
-
-void ScummEngine_v6::o6_setBoxSet() {
- int arg = pop() - 1;
-
- const byte *room = getResourceAddress(rtRoom, _roomResource);
- const byte *boxd = NULL, *boxm = NULL;
- int32 dboxSize, mboxSize;
- int i;
-
- ResourceIterator boxds(room, false);
- for (i = 0; i < arg; i++)
- boxd = boxds.findNext(MKID('BOXD'));
-
- if (!boxd)
- error("ScummEngine_v6::o6_setBoxSet: Can't find dboxes for set %d", arg);
-
- dboxSize = READ_BE_UINT32(boxd + 4) - 8;
- byte *matrix = res.createResource(rtMatrix, 2, dboxSize);
-
- assert(matrix);
- memcpy(matrix, boxd + 8, dboxSize);
-
- ResourceIterator boxms(room, false);
- for (i = 0; i < arg; i++)
- boxm = boxms.findNext(MKID('BOXM'));
-
- if (!boxm)
- error("ScummEngine_v6::o6_setBoxSet: Can't find mboxes for set %d", arg);
-
- mboxSize = READ_BE_UINT32(boxm + 4) - 8;
- matrix = res.createResource(rtMatrix, 1, mboxSize);
-
- assert(matrix);
- memcpy(matrix, boxm + 8, mboxSize);
-
- if (_version == 7)
- putActors();
-}
-
-void ScummEngine_v6::decodeParseString(int m, int n) {
- byte b = fetchScriptByte();
-
- switch (b) {
- case 65: // SO_AT
- _string[m].ypos = pop();
- _string[m].xpos = pop();
- _string[m].overhead = false;
- break;
- case 66: // SO_COLOR
- _string[m].color = pop();
- break;
- case 67: // SO_CLIPPED
- _string[m].right = pop();
- break;
- case 69: // SO_CENTER
- _string[m].center = true;
- _string[m].overhead = false;
- break;
- case 71: // SO_LEFT
- _string[m].center = false;
- _string[m].overhead = false;
- break;
- case 72: // SO_OVERHEAD
- _string[m].overhead = true;
- _string[m].no_talk_anim = false;
- break;
- case 73: // SO_SAY_VOICE
- error("decodeParseString: case 73");
- break;
- case 74: // SO_MUMBLE
- _string[m].no_talk_anim = true;
- break;
- case 75: // SO_TEXTSTRING
- printString(m, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
- break;
- case 0xFE:
- _string[m].loadDefault();
- if (n)
- _actorToPrintStrFor = pop();
- break;
- case 0xFF:
- _string[m].saveDefault();
- break;
- default:
- error("decodeParseString: default case 0x%x", b);
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v6he.cpp b/scumm/script_v6he.cpp
deleted file mode 100644
index ce3f76bc18..0000000000
--- a/scumm/script_v6he.cpp
+++ /dev/null
@@ -1,1315 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/savefile.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/imuse.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/usage_bits.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-struct vsUnpackCtx {
- uint8 size;
- uint8 type;
- uint8 b;
- uint8 *ptr;
-};
-
-struct vsPackCtx {
- int size;
- uint8 buf[256];
-};
-
-static void virtScreenSavePackBuf(vsPackCtx *ctx, uint8 *&dst, int len);
-static void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b);
-static uint8 virtScreenLoadUnpack(vsUnpackCtx *ctx, byte *data);
-static int virtScreenSavePack(byte *dst, byte *src, int len, int unk);
-
-// Compatibility notes:
-//
-// FBEAR (fbear, fbeardemo)
-// transparency in akos.cpp
-// negative size in file read/write
-
-#define OPCODE(x) _OPCODE(ScummEngine_v60he, x)
-
-void ScummEngine_v60he::setupOpcodes() {
- static const OpcodeEntryv60he opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o6_pushByteVar),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayRead),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayIndexedRead),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o6_invalid),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeByteVar),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayWrite),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayIndexedWrite),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteVarInc),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayInc),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteVarDec),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayDec),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o6_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o6_startObject),
- OPCODE(o6_drawObject),
- OPCODE(o6_drawObjectAt),
- OPCODE(o6_invalid),
- /* 64 */
- OPCODE(o6_invalid),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_stopMusic),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o6_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o60_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o6_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_startMusic),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o6_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o6_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o6_getVerbFromXY),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_invalid),
- OPCODE(o6_resourceRoutines),
- /* 9C */
- OPCODE(o60_roomOps),
- OPCODE(o60_actorOps),
- OPCODE(o6_verbOps),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o6_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o6_arrayOps),
- OPCODE(o6_saveRestoreVerbs),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o60_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorAnimCounter1),
- /* AC */
- OPCODE(o6_invalid),
- OPCODE(o6_isAnyOf),
- OPCODE(o6_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o6_talkActor),
- OPCODE(o6_talkEgo),
- /* BC */
- OPCODE(o6_dimArray),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o6_dim2dimArray),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o60_kernelGetFunctions),
- OPCODE(o60_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o6_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o60_closeFile),
- OPCODE(o60_openFile),
- OPCODE(o60_readFile),
- /* DC */
- OPCODE(o60_writeFile),
- OPCODE(o6_findAllObjects),
- OPCODE(o60_deleteFile),
- OPCODE(o60_rename),
- /* E0 */
- OPCODE(o60_soundOps),
- OPCODE(o6_getPixel),
- OPCODE(o60_localizeArrayToScript),
- OPCODE(o6_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o60_seekFilePos),
- OPCODE(o60_redimArray),
- OPCODE(o60_readFilePos),
- /* EC */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F0 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F4 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* FC */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesv60he = opcodes;
-}
-
-void ScummEngine_v60he::executeOpcode(byte i) {
- OpcodeProcv60he op = _opcodesv60he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v60he::getOpcodeDesc(byte i) {
- return _opcodesv60he[i].desc;
-}
-
-void ScummEngine_v60he::o60_setState() {
- int state = pop();
- int obj = pop();
-
- if (state & 0x8000) {
- state &= 0x7FFF;
- putState(obj, state);
- if (_heversion >= 72)
- removeObjectFromDrawQue(obj);
- } else {
- putState(obj, state);
- markObjectRectAsDirty(obj);
- if (_bgNeedsRedraw)
- clearDrawObjectQueue();
- }
-}
-
-void ScummEngine_v60he::o60_roomOps() {
- int a, b, c, d, e;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 172: // SO_ROOM_SCROLL
- b = pop();
- a = pop();
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
-
- case 174: // SO_ROOM_SCREEN
- b = pop();
- a = pop();
- if (_heversion >= 71)
- initScreens(a, _screenHeight);
- else
- initScreens(a, b);
- break;
-
- case 175: // SO_ROOM_PALETTE
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setPalColor(d, a, b, c);
- break;
-
- case 176: // SO_ROOM_SHAKE_ON
- setShake(1);
- break;
-
- case 177: // SO_ROOM_SHAKE_OFF
- setShake(0);
- break;
-
- case 179: // SO_ROOM_INTENSITY
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, a, a, b, c);
- break;
-
- case 180: // SO_ROOM_SAVEGAME
- _saveTemporaryState = true;
- _saveLoadSlot = pop();
- _saveLoadFlag = pop();
- break;
-
- case 181: // SO_ROOM_FADE
- a = pop();
- if (_heversion >= 70) {
- // Defaults to 1 but doesn't use fade effects
- } else if (a) {
- _switchRoomEffect = (byte)(a & 0xFF);
- _switchRoomEffect2 = (byte)(a >> 8);
- } else {
- fadeIn(_newEffect);
- }
- break;
-
- case 182: // SO_RGB_ROOM_INTENSITY
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, b, c, d, e);
- break;
-
- case 183: // SO_ROOM_SHADOW
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- if (_heversion == 60)
- setupShadowPalette(a, b, c, d, e, 0, 256);
- break;
-
- case 186: // SO_ROOM_TRANSFORM
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- palManipulateInit(a, b, c, d);
- break;
-
- case 187: // SO_CYCLE_SPEED
- b = pop();
- a = pop();
- checkRange(16, 1, a, "o60_roomOps: 187: color cycle out of range (%d)");
- _colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0;
- break;
-
- case 213: // SO_ROOM_NEW_PALETTE
- a = pop();
- setPalette(a);
- break;
- case 220:
- a = pop();
- b = pop();
- copyPalColor(a, b);
- break;
- case 221:
- int len;
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
- _saveLoadFlag = pop();
- _saveLoadSlot = 1;
- _saveTemporaryState = true;
- break;
- case 234: // HE 7.2
- b = pop();
- a = pop();
- swapObjects(a, b);
- break;
- case 236: // HE 7.2
- b = pop();
- a = pop();
- setRoomPalette(a, b);
- break;
- default:
- error("o60_roomOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v60he::swapObjects(int object1, int object2) {
- int idx1 = -1, idx2 = -1;
-
- for (int i = 0; i < _numLocalObjects; i++) {
- if (_objs[i].obj_nr == object1)
- idx1 = i;
-
- if (_objs[i].obj_nr == object2)
- idx2 = i;
- }
-
- if (idx1 == -1 || idx2 == -1 || idx1 <= idx2)
- return;
-
- stopObjectScript(object1);
- stopObjectScript(object2);
-
- ObjectData tmpOd;
-
- memcpy(&tmpOd, &_objs[idx1], sizeof(tmpOd));
- memcpy(&_objs[idx1], &_objs[idx2], sizeof(tmpOd));
- memcpy(&_objs[idx2], &tmpOd, sizeof(tmpOd));
-}
-
-void ScummEngine_v60he::o60_actorOps() {
- Actor *a;
- int i, j, k;
- int args[8];
-
- byte subOp = fetchScriptByte();
- if (subOp == 197) {
- _curActor = pop();
- return;
- }
-
- a = derefActorSafe(_curActor, "o60_actorOps");
- if (!a)
- return;
-
- switch (subOp) {
- case 30:
- // _heversion >= 70
- _actorClipOverride.bottom = pop();
- _actorClipOverride.right = pop();
- _actorClipOverride.top = pop();
- _actorClipOverride.left = pop();
- break;
- case 76: // SO_COSTUME
- a->setActorCostume(pop());
- break;
- case 77: // SO_STEP_DIST
- j = pop();
- i = pop();
- a->setActorWalkSpeed(i, j);
- break;
- case 78: // SO_SOUND
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; i++)
- a->_sound[i] = args[i];
- break;
- case 79: // SO_WALK_ANIMATION
- a->_walkFrame = pop();
- break;
- case 80: // SO_TALK_ANIMATION
- a->_talkStopFrame = pop();
- a->_talkStartFrame = pop();
- break;
- case 81: // SO_STAND_ANIMATION
- a->_standFrame = pop();
- break;
- case 82: // SO_ANIMATION
- // dummy case in scumm6
- pop();
- pop();
- pop();
- break;
- case 83: // SO_DEFAULT
- a->initActor(0);
- break;
- case 84: // SO_ELEVATION
- a->setElevation(pop());
- break;
- case 85: // SO_ANIMATION_DEFAULT
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 86: // SO_PALETTE
- j = pop();
- i = pop();
- checkRange(255, 0, i, "Illegal palette slot %d");
- a->remapActorPaletteColor(i, j);
- a->_needRedraw = true;
- break;
- case 87: // SO_TALK_COLOR
- a->_talkColor = pop();
- break;
- case 88: // SO_ACTOR_NAME
- loadPtrToResource(rtActorName, a->_number, NULL);
- break;
- case 89: // SO_INIT_ANIMATION
- a->_initFrame = pop();
- break;
- case 91: // SO_ACTOR_WIDTH
- a->_width = pop();
- break;
- case 92: // SO_SCALE
- i = pop();
- a->setScale(i, i);
- break;
- case 93: // SO_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 94: // SO_ALWAYS_ZCLIP
- a->_forceClip = pop();
- break;
- case 95: // SO_IGNORE_BOXES
- a->_ignoreBoxes = 1;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 96: // SO_FOLLOW_BOXES
- a->_ignoreBoxes = 0;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 97: // SO_ANIMATION_SPEED
- a->setAnimSpeed(pop());
- break;
- case 98: // SO_SHADOW
- a->_shadowMode = pop();
- a->_needRedraw = true;
- break;
- case 99: // SO_TEXT_OFFSET
- a->_talkPosY = pop();
- a->_talkPosX = pop();
- break;
- case 156: // HE 7.2
- a->_charset = pop();
- break;
- case 198: // SO_ACTOR_VARIABLE
- i = pop();
- a->setAnimVar(pop(), i);
- break;
- case 215: // SO_ACTOR_IGNORE_TURNS_ON
- a->_ignoreTurns = true;
- break;
- case 216: // SO_ACTOR_IGNORE_TURNS_OFF
- a->_ignoreTurns = false;
- break;
- case 217: // SO_ACTOR_NEW
- a->initActor(2);
- break;
- case 218:
- a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
- break;
- case 219:
- a->_drawToBackBuf = false;
- a->_needRedraw = true;
- a->_needBgReset = true;
- break;
- case 225:
- {
- byte string[128];
- copyScriptString(string);
- int slot = pop();
-
- int len = resStrLen(string) + 1;
- convertMessageToString(string, a->_heTalkQueue[slot].sentence, len);
-
- a->_heTalkQueue[slot].posX = a->_talkPosX;
- a->_heTalkQueue[slot].posY = a->_talkPosY;
- a->_heTalkQueue[slot].color = a->_talkColor;
- break;
- }
- default:
- error("o60_actorOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v60he::o60_wait() {
- int actnum;
- int offs = -2;
- Actor *a;
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 168: // SO_WAIT_FOR_ACTOR Wait for actor
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o60_wait:168");
- if (a->_moving)
- break;
- return;
- case 169: // SO_WAIT_FOR_MESSAGE Wait for message
- if (VAR(VAR_HAVE_MSG))
- break;
- return;
- case 170: // SO_WAIT_FOR_CAMERA Wait for camera
- if (camera._cur.x / 8 != camera._dest.x / 8)
- break;
- return;
- case 171: // SO_WAIT_FOR_SENTENCE
- if (_sentenceNum) {
- if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- }
- if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- default:
- error("o60_wait: default case 0x%x", subOp);
- }
-
- _scriptPointer += offs;
- o6_breakHere();
-}
-
-void ScummEngine_v60he::o60_kernelSetFunctions() {
- int args[29];
- int num;
-
- num = getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 1:
- // Used to restore images when decorating cake in
- // Fatty Bear's Birthday Surprise
- virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
- break;
- case 3:
- case 4:
- case 5:
- case 6:
- case 8:
- //Used before mini games in 3DO versions, seems safe to ignore.
- break;
- default:
- error("o60_kernelSetFunctions: default case %d (param count %d)", args[0], num);
- }
-}
-
-void ScummEngine_v60he::virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2) {
- vsUnpackCtx ctx;
- memset(&ctx, 0, sizeof(ctx));
- VirtScreen &vs = virtscr[kMainVirtScreen];
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resIdx);
- virtScreenLoadUnpack(&ctx, ah->data);
- for (int j = y1; j <= y2; ++j) {
- uint8 *p1 = vs.getPixels(x1, j - vs.topline);
- uint8 *p2 = vs.getBackPixels(x1, j - vs.topline);
- if (x2 >= x1) {
- uint32 w = x2 - x1 + 1;
- while (w--) {
- uint8 decByte = virtScreenLoadUnpack(&ctx, 0);
- *p1++ = decByte;
- *p2++ = decByte;
- }
- }
- }
- markRectAsDirty(kMainVirtScreen, x1, x2, y1, y2 + 1, USAGE_BIT_RESTORED);
-}
-
-uint8 virtScreenLoadUnpack(vsUnpackCtx *ctx, byte *data) {
- uint8 decByte;
- if (data != 0) {
- ctx->type = 0;
- ctx->ptr = data;
- decByte = 0;
- } else {
- uint8 a;
- if (ctx->type == 0) {
- a = *(ctx->ptr)++;
- if (a & 1) {
- ctx->type = 1;
- ctx->b = *(ctx->ptr)++;
- } else {
- ctx->type = 2;
- }
- ctx->size = a;
- a = (a >> 1) + 1;
- } else {
- a = ctx->size;
- }
- if (ctx->type == 2) {
- ctx->b = *(ctx->ptr)++;
- }
- ctx->size = a - 1;
- if (ctx->size == 0) {
- ctx->type = 0;
- }
- decByte = ctx->b;
- }
- return decByte;
-}
-
-
-void ScummEngine_v60he::o60_kernelGetFunctions() {
- int args[29];
- ArrayHeader *ah;
- getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 1:
- // Used to store images when decorating cake in
- // Fatty Bear's Birthday Surprise
- writeVar(0, 0);
- ah = defineArray(0, kByteArray, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
- virtScreenSave(ah->data, args[1], args[2], args[3], args[4]);
- push(readVar(0));
- break;
- default:
- error("o60_kernelGetFunctions: default case %d", args[0]);
- }
-}
-
-int ScummEngine_v60he::virtScreenSave(byte *dst, int x1, int y1, int x2, int y2) {
- int packedSize = 0;
- VirtScreen &vs = virtscr[kMainVirtScreen];
-
- for (int j = y1; j <= y2; ++j) {
- uint8 *p = vs.getBackPixels(x1, j - vs.topline);
-
- int size = virtScreenSavePack(dst, p, x2 - x1 + 1, 0);
- if (dst != 0) {
- dst += size;
- }
- packedSize += size;
- }
- return packedSize;
-}
-
-int virtScreenSavePack(byte *dst, byte *src, int len, int unk) {
- vsPackCtx ctx;
- memset(&ctx, 0, sizeof(ctx));
-
- uint8 prevByte, curByte;
-
- ctx.buf[0] = prevByte = *src++;
- int flag = 0;
- int iend = 1;
- int ibeg = 0;
-
- for (--len; len != 0; --len, prevByte = curByte) {
- bool pass = false;
-
- assert(iend < 0x100);
- ctx.buf[iend] = curByte = *src++;
- ++iend;
-
- if (flag == 0) {
- if (iend > 0x80) {
- virtScreenSavePackBuf(&ctx, dst, iend - 1);
- ctx.buf[0] = curByte;
- iend = 1;
- ibeg = 0;
- continue;
- }
- if (prevByte != curByte) {
- ibeg = iend - 1;
- continue;
- }
- if (iend - ibeg < 3) {
- if (ibeg != 0) {
- pass = true;
- } else {
- flag = 1;
- }
- } else {
- if (ibeg > 0) {
- virtScreenSavePackBuf(&ctx, dst, ibeg);
- }
- flag = 1;
- }
- }
- if (flag == 1 || pass) {
- if (prevByte != curByte || iend - ibeg > 0x80) {
- virtScreenSavePackByte(&ctx, dst, iend - ibeg - 1, prevByte);
- ctx.buf[0] = curByte;
- iend = 1;
- ibeg = 0;
- flag = 0;
- }
- }
- }
-
- if (flag == 0) {
- virtScreenSavePackBuf(&ctx, dst, iend);
- } else if (flag == 1) {
- virtScreenSavePackByte(&ctx, dst, iend - ibeg, prevByte);
- }
- return ctx.size;
-}
-
-void virtScreenSavePackBuf(vsPackCtx *ctx, uint8 *&dst, int len) {
- if (dst) {
- *dst++ = (len - 1) * 2;
- }
- ++ctx->size;
- if (len > 0) {
- ctx->size += len;
- if (dst) {
- memcpy(dst, ctx->buf, len);
- dst += len;
- }
- }
-}
-
-void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b) {
- if (dst) {
- *dst++ = ((len - 1) * 2) | 1;
- }
- ++ctx->size;
- if (dst) {
- *dst++ = b;
- }
- ++ctx->size;
-}
-
-void ScummEngine_v60he::o60_openFile() {
- int mode, len, slot, l, r;
- byte filename[100];
-
- convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- for (r = strlen((char*)filename); r != 0; r--) {
- if (filename[r - 1] == '\\')
- break;
- }
-
- mode = pop();
- slot = -1;
- for (l = 0; l < 17; l++) {
- if (_hFileTable[l].isOpen() == false) {
- slot = l;
- break;
- }
- }
-
- if (slot != -1) {
- switch(mode) {
- case 1:
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _saveFileMan->getSavePath());
- if (_hFileTable[slot].isOpen() == false)
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode);
- break;
- case 2:
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileWriteMode, _saveFileMan->getSavePath());
- break;
- default:
- error("o60_openFile(): wrong open file mode %d", mode);
- }
-
- if (_hFileTable[slot].isOpen() == false)
- slot = -1;
-
- }
- push(slot);
-}
-
-void ScummEngine_v60he::o60_closeFile() {
- int slot = pop();
- if (slot != -1)
- _hFileTable[slot].close();
-}
-
-void ScummEngine_v60he::o60_deleteFile() {
- int len, r;
- byte filename[100];
-
- convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- for (r = strlen((char*)filename); r != 0; r--) {
- if (filename[r - 1] == '\\')
- break;
- }
-
- debug(1, "stub o60_deleteFile(\"%s\")", filename + r);
-}
-
-void ScummEngine_v60he::o60_rename() {
- int len, r1, r2;
- byte filename[100],filename2[100];
-
- convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- for (r1 = strlen((char*)filename); r1 != 0; r1--) {
- if (filename[r1 - 1] == '\\')
- break;
- }
-
- convertMessageToString(_scriptPointer, filename2, sizeof(filename2));
-
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- for (r2 = strlen((char*)filename2); r2 != 0; r2--) {
- if (filename2[r2 - 1] == '\\')
- break;
- }
-
- debug(1, "stub o60_rename(\"%s\" to \"%s\")", filename + r1, filename2 + r2);
-}
-
-int ScummEngine_v60he::readFileToArray(int slot, int32 size) {
- if (size == 0)
- size = _hFileTable[slot].size() - _hFileTable[slot].pos();
-
- writeVar(0, 0);
-
- ArrayHeader *ah = defineArray(0, kByteArray, 0, size);
- _hFileTable[slot].read(ah->data, size);
-
- return readVar(0);
-}
-
-void ScummEngine_v60he::o60_readFile() {
- int32 size = pop();
- int slot = pop();
- int val;
-
- // Fatty Bear uses positive values
- if ((_platform == Common::kPlatformPC) && (_gameId == GID_FBEAR))
- size = -size;
-
- if (size == -2) {
- val = _hFileTable[slot].readUint16LE();
- push(val);
- } else if (size == -1) {
- val = _hFileTable[slot].readByte();
- push(val);
- } else {
- val = readFileToArray(slot, size);
- push(val);
- }
-}
-
-void ScummEngine_v60he::writeFileFromArray(int slot, int resID) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resID);
- int32 size = FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
-
- _hFileTable[slot].write(ah->data, size);
-}
-
-void ScummEngine_v60he::o60_writeFile() {
- int32 size = pop();
- int16 resID = pop();
- int slot = pop();
-
- // Fatty Bear uses positive values
- if ((_platform == Common::kPlatformPC) && (_gameId == GID_FBEAR))
- size = -size;
-
- if (size == -2) {
- _hFileTable[slot].writeUint16LE(resID);
- } else if (size == -1) {
- _hFileTable[slot].writeByte(resID);
- } else {
- writeFileFromArray(slot, resID);
- }
-}
-
-void ScummEngine_v60he::o60_soundOps() {
- byte subOp = fetchScriptByte();
- int arg = pop();
-
- switch (subOp) {
- case 0xde:
- _imuse->setMusicVolume(arg);
- break;
- case 0xdf:
- // Used in fbear introduction
- break;
- case 0xe0:
- // Fatty Bear's Birthday surprise uses this when playing the
- // piano, but only when using one of the digitized instruments.
- // See also o6_startSound().
- _sound->setOverrideFreq(arg);
- break;
- default:
- error("o60_soundOps: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v60he::localizeArray(int slot, byte scriptSlot) {
- if (_heversion >= 80)
- slot &= ~0x33539000;
-
- if (slot >= _numArray)
- error("o60_localizeArrayToScript(%d): array slot out of range", slot);
-
- _arraySlot[slot] = scriptSlot;
-}
-
-void ScummEngine_v60he::o60_localizeArrayToScript() {
- int slot = pop();
- localizeArray(slot, _currentScript);
-}
-
-void ScummEngine_v60he::o60_seekFilePos() {
- int mode, offset, slot;
-
- mode = pop();
- offset = pop();
- slot = pop();
-
- if (slot == -1)
- return;
-
- switch (mode) {
- case 1:
- _hFileTable[slot].seek(offset, SEEK_SET);
- break;
- case 2:
- _hFileTable[slot].seek(offset, SEEK_CUR);
- break;
- case 3:
- _hFileTable[slot].seek(offset, SEEK_END);
- break;
- default:
- error("o60_seekFilePos: default case %d", mode);
- }
-}
-
-void ScummEngine_v60he::o60_readFilePos() {
- int slot = pop();
-
- if (slot == -1) {
- push(0);
- return;
- }
-
- push(_hFileTable[slot].pos());
-}
-
-void ScummEngine_v60he::o60_redimArray() {
- int newX, newY;
- newY = pop();
- newX = pop();
-
- if (newY == 0)
- SWAP(newX, newY);
-
- byte subOp = fetchScriptByte();
- switch (subOp) {
- case 199:
- redimArray(fetchScriptWord(), newX, newY, kIntArray);
- break;
- case 202:
- redimArray(fetchScriptWord(), newX, newY, kByteArray);
- break;
- default:
- error("o60_redimArray: default type %d", subOp);
- }
-}
-
-void ScummEngine_v60he::redimArray(int arrayId, int newX, int newY, int type) {
- // Used in mini game at Cosmic Dust Diner in puttmoon
- int newSize, oldSize;
-
- if (readVar(arrayId) == 0)
- error("redimArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(arrayId));
-
- if (!ah)
- error("redimArray: Invalid array (%d) reference", readVar(arrayId));
-
- newSize = (type == kIntArray) ? 2 : 1;
- oldSize = (ah->type == kIntArray) ? 2 : 1;
-
- newSize *= (newX + 1) * (newY + 1);
- oldSize *= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
-
- if (newSize != oldSize)
- error("redimArray: array %d redim mismatch", readVar(arrayId));
-
- ah->type = TO_LE_16(type);
- ah->dim1 = TO_LE_16(newY + 1);
- ah->dim2 = TO_LE_16(newX + 1);
-}
-
-void ScummEngine_v60he::decodeParseString(int m, int n) {
- int i, colors;
- int args[31];
-
- byte b = fetchScriptByte();
-
- switch (b) {
- case 65: // SO_AT
- _string[m].ypos = pop();
- _string[m].xpos = pop();
- _string[m].overhead = false;
- break;
- case 66: // SO_COLOR
- _string[m].color = pop();
- break;
- case 67: // SO_CLIPPED
- _string[m].right = pop();
- break;
- case 69: // SO_CENTER
- _string[m].center = true;
- _string[m].overhead = false;
- break;
- case 71: // SO_LEFT
- _string[m].center = false;
- _string[m].overhead = false;
- break;
- case 72: // SO_OVERHEAD
- _string[m].overhead = true;
- _string[m].no_talk_anim = false;
- break;
- case 74: // SO_MUMBLE
- _string[m].no_talk_anim = true;
- break;
- case 75: // SO_TEXTSTRING
- printString(m, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
- break;
- case 0xF9:
- colors = pop();
- if (colors == 1) {
- _string[m].color = pop();
- } else {
- push(colors);
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- _string[m].color = _charsetColorMap[0];
- }
- break;
- case 0xFE:
- _string[m].loadDefault();
- if (n)
- _actorToPrintStrFor = pop();
- break;
- case 0xFF:
- _string[m].saveDefault();
- break;
- default:
- error("decodeParseString: default case 0x%x", b);
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v72he.cpp b/scumm/script_v72he.cpp
deleted file mode 100644
index 021a74dcc3..0000000000
--- a/scumm/script_v72he.cpp
+++ /dev/null
@@ -1,2352 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-#include "common/savefile.h"
-#include "common/system.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v72he, x)
-
-void ScummEngine_v72he::setupOpcodes() {
- static const OpcodeEntryV72he opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o72_pushDWord),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o72_getScriptString),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o72_isAnyOf),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o72_resetCutscene),
- OPCODE(o6_invalid),
- OPCODE(o72_findObjectWithClassOf),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o72_getObjectImageX),
- OPCODE(o72_getObjectImageY),
- OPCODE(o72_captureWizImage),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o72_getTimer),
- OPCODE(o72_setTimer),
- OPCODE(o72_getSoundPosition),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o72_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o72_startObject),
- OPCODE(o72_drawObject),
- OPCODE(o72_printWizImage),
- OPCODE(o72_getArrayDimSize),
- /* 64 */
- OPCODE(o72_getNumFreeArrays),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_stopMusic),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o6_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o60_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o70_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_startMusic),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o70_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o70_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o6_getVerbFromXY),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_invalid),
- OPCODE(o70_resourceRoutines),
- /* 9C */
- OPCODE(o72_roomOps),
- OPCODE(o72_actorOps),
- OPCODE(o72_verbOps),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o72_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o72_arrayOps),
- OPCODE(o6_saveRestoreVerbs),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o60_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorAnimCounter1),
- /* AC */
- OPCODE(o6_invalid),
- OPCODE(o6_isAnyOf),
- OPCODE(o72_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o72_talkActor),
- OPCODE(o72_talkEgo),
- /* BC */
- OPCODE(o72_dimArray),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o72_dim2dimArray),
- OPCODE(o72_traceStatus),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o72_kernelGetFunctions),
- OPCODE(o70_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o72_drawWizImage),
- OPCODE(o72_debugInput),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o72_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o60_closeFile),
- OPCODE(o72_openFile),
- OPCODE(o72_readFile),
- /* DC */
- OPCODE(o72_writeFile),
- OPCODE(o72_findAllObjects),
- OPCODE(o72_deleteFile),
- OPCODE(o72_rename),
- /* E0 */
- OPCODE(o60_soundOps),
- OPCODE(o72_getPixel),
- OPCODE(o60_localizeArrayToScript),
- OPCODE(o72_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o70_seekFilePos),
- OPCODE(o72_redimArray),
- OPCODE(o60_readFilePos),
- /* EC */
- OPCODE(o70_copyString),
- OPCODE(o70_getStringWidth),
- OPCODE(o70_getStringLen),
- OPCODE(o70_appendString),
- /* F0 */
- OPCODE(o70_concatString),
- OPCODE(o70_compareString),
- OPCODE(o70_isResourceLoaded),
- OPCODE(o72_readINI),
- /* F4 */
- OPCODE(o72_writeINI),
- OPCODE(o70_getStringLenForWidth),
- OPCODE(o70_getCharIndexInString),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o72_getResourceSize),
- OPCODE(o72_setFilePath),
- OPCODE(o72_setWindowCaption),
- OPCODE(o70_polygonOps),
- /* FC */
- OPCODE(o70_polygonHit),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV72he = opcodes;
-}
-
-void ScummEngine_v72he::executeOpcode(byte i) {
- OpcodeProcV72he op = _opcodesV72he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v72he::getOpcodeDesc(byte i) {
- return _opcodesV72he[i].desc;
-}
-
-static const int arrayDataSizes[] = { 0, 1, 4, 8, 8, 16, 32 };
-
-ScummEngine_v72he::ArrayHeader *ScummEngine_v72he::defineArray(int array, int type, int dim2start, int dim2end,
- int dim1start, int dim1end) {
- int id;
- int size;
- ArrayHeader *ah;
-
- assert(dim2start >= 0 && dim2start <= dim2end);
- assert(dim1start >= 0 && dim1start <= dim1end);
- assert(0 <= type && type <= 6);
-
-
- if (type == kBitArray || type == kNibbleArray)
- type = kByteArray;
-
- nukeArray(array);
-
- id = findFreeArrayId();
-
- debug(9,"defineArray (array %d, dim2start %d, dim2end %d dim1start %d dim1end %d", id, dim2start, dim2end, dim1start, dim1end);
-
- if (array & 0x80000000) {
- error("Can't define bit variable as array pointer");
- }
-
- size = arrayDataSizes[type];
-
- if (_heversion >= 80)
- id |= 0x33539000;
-
- writeVar(array, id);
-
- if (_heversion >= 80)
- id &= ~0x33539000;
-
- size *= dim2end - dim2start + 1;
- size *= dim1end - dim1start + 1;
- size >>= 3;
-
- ah = (ArrayHeader *)res.createResource(rtString, id, size + sizeof(ArrayHeader));
-
- ah->type = TO_LE_32(type);
- ah->dim1start = TO_LE_32(dim1start);
- ah->dim1end = TO_LE_32(dim1end);
- ah->dim2start = TO_LE_32(dim2start);
- ah->dim2end = TO_LE_32(dim2end);
-
- return ah;
-}
-
-int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
- debug(9, "readArray (array %d, idx2 %d, idx1 %d)", readVar(array), idx2, idx1);
-
- if (readVar(array) == 0)
- error("readArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
-
- if (ah == NULL || ah->data == NULL)
- error("readArray: invalid array %d (%d)", array, readVar(array));
-
- if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
- idx1 < (int)FROM_LE_32(ah->dim1start) || idx1 > (int)FROM_LE_32(ah->dim1end)) {
- error("readArray: array %d out of bounds: [%d, %d] exceeds [%d..%d, %d..%d]",
- array, idx1, idx2, FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end),
- FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end));
- }
-
- const int offset = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (idx2 - FROM_LE_32(ah->dim2start)) - FROM_LE_32(ah->dim1start) + idx1;
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- return ah->data[offset];
-
- case kIntArray:
- return (int16)READ_LE_UINT16(ah->data + offset * 2);
-
- case kDwordArray:
- return (int32)READ_LE_UINT32(ah->data + offset * 4);
- }
-
- return 0;
-}
-
-void ScummEngine_v72he::writeArray(int array, int idx2, int idx1, int value) {
- debug(9, "writeArray (array %d, idx2 %d, idx1 %d, value %d)", readVar(array), idx2, idx1, value);
-
- if (readVar(array) == 0)
- error("writeArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
-
- if (!ah)
- error("writeArray: Invalid array (%d) reference", readVar(array));
-
- if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
- idx1 < (int)FROM_LE_32(ah->dim1start) || idx1 > (int)FROM_LE_32(ah->dim1end)) {
- error("writeArray: array %d out of bounds: [%d, %d] exceeds [%d..%d, %d..%d]",
- array, idx1, idx2, FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end),
- FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end));
- }
-
- const int offset = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (idx2 - FROM_LE_32(ah->dim2start)) - FROM_LE_32(ah->dim1start) + idx1;
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- ah->data[offset] = value;
- break;
-
- case kIntArray:
- WRITE_LE_UINT16(ah->data + offset * 2, value);
- break;
-
- case kDwordArray:
- WRITE_LE_UINT32(ah->data + offset * 4, value);
- break;
- }
-}
-
-int ScummEngine_v72he::setupStringArray(int size) {
- writeVar(0, 0);
- defineArray(0, kStringArray, 0, 0, 0, size + 1);
- writeArray(0, 0, 0, 0);
- return readVar(0);
-}
-
-void ScummEngine_v72he::readArrayFromIndexFile() {
- int num;
- int a, b, c;
-
- while ((num = _fileHandle->readUint16LE()) != 0) {
- a = _fileHandle->readUint16LE();
- b = _fileHandle->readUint16LE();
- c = _fileHandle->readUint16LE();
-
- if (c == 1)
- defineArray(num, kBitArray, 0, a, 0, b);
- else
- defineArray(num, kDwordArray, 0, a, 0, b);
- }
-}
-
-int ScummEngine_v72he::convertFilePath(byte *dst, bool setFilePath) {
- debug(1, "convertFilePath: original filePath is %s", dst);
-
- // Switch all \ to / for portablity
- int len = resStrLen(dst) + 1;
- for (int i = 0; i < len; i++) {
- if (dst[i] == '\\')
- dst[i] = '/';
- }
-
- // Strip path
- int r = 0;
- if (dst[0] == '.' && dst[1] == '/') {
- r = 2;
- } else if (dst[0] == 'c' && dst[1] == ':') {
- for (r = len; r != 0; r--) {
- if (dst[r - 1] == '/')
- break;
- }
- }
-
- if (setFilePath) {
- char filePath[256];
- sprintf(filePath, "%s%s", _gameDataPath.c_str(), dst + r);
- if (!Common::File::exists(filePath)) {
- sprintf(filePath, "%s%s", _saveFileMan->getSavePath(), dst + r);
- }
- strcpy((char *)dst, filePath);
- debug(1, "convertFilePath: filePath is %s", dst);
- }
-
- return r;
-}
-
-void ScummEngine_v72he::copyScriptString(byte *dst, int dstSize) {
- byte string[1024];
- byte chr;
- int pos = 0;
-
- int array = pop();
- if (array == -1) {
- if (_stringLength == 1)
- error("String stack underflow");
-
- _stringLength -= 2;
- while ((chr = _stringBuffer[_stringLength]) != 0) {
- string[pos] = chr;
- pos++;
-
- if (pos > dstSize)
- error("String too long to pop");
-
- _stringLength--;
- }
-
- string[pos] = 0;
- _stringLength++;
-
- // Reverse string
- int len = resStrLen(string);
- while (len--)
- *dst++ = string[len];
- } else {
- writeVar(0, array);
- while ((chr = readArray(0, 0, pos)) != 0) {
- *dst++ = chr;
- pos++;
- }
- }
- *dst = 0;
-}
-
-void ScummEngine_v72he::decodeScriptString(byte *dst, bool scriptString) {
- const byte *src;
- int args[31];
- int num, len, val;
- byte chr, string[1024];
- memset(args, 0, sizeof(args));
- memset(string, 0, sizeof(string));
-
- // Get stack list, plus one
- num = pop();
- for (int i = num; i >= 0; i--)
- args[i] = pop();
-
- // Get string
- if (scriptString) {
- len = resStrLen(_scriptPointer) + 1;
- memcpy(string, _scriptPointer, len);
- _scriptPointer += len;
- } else {
- copyScriptString(string, sizeof(string));
- len = resStrLen(string) + 1;
- }
-
- // Decode string
- num = 0;
- val = 0;
- while (len--) {
- chr = string[num++];
- if (chr == '%') {
- chr = string[num++];
- switch(chr) {
- case 'b':
- //dst += sprintf((char *)dst, "%b", args[val++]);
- break;
- case 'c':
- *dst++ = args[val++];
- break;
- case 'd':
- dst += sprintf((char *)dst, "%d", args[val++]);
- break;
- case 's':
- src = getStringAddress(args[val++]);
- if (src) {
- while (*src != 0)
- *dst++ = *src++;
- }
- break;
- case 'x':
- dst += sprintf((char *)dst, "%x", args[val++]);
- break;
- default:
- *dst++ = '%';
- num--;
- break;
- }
- } else {
- *dst++ = chr;
- }
- }
- *dst = 0;
-}
-
-byte *ScummEngine_v70he::heFindResourceData(uint32 tag, byte *ptr) {
- ptr = heFindResource(tag, ptr);
-
- if (ptr == NULL)
- return NULL;
- return ptr + _resourceHeaderSize;
-}
-
-byte *ScummEngine_v70he::heFindResource(uint32 tag, byte *searchin) {
- uint32 curpos, totalsize, size;
-
- debugC(DEBUG_RESOURCE, "heFindResource(%s, %lx)", tag2str(tag), searchin);
-
- assert(searchin);
- searchin += 4;
- _resourceLastSearchSize = totalsize = READ_BE_UINT32(searchin);
- curpos = 8;
- searchin += 4;
-
- while (curpos < totalsize) {
- if (READ_UINT32(searchin) == tag) {
- return searchin;
- }
-
- size = READ_BE_UINT32(searchin + 4);
- if ((int32)size <= 0) {
- error("(%s) Not found in %d... illegal block len %d", tag2str(tag), 0, size);
- return NULL;
- }
-
- curpos += size;
- searchin += size;
- }
-
- return NULL;
-}
-
-byte *ScummEngine_v70he::findWrappedBlock(uint32 tag, byte *ptr, int state, bool errorFlag) {
- if (READ_UINT32(ptr) == MKID('MULT')) {
- byte *offs, *wrap;
- uint32 size;
-
- wrap = heFindResource(MKID('WRAP'), ptr);
- if (wrap == NULL)
- return NULL;
-
- offs = heFindResourceData(MKID('OFFS'), wrap);
- if (offs == NULL)
- return NULL;
-
- size = getResourceDataSize(offs) / 4;
- assert((uint32)state <= (uint32)size);
-
-
- offs += READ_LE_UINT32(offs + state * sizeof(uint32));
- offs = heFindResourceData(tag, offs - 8);
- if (offs)
- return offs;
-
- offs = heFindResourceData(MKID('DEFA'), ptr);
- if (offs == NULL)
- return NULL;
-
- return heFindResourceData(tag, offs - 8);
- } else {
- return heFindResourceData(tag, ptr);
- }
-}
-
-int ScummEngine_v72he::findObject(int x, int y, int num, int *args) {
- int b, cls, i, result;
-
- for (i = 1; i < _numLocalObjects; i++) {
- result = 0;
- if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable))
- continue;
-
- // Check polygon bounds
- if (_wiz->polygonDefined(_objs[i].obj_nr)) {
- if (_wiz->polygonHit(_objs[i].obj_nr, x, y))
- result = _objs[i].obj_nr;
- else if (VAR_POLYGONS_ONLY != 0xFF && VAR(VAR_POLYGONS_ONLY))
- continue;
- }
-
- if (!result) {
- // Check object bounds
- if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&
- _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y)
- result = _objs[i].obj_nr;
- }
-
- if (result) {
- if (!num)
- return result;
-
- // Check object class
- cls = args[0];
- b = getClass(_objs[i].obj_nr, cls);
- if ((cls & 0x80 && b) || (!(cls & 0x80) && !b))
- return result;
- }
- }
-
- return 0;
-}
-
-void ScummEngine_v72he::o72_pushDWord() {
- push(fetchScriptDWordSigned());
-}
-
-void ScummEngine_v72he::o72_getScriptString() {
- byte chr;
-
- while ((chr = fetchScriptByte()) != 0) {
- _stringBuffer[_stringLength] = chr;
- _stringLength++;
-
- if (_stringLength >= 4096)
- error("String stack overflow");
- }
-
- _stringBuffer[_stringLength] = 0;
- _stringLength++;
-}
-
-void ScummEngine_v72he::o72_isAnyOf() {
- int args[128];
- int num, value;
-
- num = getStackList(args, ARRAYSIZE(args));
- value = pop();
-
- for (int i = 0; i < num; i++) {
- if (args[i] == value) {
- push(1);
- return;
- }
- }
-
- push(0);
-}
-
-void ScummEngine_v72he::o72_resetCutscene() {
- int idx;
-
- idx = vm.cutSceneStackPointer;
- vm.cutSceneStackPointer = 0;
- vm.cutScenePtr[idx] = 0;
- vm.cutSceneScript[idx] = 0;
-
- VAR(VAR_OVERRIDE) = 0;
-}
-
-void ScummEngine_v72he::o72_findObjectWithClassOf() {
- int args[16], num;
-
- num = getStackList(args, ARRAYSIZE(args));
- int y = pop();
- int x = pop();
- int r = findObject(x, y, num, args);
- push(r);
-}
-
-void ScummEngine_v72he::o72_getObjectImageX() {
- int object = pop();
- int objnum = getObjectIndex(object);
-
- if (objnum == -1) {
- push(0);
- return;
- }
-
- push(_objs[objnum].x_pos / 8);
-}
-
-void ScummEngine_v72he::o72_getObjectImageY() {
- int object = pop();
- int objnum = getObjectIndex(object);
-
- if (objnum == -1) {
- push(0);
- return;
- }
-
- push(_objs[objnum].y_pos / 8);
-}
-
-void ScummEngine_v72he::o72_captureWizImage() {
- Common::Rect grab;
- grab.bottom = pop() + 1;
- grab.right = pop() + 1;
- grab.top = pop();
- grab.left = pop();
- _wiz->captureWizImage(pop(), grab, false, true);
-}
-
-void ScummEngine_v72he::o72_getTimer() {
- int timer = pop();
- byte cmd = fetchScriptByte();
-
- if (cmd == 10 || cmd == 50) {
- push(getHETimer(timer));
- } else {
- push(0);
- }
-}
-
-void ScummEngine_v72he::o72_setTimer() {
- int timer = pop();
- byte cmd = fetchScriptByte();
-
- if (cmd == 158 || cmd == 61) {
- setHETimer(timer);
- } else {
- error("TIMER command %d?", cmd);
- }
-}
-
-void ScummEngine_v72he::o72_getSoundPosition() {
- int snd = pop();
- push(_sound->getSoundPos(snd));
-}
-
-void ScummEngine_v72he::o72_startScript() {
- int args[25];
- int script;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = fetchScriptByte();
- runScript(script, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args);
-}
-
-void ScummEngine_v72he::o72_startObject() {
- int args[25];
- int script, entryp;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- entryp = pop();
- script = pop();
- flags = fetchScriptByte();
- runObjectScript(script, entryp, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args);
-}
-
-void ScummEngine_v72he::o72_drawObject() {
- byte subOp = fetchScriptByte();
- int state, y, x;
-
- switch (subOp) {
- case 62:
- state = pop();
- y = pop();
- x = pop();
- break;
- case 63:
- state = pop();
- if (state == 0)
- state = 1;
- y = x = -100;
- break;
- case 65:
- state = 1;
- y = pop();
- x = pop();
- break;
- default:
- error("o72_drawObject: default case %d", subOp);
- }
-
- int object = pop();
- int objnum = getObjectIndex(object);
- if (objnum == -1)
- return;
-
- if (y != -100 && x != -100) {
- _objs[objnum].x_pos = x * 8;
- _objs[objnum].y_pos = y * 8;
- }
-
- if (state != -1) {
- addObjectToDrawQue(objnum);
- putState(object, state);
- }
-}
-
-void ScummEngine_v72he::o72_printWizImage() {
- WizImage wi;
- wi.resNum = pop();
- wi.x1 = wi.y1 = 0;
- wi.state = 0;
- wi.flags = kWIFPrint;
- _wiz->displayWizImage(&wi);
-}
-
-void ScummEngine_v72he::o72_getArrayDimSize() {
- byte subOp = fetchScriptByte();
- int32 val1, val2;
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
- if (!ah) {
- push(0);
- return;
- }
-
- switch (subOp) {
- case 1:
- case 3:
- val1 = FROM_LE_32(ah->dim1end);
- val2 = FROM_LE_32(ah->dim1start);
- push(val1 - val2 + 1);
- break;
- case 2:
- val1 = FROM_LE_32(ah->dim2end);
- val2 = FROM_LE_32(ah->dim2start);
- push(val1 - val2 + 1);
- break;
- case 4:
- push(FROM_LE_32(ah->dim1start));
- break;
- case 5:
- push(FROM_LE_32(ah->dim1end));
- break;
- case 6:
- push(FROM_LE_32(ah->dim2start));
- break;
- case 7:
- push(FROM_LE_32(ah->dim2end));
- break;
- default:
- error("o72_getArrayDimSize: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_getNumFreeArrays() {
- byte **addr = res.address[rtString];
- int i, num = 0;
-
- for (i = 1; i < _numArray; i++) {
- if (!addr[i])
- num++;
- }
-
- push (num);
-}
-
-void ScummEngine_v72he::o72_roomOps() {
- int a, b, c, d, e;
- byte filename[100];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 172: // SO_ROOM_SCROLL
- b = pop();
- a = pop();
- if (a < (_screenWidth / 2))
- a = (_screenWidth / 2);
- if (b < (_screenWidth / 2))
- b = (_screenWidth / 2);
- if (a > _roomWidth - (_screenWidth / 2))
- a = _roomWidth - (_screenWidth / 2);
- if (b > _roomWidth - (_screenWidth / 2))
- b = _roomWidth - (_screenWidth / 2);
- VAR(VAR_CAMERA_MIN_X) = a;
- VAR(VAR_CAMERA_MAX_X) = b;
- break;
-
- case 174: // SO_ROOM_SCREEN
- b = pop();
- a = pop();
- initScreens(a, _screenHeight);
- break;
-
- case 175: // SO_ROOM_PALETTE
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setPalColor(d, a, b, c);
- break;
-
- case 179: // SO_ROOM_INTENSITY
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, a, a, b, c);
- break;
-
- case 180: // SO_ROOM_SAVEGAME
- _saveTemporaryState = true;
- _saveLoadSlot = pop();
- _saveLoadFlag = pop();
- break;
-
- case 181: // SO_ROOM_FADE
- // Defaults to 1 but doesn't use fade effects
- a = pop();
- break;
-
- case 182: // SO_RGB_ROOM_INTENSITY
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, b, c, d, e);
- break;
-
- case 213: // SO_ROOM_NEW_PALETTE
- a = pop();
- setPalette(a);
- break;
-
- case 220:
- a = pop();
- b = pop();
- copyPalColor(a, b);
- break;
-
- case 221:
- copyScriptString(filename, sizeof(filename));
- _saveLoadFlag = pop();
- _saveLoadSlot = 1;
- _saveTemporaryState = true;
- break;
-
- case 234:
- b = pop();
- a = pop();
- swapObjects(a, b);
- break;
-
- case 236:
- b = pop();
- a = pop();
- setRoomPalette(a, b);
- break;
-
- default:
- error("o72_roomOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_actorOps() {
- Actor *a;
- int i, j, k;
- int args[32];
- byte string[256];
-
- byte subOp = fetchScriptByte();
- if (subOp == 197) {
- _curActor = pop();
- return;
- }
-
- a = derefActorSafe(_curActor, "o72_actorOps");
- if (!a)
- return;
-
- switch (subOp) {
- case 21: // HE 80+
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; ++i) {
- a->setUserCondition(args[i] & 0x7F, args[i] & 0x80);
- }
- break;
- case 24: // HE 80+
- k = pop();
- if (k == 0)
- k = _rnd.getRandomNumberRng(1, 10);
- a->_heNoTalkAnimation = 1;
- a->setTalkCondition(k);
- break;
- case 43: // HE 90+
- // HE games use reverse order of layering, so we adjust
- a->_layer = -pop();
- a->_needRedraw = true;
- break;
- case 64:
- _actorClipOverride.bottom = pop();
- _actorClipOverride.right = pop();
- _actorClipOverride.top = pop();
- _actorClipOverride.left = pop();
- break;
- case 67: // HE 99+
- a->_clipOverride.bottom = pop();
- a->_clipOverride.right = pop();
- a->_clipOverride.top = pop();
- a->_clipOverride.left = pop();
- break;
- case 65: // HE 98+
- j = pop();
- i = pop();
- a->putActor(i, j, a->_room);
- break;
- case 68: // HE 90+
- k = pop();
- debug(0,"o72_actorOps: case 68 (%d)", k);
- break;
- case 76: // SO_COSTUME
- a->setActorCostume(pop());
- break;
- case 77: // SO_STEP_DIST
- j = pop();
- i = pop();
- a->setActorWalkSpeed(i, j);
- break;
- case 78: // SO_SOUND
- k = getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < k; i++)
- a->_sound[i] = args[i];
- break;
- case 79: // SO_WALK_ANIMATION
- a->_walkFrame = pop();
- break;
- case 80: // SO_TALK_ANIMATION
- a->_talkStopFrame = pop();
- a->_talkStartFrame = pop();
- break;
- case 81: // SO_STAND_ANIMATION
- a->_standFrame = pop();
- break;
- case 82: // SO_ANIMATION
- // dummy case in scumm6
- pop();
- pop();
- pop();
- break;
- case 83: // SO_DEFAULT
- a->initActor(0);
- break;
- case 84: // SO_ELEVATION
- a->setElevation(pop());
- break;
- case 85: // SO_ANIMATION_DEFAULT
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 86: // SO_PALETTE
- j = pop();
- i = pop();
- checkRange(255, 0, i, "Illegal palette slot %d");
- a->remapActorPaletteColor(i, j);
- a->_needRedraw = true;
- break;
- case 87: // SO_TALK_COLOR
- a->_talkColor = pop();
- break;
- case 88: // SO_ACTOR_NAME
- copyScriptString(string, sizeof(string));
- loadPtrToResource(rtActorName, a->_number, string);
- break;
- case 89: // SO_INIT_ANIMATION
- a->_initFrame = pop();
- break;
- case 91: // SO_ACTOR_WIDTH
- a->_width = pop();
- break;
- case 92: // SO_SCALE
- i = pop();
- a->setScale(i, i);
- break;
- case 93: // SO_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 94: // SO_ALWAYS_ZCLIP
- a->_forceClip = pop();
- break;
- case 95: // SO_IGNORE_BOXES
- a->_ignoreBoxes = 1;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 96: // SO_FOLLOW_BOXES
- a->_ignoreBoxes = 0;
- a->_forceClip = 0;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 97: // SO_ANIMATION_SPEED
- a->setAnimSpeed(pop());
- break;
- case 98: // SO_SHADOW
- a->_heXmapNum = pop();
- a->_needRedraw = true;
- break;
- case 99: // SO_TEXT_OFFSET
- a->_talkPosY = pop();
- a->_talkPosX = pop();
- break;
- case 156: // HE 72+
- a->_charset = pop();
- break;
- case 175: // HE 99+
- a->_hePaletteNum = pop();
- a->_needRedraw = true;
- break;
- case 198: // SO_ACTOR_VARIABLE
- i = pop();
- a->setAnimVar(pop(), i);
- break;
- case 215: // SO_ACTOR_IGNORE_TURNS_ON
- a->_ignoreTurns = true;
- break;
- case 216: // SO_ACTOR_IGNORE_TURNS_OFF
- a->_ignoreTurns = false;
- break;
- case 217: // SO_ACTOR_NEW
- a->initActor(2);
- break;
- case 218:
- a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
- break;
- case 219:
- a->_drawToBackBuf = false;
- a->_needRedraw = true;
- a->_needBgReset = true;
- break;
- case 225:
- {
- copyScriptString(string, sizeof(string));
- int slot = pop();
-
- int len = resStrLen(string) + 1;
- memcpy(a->_heTalkQueue[slot].sentence, string, len);
-
- a->_heTalkQueue[slot].posX = a->_talkPosX;
- a->_heTalkQueue[slot].posY = a->_talkPosY;
- a->_heTalkQueue[slot].color = a->_talkColor;
- break;
- }
- default:
- error("o72_actorOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_verbOps() {
- int slot, a, b;
- VerbSlot *vs;
- byte name[200];
-
- byte subOp = fetchScriptByte();
- if (subOp == 196) {
- _curVerb = pop();
- _curVerbSlot = getVerbSlot(_curVerb, 0);
- checkRange(_numVerbs - 1, 0, _curVerbSlot, "Illegal new verb slot %d");
- return;
- }
- vs = &_verbs[_curVerbSlot];
- slot = _curVerbSlot;
- switch (subOp) {
- case 124: // SO_VERB_IMAGE
- a = pop();
- if (_curVerbSlot) {
- setVerbObject(_roomResource, a, slot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 125: // SO_VERB_NAME
- copyScriptString(name, sizeof(name));
- loadPtrToResource(rtVerb, slot, name);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 126: // SO_VERB_COLOR
- vs->color = pop();
- break;
- case 127: // SO_VERB_HICOLOR
- vs->hicolor = pop();
- break;
- case 128: // SO_VERB_AT
- vs->curRect.top = pop();
- vs->curRect.left = pop();
- break;
- case 129: // SO_VERB_ON
- vs->curmode = 1;
- break;
- case 130: // SO_VERB_OFF
- vs->curmode = 0;
- break;
- case 131: // SO_VERB_DELETE
- slot = getVerbSlot(pop(), 0);
- killVerb(slot);
- break;
- case 132: // SO_VERB_NEW
- slot = getVerbSlot(_curVerb, 0);
- if (slot == 0) {
- for (slot = 1; slot < _numVerbs; slot++) {
- if (_verbs[slot].verbid == 0)
- break;
- }
- if (slot == _numVerbs)
- error("Too many verbs");
- _curVerbSlot = slot;
- }
- vs = &_verbs[slot];
- vs->verbid = _curVerb;
- vs->color = 2;
- vs->hicolor = 0;
- vs->dimcolor = 8;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
- case 133: // SO_VERB_DIMCOLOR
- vs->dimcolor = pop();
- break;
- case 134: // SO_VERB_DIM
- vs->curmode = 2;
- break;
- case 135: // SO_VERB_KEY
- vs->key = pop();
- break;
- case 136: // SO_VERB_CENTER
- vs->center = 1;
- break;
- case 137: // SO_VERB_NAME_STR
- a = pop();
- if (a == 0) {
- loadPtrToResource(rtVerb, slot, (const byte *)"");
- } else {
- loadPtrToResource(rtVerb, slot, getStringAddress(a));
- }
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 139: // SO_VERB_IMAGE_IN_ROOM
- b = pop();
- a = pop();
-
- if (slot && a != vs->imgindex) {
- setVerbObject(b, a, slot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 140: // SO_VERB_BAKCOLOR
- vs->bkcolor = pop();
- break;
- case 255:
- drawVerb(slot, 0);
- verbMouseOver(0);
- break;
- default:
- error("o72_verbops: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_findObject() {
- int y = pop();
- int x = pop();
- int r = findObject(x, y, 0, 0);
- push(r);
-}
-
-void ScummEngine_v72he::o72_arrayOps() {
- ArrayHeader *ah;
- byte string[1024];
- int dim1end, dim1start, dim2end, dim2start;
- int id, len, b, c, list[128];
- int offs, tmp, tmp2;
- uint tmp3;
-
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord();
- debug(9,"o72_arrayOps: array %d case %d", array, subOp);
-
- switch (subOp) {
- case 7: // SO_ASSIGN_STRING
- copyScriptString(string, sizeof(string));
- len = resStrLen(string);
- ah = defineArray(array, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- break;
-
- case 126:
- len = getStackList(list, ARRAYSIZE(list));
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
- }
- tmp2 = 0;
- while (dim2start <= dim2end) {
- tmp = dim1start;
- while (tmp <= dim1end) {
- writeArray(array, dim2start, tmp, list[tmp2++]);
- if (tmp2 == len)
- tmp2 = 0;
- tmp++;
- }
- dim2start++;
- }
- break;
- case 127:
- {
- int a2_dim1end = pop();
- int a2_dim1start = pop();
- int a2_dim2end = pop();
- int a2_dim2start = pop();
- int array2 = fetchScriptWord();
- int a1_dim1end = pop();
- int a1_dim1start = pop();
- int a1_dim2end = pop();
- int a1_dim2start = pop();
- if (a1_dim1end - a1_dim1start != a2_dim1end - a2_dim1start || a2_dim2end - a2_dim2start != a1_dim2end - a1_dim2start) {
- error("Source and dest ranges size are mismatched");
- }
- copyArray(array, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
- }
- break;
- case 128:
- b = pop();
- c = pop();
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
- }
-
- offs = (b >= c) ? 1 : -1;
- tmp2 = c;
- tmp3 = c - b + 1;
- while (dim2start <= dim2end) {
- tmp = dim1start;
- while (tmp <= dim1end) {
- writeArray(array, dim2start, tmp, tmp2);
- if (--tmp3 == 0) {
- tmp2 = c;
- tmp3 = c - b + 1;
- } else {
- tmp2 += offs;
- }
- tmp++;
- }
- dim2start++;
- }
- break;
- case 194:
- decodeScriptString(string);
- len = resStrLen(string);
- ah = defineArray(array, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- break;
- case 208: // SO_ASSIGN_INT_LIST
- b = pop();
- c = pop();
- id = readVar(array);
- if (id == 0) {
- defineArray(array, kDwordArray, 0, 0, 0, b + c - 1);
- }
- while (c--) {
- writeArray(array, 0, b + c, pop());
- }
- break;
- case 212: // SO_ASSIGN_2DIM_LIST
- len = getStackList(list, ARRAYSIZE(list));
- id = readVar(array);
- if (id == 0)
- error("Must DIM a two dimensional array before assigning");
- c = pop();
- while (--len >= 0) {
- writeArray(array, c, len, list[len]);
- }
- break;
- default:
- error("o72_arrayOps: default case %d (array %d)", subOp, array);
- }
-}
-
-void ScummEngine_v72he::o72_systemOps() {
- byte string[1024];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 22: // HE80+
- clearDrawObjectQueue();
- break;
- case 26: // HE80+
- gdi.copyVirtScreenBuffers(Common::Rect(_screenWidth, _screenHeight));
- updatePalette();
- break;
- case 158:
- restart();
- break;
- case 160:
- // Confirm shutdown
- shutDown();
- break;
- case 244:
- shutDown();
- break;
- case 251:
- copyScriptString(string, sizeof(string));
- debug(0, "Start executable (%s)", string);
- break;
- case 252:
- copyScriptString(string, sizeof(string));
- debug(0, "Start game (%s)", string);
- break;
- default:
- error("o72_systemOps invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_talkActor() {
- Actor *a;
-
- int act = pop();
-
- _string[0].loadDefault();
-
- // A value of 225 can occur when examining the gold in the mine of pajama, after mining the gold.
- // This is a script bug, the script should set the subtitle color, not actor number.
- // This script bug was fixed in the updated version of pajama.
- if (act == 225) {
- _string[0].color = act;
- } else {
- _actorToPrintStrFor = act;
- if (_actorToPrintStrFor != 0xFF) {
- a = derefActor(_actorToPrintStrFor, "o72_talkActor");
- _string[0].color = a->_talkColor;
- }
- }
-
- actorTalk(_scriptPointer);
-
- _scriptPointer += resStrLen(_scriptPointer) + 1;
-}
-
-void ScummEngine_v72he::o72_talkEgo() {
- push(VAR(VAR_EGO));
- o72_talkActor();
-}
-
-void ScummEngine_v72he::o72_dimArray() {
- int data;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 2: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 3: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 4: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 5: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 6:
- data = kDwordArray;
- break;
- case 7: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- case 204: // SO_UNDIM_ARRAY
- nukeArray(fetchScriptWord());
- return;
- default:
- error("o72_dimArray: default case %d", subOp);
- }
-
- defineArray(fetchScriptWord(), data, 0, 0, 0, pop());
-}
-
-
-void ScummEngine_v72he::o72_dim2dimArray() {
- int data, dim1end, dim2end;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 2: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 3: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 4: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 5: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 6:
- data = kDwordArray;
- break;
- case 7: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- default:
- error("o72_dim2dimArray: default case %d", subOp);
- }
-
- dim1end = pop();
- dim2end = pop();
- defineArray(fetchScriptWord(), data, 0, dim2end, 0, dim1end);
-}
-
-void ScummEngine_v72he::o72_traceStatus() {
- byte string[80];
-
- copyScriptString(string, sizeof(string));
- pop();
-}
-
-void ScummEngine_v72he::o72_kernelGetFunctions() {
- int args[29];
- ArrayHeader *ah;
- getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 1:
- writeVar(0, 0);
- ah = defineArray(0, kByteArray, 0, 0, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
- virtScreenSave(ah->data, args[1], args[2], args[3], args[4]);
- push(readVar(0));
- break;
- default:
- error("o72_kernelGetFunctions: default case %d", args[0]);
- }
-}
-
-void ScummEngine_v72he::o72_drawWizImage() {
- WizImage wi;
- wi.flags = pop();
- wi.y1 = pop();
- wi.x1 = pop();
- wi.resNum = pop();
- wi.state = 0;
- _wiz->displayWizImage(&wi);
-}
-
-void ScummEngine_v72he::o72_debugInput() {
- byte string[255];
-
- copyScriptString(string, sizeof(string));
- int len = resStrLen(string) + 1;
-
- writeVar(0, 0);
- ArrayHeader *ah = defineArray(0, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, string, len);
- push(readVar(0));
- debug(1,"o72_debugInput: String %s", string);
-}
-
-void ScummEngine_v72he::o72_jumpToScript() {
- int args[25];
- int script;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- script = pop();
- flags = fetchScriptByte();
- stopObjectCode();
- runScript(script, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args);
-}
-
-void ScummEngine_v72he::o72_openFile() {
- int mode, slot, i;
- byte filename[256];
-
- mode = pop();
- copyScriptString(filename, sizeof(filename));
-
- debug(1,"Original filename %s", filename);
-
- // There are Macintosh specific versions of HE7.2 games.
- if (_heversion >= 80 && _platform == Common::kPlatformMacintosh) {
- // Work around for filename difference in HE7 file, needs to
- // open 'Water (7)' instead of 'Water Worries (7)'.
- if (_gameId == GID_WATER && _heversion == 99 && !strcmp((char *)filename, "Water.he7")) {
- strcpy((char *)filename, "Water (7)");
- } else {
- char buf1[128];
- buf1[0] = '\0';
- generateSubstResFileName((char *)filename, buf1, sizeof(buf1));
- if (buf1[0]) {
- strcpy((char *)filename, buf1);
- }
- }
- }
-
- int r = convertFilePath(filename);
- debug(1,"Final filename to %s", filename + r);
-
- slot = -1;
- for (i = 1; i < 17; i++) {
- if (_hFileTable[i].isOpen() == false) {
- slot = i;
- break;
- }
- }
-
- if (slot != -1) {
- switch(mode) {
- case 1:
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _saveFileMan->getSavePath());
- if (_hFileTable[slot].isOpen() == false)
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _gameDataPath.c_str());
- break;
- case 2:
- _hFileTable[slot].open((char*)filename + r, Common::File::kFileWriteMode, _saveFileMan->getSavePath());
- break;
- default:
- error("o72_openFile(): wrong open file mode %d", mode);
- }
-
- if (_hFileTable[slot].isOpen() == false)
- slot = -1;
-
- }
- debug(1, "o72_openFile: slot %d, mode %d", slot, mode);
- push(slot);
-}
-
-int ScummEngine_v72he::readFileToArray(int slot, int32 size) {
- if (size == 0)
- size = _hFileTable[slot].size() - _hFileTable[slot].pos();
-
- writeVar(0, 0);
- ArrayHeader *ah = defineArray(0, kByteArray, 0, 0, 0, size);
-
- if (_hFileTable[slot].isOpen())
- _hFileTable[slot].read(ah->data, size + 1);
-
- return readVar(0);
-}
-
-void ScummEngine_v72he::o72_readFile() {
- int slot, val;
- int32 size;
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 4:
- slot = pop();
- val = _hFileTable[slot].readByte();
- push(val);
- break;
- case 5:
- slot = pop();
- val = _hFileTable[slot].readUint16LE();
- push(val);
- break;
- case 6:
- slot = pop();
- val = _hFileTable[slot].readUint32LE();
- push(val);
- break;
- case 8:
- fetchScriptByte();
- size = pop();
- slot = pop();
- val = readFileToArray(slot, size);
- push(val);
- break;
- default:
- error("o72_readFile: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::writeFileFromArray(int slot, int32 resID) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resID);
- int32 size = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
-
- _hFileTable[slot].write(ah->data, size);
-}
-
-void ScummEngine_v72he::o72_writeFile() {
- int32 resID = pop();
- int slot = pop();
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 4:
- _hFileTable[slot].writeByte(resID);
- break;
- case 5:
- _hFileTable[slot].writeUint16LE(resID);
- break;
- case 6:
- _hFileTable[slot].writeUint32LE(resID);
- break;
- case 8:
- fetchScriptByte();
- writeFileFromArray(slot, resID);
- break;
- default:
- error("o72_writeFile: default case %d", subOp);
- }
-}
-
-void ScummEngine_v72he::o72_findAllObjects() {
- int room = pop();
- int i;
-
- if (room != _currentRoom)
- error("o72_findAllObjects: current room is not %d", room);
-
- writeVar(0, 0);
- defineArray(0, kDwordArray, 0, 0, 0, _numLocalObjects);
- writeArray(0, 0, 0, _numLocalObjects);
-
- for (i = 1; i < _numLocalObjects; i++) {
- writeArray(0, 0, i, _objs[i].obj_nr);
- }
-
- push(readVar(0));
-}
-
-void ScummEngine_v72he::o72_deleteFile() {
- byte filename[256];
-
- copyScriptString(filename, sizeof(filename));
- debug(1, "stub o72_deleteFile(%s)", filename);
-}
-
-void ScummEngine_v72he::o72_rename() {
- byte oldFilename[100],newFilename[100];
-
- copyScriptString(newFilename, sizeof(newFilename));
- copyScriptString(oldFilename, sizeof(oldFilename));
-
- debug(1, "stub o72_rename(%s to %s)", oldFilename, newFilename);
-}
-
-void ScummEngine_v72he::o72_getPixel() {
- byte area;
-
- int y = pop();
- int x = pop();
- byte subOp = fetchScriptByte();
-
- VirtScreen *vs = findVirtScreen(y);
- if (vs == NULL || x > _screenWidth - 1 || x < 0) {
- push(-1);
- return;
- }
-
- switch (subOp) {
- case 9: // HE 100
- case 218:
- area = *vs->getBackPixels(x, y - vs->topline);
- break;
- case 8: // HE 100
- case 219:
- area = *vs->getPixels(x, y - vs->topline);
- break;
- default:
- error("o72_getPixel: default case %d", subOp);
- }
- push(area);
-}
-
-void ScummEngine_v72he::o72_pickVarRandom() {
- int num;
- int args[100];
- int32 dim1end;
-
- num = getStackList(args, ARRAYSIZE(args));
- int value = fetchScriptWord();
-
- if (readVar(value) == 0) {
- defineArray(value, kDwordArray, 0, 0, 0, num);
- if (num > 0) {
- int16 counter = 0;
- do {
- writeArray(value, 0, counter + 1, args[counter]);
- } while (++counter < num);
- }
-
- shuffleArray(value, 1, num);
- writeArray(value, 0, 0, 2);
- push(readArray(value, 0, 1));
- return;
- }
-
- num = readArray(value, 0, 0);
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(value));
- dim1end = FROM_LE_32(ah->dim1end);
-
- if (dim1end < num) {
- int32 var_2 = readArray(value, 0, num - 1);
- shuffleArray(value, 1, dim1end);
- if (readArray(value, 0, 1) == var_2) {
- num = 2;
- } else {
- num = 1;
- }
- }
-
- writeArray(value, 0, 0, num + 1);
- push(readArray(value, 0, num));
-}
-
-void ScummEngine_v72he::o72_redimArray() {
- int newX, newY;
- newY = pop();
- newX = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 5:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kIntArray);
- break;
- case 4:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kByteArray);
- break;
- case 6:
- redimArray(fetchScriptWord(), 0, newX, 0, newY, kDwordArray);
- break;
- default:
- error("o72_redimArray: default type %d", subOp);
- }
-}
-
-void ScummEngine_v72he::redimArray(int arrayId, int newDim2start, int newDim2end,
- int newDim1start, int newDim1end, int type) {
- int newSize, oldSize;
-
- if (readVar(arrayId) == 0)
- error("redimArray: Reference to zeroed array pointer");
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(arrayId));
-
- if (!ah)
- error("redimArray: Invalid array (%d) reference", readVar(arrayId));
-
- newSize = arrayDataSizes[type];
- oldSize = arrayDataSizes[FROM_LE_32(ah->type)];
-
- newSize *= (newDim1end - newDim1start + 1) * (newDim2end - newDim2start + 1);
- oldSize *= (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
- (FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
-
- newSize >>= 3;
- oldSize >>= 3;
-
- if (newSize != oldSize)
- error("redimArray: array %d redim mismatch", readVar(arrayId));
-
- ah->type = TO_LE_32(type);
- ah->dim1start = TO_LE_32(newDim1start);
- ah->dim1end = TO_LE_32(newDim1end);
- ah->dim2start = TO_LE_32(newDim2start);
- ah->dim2end = TO_LE_32(newDim2end);
-}
-
-void ScummEngine_v72he::checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end) {
- if (dim1end < dim1start) {
- error("Across max %d smaller than min %d", dim1end, dim1start);
- }
- if (dim2end < dim2start) {
- error("Down max %d smaller than min %d", dim2end, dim2start);
- }
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- assert(ah);
- if (ah->dim2start > dim2start || ah->dim2end < dim2end || ah->dim1start > dim1start || ah->dim1end < dim1end) {
- error("Invalid array access (%d,%d,%d,%d) limit (%d,%d,%d,%d)", dim2start, dim2end, dim1start, dim1end, ah->dim2start, ah->dim2end, ah->dim1start, ah->dim1end);
- }
-}
-
-void ScummEngine_v72he::copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
- int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end)
-{
- byte *dst, *src;
- int dstPitch, srcPitch;
- int rowSize;
- checkArrayLimits(array1, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end);
- checkArrayLimits(array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
- int a12_num = a1_dim2end - a1_dim2start + 1;
- int a11_num = a1_dim1end - a1_dim1start + 1;
- int a22_num = a2_dim2end - a2_dim2start + 1;
- int a21_num = a2_dim1end - a2_dim1start + 1;
- if (a22_num != a12_num || a21_num != a11_num) {
- error("Operation size mismatch (%d vs %d)(%d vs %d)", a12_num, a22_num, a11_num, a21_num);
- }
-
- if (array1 != array2) {
- ArrayHeader *ah1 = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
- assert(ah1);
- ArrayHeader *ah2 = (ArrayHeader *)getResourceAddress(rtString, readVar(array2));
- assert(ah2);
- if (FROM_LE_32(ah1->type) == FROM_LE_32(ah2->type)) {
- copyArrayHelper(ah1, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
- copyArrayHelper(ah2, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
- for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
- memcpy(dst, src, rowSize);
- dst += dstPitch;
- src += srcPitch;
- }
- } else {
- for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start) {
- int a2dim1 = a2_dim1start;
- int a1dim1 = a1_dim1start;
- for (; a1dim1 <= a1_dim1end; ++a1dim1, ++a2dim1) {
- int val = readArray(array2, a2_dim2start, a2dim1);
- writeArray(array1, a1_dim2start, a1dim1, val);
- }
- }
- }
- } else {
- if (a2_dim2start != a1_dim2start || a2_dim1start != a1_dim1start) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
- assert(ah);
- if (a2_dim2start > a1_dim2start) {
- copyArrayHelper(ah, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
- copyArrayHelper(ah, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
- } else {
- copyArrayHelper(ah, a1_dim2end, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
- copyArrayHelper(ah, a2_dim2end, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
- }
- for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
- memcpy(dst, src, rowSize);
- dst += dstPitch;
- src += srcPitch;
- }
- }
- }
-}
-
-void ScummEngine_v72he::copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num) {
- const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;
- const int offset = pitch * (idx2 - FROM_LE_32(ah->dim2start)) + idx1 - FROM_LE_32(ah->dim1start);
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- *num = len1 - idx1 + 1;
- *size = pitch;
- *data = ah->data + offset;
- break;
- case kIntArray:
- *num = (len1 - idx1) * 2 + 2;
- *size = pitch * 2;
- *data = ah->data + offset * 2;
- break;
- case kDwordArray:
- *num = (len1 - idx1) * 4 + 4;
- *size = pitch * 4;
- *data = ah->data + offset * 4;
- break;
- default:
- error("Invalid array type", FROM_LE_32(ah->type));
- }
-}
-
-void ScummEngine_v72he::o72_readINI() {
- byte option[128];
- ArrayHeader *ah;
- const char *entry;
- int len;
-
- copyScriptString(option, sizeof(option));
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 43: // HE 100
- case 6: // number
- if (!strcmp((char *)option, "NoPrinting")) {
- push(1);
- } else if (!strcmp((char *)option, "TextOn")) {
- push(ConfMan.getBool("subtitles"));
- } else {
- push(ConfMan.getInt((char *)option));
- }
- break;
- case 77: // HE 100
- case 7: // string
- entry = (ConfMan.get((char *)option).c_str());
-
- writeVar(0, 0);
- len = resStrLen((const byte *)entry);
- ah = defineArray(0, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, entry, len);
-
- push(readVar(0));
- break;
- default:
- error("o72_readINI: default type %d", subOp);
- }
-
- debug(1, "o72_readINI: Option %s", option);
-}
-
-void ScummEngine_v72he::o72_writeINI() {
- int value;
- byte option[256], string[1024];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 43: // HE 100
- case 6: // number
- value = pop();
- copyScriptString(option, sizeof(option));
- ConfMan.set((char *)option, value);
- debug(1, "o72_writeINI: Option %s Value %d", option, value);
- break;
- case 77: // HE 100
- case 7: // string
- copyScriptString(string, sizeof(string));
- copyScriptString(option, sizeof(option));
-
- // Filter out useless settings
- if (!strcmp((char *)option, "HETest") || !strcmp((char *)option, "Version"))
- return;
-
- // Filter out confusing subtitle setting
- if (!strcmp((char *)option, "TextOn"))
- return;
-
- // Filter out confusing path settings
- if (!strcmp((char *)option, "DownLoadPath") || !strcmp((char *)option, "GameResourcePath") || !strcmp((char *)option, "SaveGamePath"))
- return;
-
- ConfMan.set((char *)option, (char *)string);
- debug(1, "o72_writeINI: Option %s String %s", option, string);
- break;
- default:
- error("o72_writeINI: default type %d", subOp);
- }
-
- ConfMan.flushToDisk();
-}
-
-void ScummEngine_v72he::o72_getResourceSize() {
- const byte *ptr;
- int size, type;
-
- int resid = pop();
- if (_heversion == 72) {
- push(getSoundResourceSize(resid));
- return;
- }
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 13:
- push (getSoundResourceSize(resid));
- return;
- case 14:
- type = rtRoomImage;
- break;
- case 15:
- type = rtImage;
- break;
- case 16:
- type = rtCostume;
- break;
- case 17:
- type = rtScript;
- break;
- default:
- error("o80_getResourceSize: default type %d", subOp);
- }
-
- ptr = getResourceAddress(type, resid);
- assert(ptr);
- size = READ_BE_UINT32(ptr + 4) - 8;
- push(size);
-}
-
-void ScummEngine_v72he::o72_setFilePath() {
- // File related
- byte filename[255];
- copyScriptString(filename, sizeof(filename));
- debug(1,"o72_setFilePath: %s", filename);
-}
-
-void ScummEngine_v72he::o72_setWindowCaption() {
- byte name[1024];
- copyScriptString(name, sizeof(name));
- byte subOp = fetchScriptByte();
-
- debug(1,"o72_setWindowCaption: (%d) %s", subOp, name);
-}
-
-void ScummEngine_v72he::decodeParseString(int m, int n) {
- Actor *a;
- int i, colors, size;
- int args[31];
- byte name[1024];
-
- byte b = fetchScriptByte();
-
- switch (b) {
- case 65: // SO_AT
- _string[m].ypos = pop();
- _string[m].xpos = pop();
- _string[m].overhead = false;
- break;
- case 66: // SO_COLOR
- _string[m].color = pop();
- break;
- case 67: // SO_CLIPPED
- _string[m].right = pop();
- break;
- case 69: // SO_CENTER
- _string[m].center = true;
- _string[m].overhead = false;
- break;
- case 71: // SO_LEFT
- _string[m].center = false;
- _string[m].overhead = false;
- break;
- case 72: // SO_OVERHEAD
- _string[m].overhead = true;
- _string[m].no_talk_anim = false;
- break;
- case 73: // SO_SAY_VOICE
- error("decodeParseString: case 73");
- break;
- case 74: // SO_MUMBLE
- _string[m].no_talk_anim = true;
- break;
- case 75: // SO_TEXTSTRING
- printString(m, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
- break;
- case 194:
- decodeScriptString(name, true);
- printString(m, name);
- break;
- case 0xE1:
- {
- byte *dataPtr = getResourceAddress(rtTalkie, pop());
- byte *text = findWrappedBlock(MKID('TEXT'), dataPtr, 0, 0);
- size = getResourceDataSize(text);
- memcpy(name, text, size);
- printString(m, name);
- }
- break;
- case 0xF9:
- colors = pop();
- if (colors == 1) {
- _string[m].color = pop();
- } else {
- push(colors);
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- _string[m].color = _charsetColorMap[0];
- }
- break;
- case 0xFE:
- _string[m].loadDefault();
- if (n) {
- _actorToPrintStrFor = pop();
- if (_actorToPrintStrFor != 0xFF) {
- a = derefActor(_actorToPrintStrFor, "decodeParseString");
- _string[0].color = a->_talkColor;
- }
- }
- break;
- case 0xFF:
- _string[m].saveDefault();
- break;
- default:
- error("decodeParseString: default case 0x%x", b);
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp
deleted file mode 100644
index f615266131..0000000000
--- a/scumm/script_v7he.cpp
+++ /dev/null
@@ -1,1133 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v70he, x)
-
-void ScummEngine_v70he::setupOpcodes() {
- static const OpcodeEntryv70he opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o6_pushByteVar),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayRead),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayIndexedRead),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o6_invalid),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeByteVar),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayWrite),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayIndexedWrite),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteVarInc),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayInc),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteVarDec),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_byteArrayDec),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o6_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o6_startObject),
- OPCODE(o6_drawObject),
- OPCODE(o6_drawObjectAt),
- OPCODE(o6_invalid),
- /* 64 */
- OPCODE(o6_invalid),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_stopMusic),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o6_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o60_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o70_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_startMusic),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o70_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o70_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o6_getVerbFromXY),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_invalid),
- OPCODE(o70_resourceRoutines),
- /* 9C */
- OPCODE(o60_roomOps),
- OPCODE(o60_actorOps),
- OPCODE(o6_verbOps),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o6_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o6_arrayOps),
- OPCODE(o6_saveRestoreVerbs),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o60_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorAnimCounter1),
- /* AC */
- OPCODE(o6_invalid),
- OPCODE(o6_isAnyOf),
- OPCODE(o70_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o6_talkActor),
- OPCODE(o6_talkEgo),
- /* BC */
- OPCODE(o6_dimArray),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o6_dim2dimArray),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o60_kernelGetFunctions),
- OPCODE(o70_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o6_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o60_closeFile),
- OPCODE(o60_openFile),
- OPCODE(o60_readFile),
- /* DC */
- OPCODE(o60_writeFile),
- OPCODE(o6_findAllObjects),
- OPCODE(o60_deleteFile),
- OPCODE(o60_rename),
- /* E0 */
- OPCODE(o60_soundOps),
- OPCODE(o6_getPixel),
- OPCODE(o60_localizeArrayToScript),
- OPCODE(o6_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o70_seekFilePos),
- OPCODE(o60_redimArray),
- OPCODE(o60_readFilePos),
- /* EC */
- OPCODE(o70_copyString),
- OPCODE(o70_getStringWidth),
- OPCODE(o70_getStringLen),
- OPCODE(o70_appendString),
- /* F0 */
- OPCODE(o70_concatString),
- OPCODE(o70_compareString),
- OPCODE(o70_isResourceLoaded),
- OPCODE(o70_readINI),
- /* F4 */
- OPCODE(o70_writeINI),
- OPCODE(o70_getStringLenForWidth),
- OPCODE(o70_getCharIndexInString),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o6_invalid),
- OPCODE(o70_setFilePath),
- OPCODE(o70_setWindowCaption),
- OPCODE(o70_polygonOps),
- /* FC */
- OPCODE(o70_polygonHit),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesv70he = opcodes;
-}
-
-void ScummEngine_v70he::executeOpcode(byte i) {
- OpcodeProcv70he op = _opcodesv70he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v70he::getOpcodeDesc(byte i) {
- return _opcodesv70he[i].desc;
-}
-
-int ScummEngine_v70he::getStringCharWidth(byte chr) {
- int charset = _string[0]._default.charset;
-
- byte *ptr = getResourceAddress(rtCharset, charset);
- assert(ptr);
- ptr += 29;
-
- int spacing = 0;
-
- int offs = READ_LE_UINT32(ptr + chr * 4 + 4);
- if (offs) {
- spacing = ptr[offs] + (signed char)ptr[offs + 2];
- }
-
- return spacing;
-}
-
-int ScummEngine_v70he::setupStringArray(int size) {
- writeVar(0, 0);
- defineArray(0, kStringArray, 0, size + 1);
- writeArray(0, 0, 0, 0);
- return readVar(0);
-}
-
-void ScummEngine_v70he::appendSubstring(int dst, int src, int srcOffs, int len) {
- int dstOffs, value;
- int i = 0;
-
- if (len == -1) {
- len = resStrLen(getStringAddress(src));
- srcOffs = 0;
- }
-
- dstOffs = resStrLen(getStringAddress(dst));
-
- len -= srcOffs;
- len++;
-
- while (i < len) {
- writeVar(0, src);
- value = readArray(0, 0, srcOffs + i);
- writeVar(0, dst);
- writeArray(0, 0, dstOffs + i, value);
- i++;
- }
-
- writeArray(0, 0, dstOffs + i, 0);
-}
-
-void ScummEngine_v70he::o70_startSound() {
- int var, value;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 9:
- _heSndFlags |= 4;
- break;
- case 23:
- value = pop();
- var = pop();
- _heSndSoundId = pop();
- _sound->setSoundVar(_heSndSoundId, var, value);
- break;
- case 25:
- value = pop();
- _heSndSoundId = pop();
- _sound->addSoundToQueue(_heSndSoundId, 0, 0, 8);
- case 56:
- _heSndFlags |= 16;
- break;
- case 164:
- _heSndFlags |= 2;
- break;
- case 224:
- _heSndSoundFreq = pop();
- break;
- case 230:
- _heSndChannel = pop();
- break;
- case 231:
- _heSndOffset = pop();
- break;
- case 232:
- _heSndSoundId = pop();
- _heSndOffset = 0;
- _heSndSoundFreq = 11025;
- _heSndChannel = VAR(VAR_SOUND_CHANNEL);
- break;
- case 245:
- _heSndFlags |= 1;
- break;
- case 255:
- _sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags);
- _heSndFlags = 0;
- break;
-
- default:
- error("o70_startSound invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v70he::o70_pickupObject() {
- int obj, room;
-
- room = pop();
- obj = pop();
- if (room == 0)
- room = getObjectRoom(obj);
-
- addObjectToInventory(obj, room);
- putOwner(obj, VAR(VAR_EGO));
- if (_heversion <= 70) {
- putClass(obj, kObjectClassUntouchable, 1);
- putState(obj, 1);
- markObjectRectAsDirty(obj);
- clearDrawObjectQueue();
- }
- runInventoryScript(obj); /* Difference */
-}
-
-void ScummEngine_v70he::o70_getActorRoom() {
- int act = pop();
-
- if (act < _numActors) {
- Actor *a = derefActor(act, "o70_getActorRoom");
- push(a->_room);
- } else
- push(getObjectRoom(act));
-}
-
-void ScummEngine_v70he::o70_resourceRoutines() {
- int objidx, resid;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 100: // SO_LOAD_SCRIPT
- resid = pop();
- ensureResourceLoaded(rtScript, resid);
- break;
- case 101: // SO_LOAD_SOUND
- resid = pop();
- ensureResourceLoaded(rtSound, resid);
- break;
- case 102: // SO_LOAD_COSTUME
- resid = pop();
- ensureResourceLoaded(rtCostume, resid);
- break;
- case 103: // SO_LOAD_ROOM
- resid = pop();
- ensureResourceLoaded(rtRoomImage, resid);
- ensureResourceLoaded(rtRoom, resid);
- break;
- case 104: // SO_NUKE_SCRIPT
- resid = pop();
- res.nukeResource(rtScript, resid);
- break;
- case 105: // SO_NUKE_SOUND
- resid = pop();
- res.nukeResource(rtSound, resid);
- break;
- case 106: // SO_NUKE_COSTUME
- resid = pop();
- res.nukeResource(rtCostume, resid);
- break;
- case 107: // SO_NUKE_ROOM
- resid = pop();
- res.nukeResource(rtRoom, resid);
- res.nukeResource(rtRoomImage, resid);
- break;
- case 108: // SO_LOCK_SCRIPT
- resid = pop();
- if (resid >= _numGlobalScripts)
- break;
- res.lock(rtScript, resid);
- break;
- case 109: // SO_LOCK_SOUND
- resid = pop();
- res.lock(rtSound, resid);
- break;
- case 110: // SO_LOCK_COSTUME
- resid = pop();
- res.lock(rtCostume, resid);
- break;
- case 111: // SO_LOCK_ROOM
- resid = pop();
- if (_heversion <= 71 && resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
- res.lock(rtRoom, resid);
- res.lock(rtRoomImage, resid);
- break;
- case 112: // SO_UNLOCK_SCRIPT
- resid = pop();
- if (resid >= _numGlobalScripts)
- break;
- res.unlock(rtScript, resid);
- break;
- case 113: // SO_UNLOCK_SOUND
- resid = pop();
- res.unlock(rtSound, resid);
- break;
- case 114: // SO_UNLOCK_COSTUME
- resid = pop();
- res.unlock(rtCostume, resid);
- break;
- case 115: // SO_UNLOCK_ROOM
- resid = pop();
- if (_heversion <= 71 && resid > 0x7F)
- resid = _resourceMapper[resid & 0x7F];
- res.unlock(rtRoom, resid);
- res.unlock(rtRoomImage, resid);
- break;
- case 116:
- break;
- case 117: // SO_LOAD_CHARSET
- resid = pop();
- loadCharset(resid);
- break;
- case 118: // SO_NUKE_CHARSET
- resid = pop();
- nukeCharset(resid);
- break;
- case 119: // SO_LOAD_OBJECT
- {
- int obj = pop();
- int room = getObjectRoom(obj);
- loadFlObject(obj, room);
- break;
- }
- case 120:
- resid = pop();
- if (resid >= _numGlobalScripts)
- break;
- //queueLoadResource(rtScript, resid);
- break;
- case 121:
- resid = pop();
- //queueLoadResource(rtSound, resid);
- break;
- case 122:
- resid = pop();
- //queueLoadResource(rtCostume, resid);
- break;
- case 123:
- resid = pop();
- //queueLoadResource(rtRoomImage, resid);
- break;
- case 159:
- resid = pop();
- res.unlock(rtImage, resid);
- break;
- case 192:
- resid = pop();
- res.nukeResource(rtImage, resid);
- break;
- case 201:
- resid = pop();
- ensureResourceLoaded(rtImage, resid);
- break;
- case 202:
- resid = pop();
- res.lock(rtImage, resid);
- break;
- case 203:
- resid = pop();
- //queueLoadResource(rtImage, resid);
- break;
- case 233:
- resid = pop();
- objidx = getObjectIndex(resid);
- if (objidx == -1)
- break;
- res.lock(rtFlObject, _objs[objidx].fl_object_index);
- break;
- case 235:
- resid = pop();
- objidx = getObjectIndex(resid);
- if (objidx == -1)
- break;
- res.unlock(rtFlObject, _objs[objidx].fl_object_index);
- break;
- case 239:
- // Used in airport
- break;
- default:
- error("o70_resourceRoutines: default case %d", subOp);
- }
-}
-
-void ScummEngine_v70he::o70_systemOps() {
- byte *src, string[256];
- int id, len;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 158:
- restart();
- break;
- case 160:
- // Confirm shutdown
- shutDown();
- break;
- case 244:
- shutDown();
- break;
- case 250:
- id = pop();
- src = getStringAddress(id);
- len = resStrLen(src) + 1;
- memcpy(string, src, len);
- debug(0, "Start executable (%s)", string);
- break;
- case 251:
- convertMessageToString(_scriptPointer, string, sizeof(string));
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
- debug(0, "Start executable (%s)", string);
- break;
- case 252:
- convertMessageToString(_scriptPointer, string, sizeof(string));
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
- debug(0, "Start game (%s)", string);
- break;
- case 253:
- id = pop();
- src = getStringAddress(id);
- len = resStrLen(src) + 1;
- memcpy(string, src, len);
- debug(0, "Start game (%s)", string);
- break;
- default:
- error("o70_systemOps invalid case %d", subOp);
- }
-}
-
-void ScummEngine_v70he::o70_seekFilePos() {
- int mode, offset, slot;
- mode = pop();
- offset = pop();
- slot = pop();
-
- if (slot == -1)
- return;
-
- switch (mode) {
- case 1:
- _hFileTable[slot].seek(offset, SEEK_SET);
- break;
- case 2:
- _hFileTable[slot].seek(offset, SEEK_CUR);
- break;
- case 3:
- _hFileTable[slot].seek(offset, SEEK_END);
- break;
- default:
- error("o70_seekFilePos: default case 0x%x", mode);
- }
-}
-
-void ScummEngine_v70he::o70_copyString() {
- int dst, size;
- int src = pop();
-
- size = resStrLen(getStringAddress(src)) + 1;
- dst = setupStringArray(size);
-
- appendSubstring(dst, src, -1, -1);
-
- push(dst);
-}
-
-void ScummEngine_v70he::o70_getStringWidth() {
- int array, pos, len;
- int chr, width = 0;
-
- len = pop();
- pos = pop();
- array = pop();
-
- if (len == -1) {
- pos = 0;
- len = resStrLen(getStringAddress(array));
- }
-
- writeVar(0, array);
- while (pos <= len) {
- chr = readArray(0, 0, pos);
- if (chr == 0)
- break;
- width += getStringCharWidth(chr);
- pos++;
- }
-
- push(width);
-}
-
-void ScummEngine_v70he::o70_kernelSetFunctions() {
- int args[29];
- int num;
- Actor *a;
-
- num = getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 1:
- // Used to restore images when decorating cake in
- // Fatty Bear's Birthday Surprise
- virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
- break;
- case 20: // HE72+
- a = derefActor(args[1], "o70_kernelSetFunctions: 20");
- ((ScummEngine_v71he *)this)->queueAuxBlock(a);
- break;
- case 21:
- _skipDrawObject = 1;
- break;
- case 22:
- _skipDrawObject = 0;
- break;
- case 23:
- _charset->clearCharsetMask();
- _fullRedraw = true;
- break;
- case 24:
- _skipProcessActors = 1;
- redrawAllActors();
- break;
- case 25:
- _skipProcessActors = 0;
- redrawAllActors();
- break;
- case 26:
- a = derefActor(args[1], "o70_kernelSetFunctions: 26");
- a->_auxBlock.r.left = 0;
- a->_auxBlock.r.right = -1;
- a->_auxBlock.r.top = 0;
- a->_auxBlock.r.bottom = -2;
- break;
- case 30:
- a = derefActor(args[1], "o70_kernelSetFunctions: 30");
- a->_clipOverride.bottom = args[2];
- break;
- case 42:
- _wiz->_rectOverrideEnabled = true;
- _wiz->_rectOverride.left = args[1];
- _wiz->_rectOverride.top = args[2];
- _wiz->_rectOverride.right = args[3];
- _wiz->_rectOverride.bottom = args[4];
- break;
- case 43:
- _wiz->_rectOverrideEnabled = false;
- break;
- default:
- error("o70_kernelSetFunctions: default case %d (param count %d)", args[0], num);
- }
-}
-
-void ScummEngine_v70he::o70_getStringLen() {
- int id, len;
- byte *addr;
-
- id = pop();
-
- addr = getStringAddress(id);
- if (!addr)
- error("o70_getStringLen: Reference to zeroed array pointer (%d)", id);
-
- len = resStrLen(getStringAddress(id));
- push(len);
-}
-
-void ScummEngine_v70he::o70_appendString() {
- int dst, size;
-
- int len = pop();
- int srcOffs = pop();
- int src = pop();
-
- size = len - srcOffs + 2;
- dst = setupStringArray(size);
-
- appendSubstring(dst, src, srcOffs, len);
-
- push(dst);
-}
-
-void ScummEngine_v70he::o70_concatString() {
- int dst, size;
-
- int src2 = pop();
- int src1 = pop();
-
- size = resStrLen(getStringAddress(src1));
- size += resStrLen(getStringAddress(src2)) + 1;
- dst = setupStringArray(size);
-
- appendSubstring(dst, src1, 0, -1);
- appendSubstring(dst, src2, 0, -1);
-
- push(dst);
-}
-
-void ScummEngine_v70he::o70_compareString() {
- int result;
-
- int array1 = pop();
- int array2 = pop();
-
- byte *string1 = getStringAddress(array1);
- if (!string1)
- error("o70_compareString: Reference to zeroed array pointer (%d)", array1);
-
- byte *string2 = getStringAddress(array2);
- if (!string2)
- error("o70_compareString: Reference to zeroed array pointer (%d)", array2);
-
- while (*string1 == *string2) {
- if (*string2 == 0) {
- push(0);
- return;
- }
-
- string1++;
- string2++;
- }
-
- result = (*string1 > *string2) ? -1 : 1;
- push(result);
-}
-
-void ScummEngine_v70he::o70_isResourceLoaded() {
- // Reports percentage of resource loaded by queue
- int type;
-
- byte subOp = fetchScriptByte();
- /* int idx = */ pop();
-
- switch (subOp) {
- case 18:
- type = rtImage;
- break;
- case 226:
- type = rtRoom;
- break;
- case 227:
- type = rtCostume;
- break;
- case 228:
- type = rtSound;
- break;
- case 229:
- type = rtScript;
- break;
- default:
- error("o70_isResourceLoaded: default case %d", subOp);
- }
-
- push(100);
-}
-
-void ScummEngine_v70he::o70_readINI() {
- byte option[256];
- ArrayHeader *ah;
- const char *entry;
- int len, type;
-
- convertMessageToString(_scriptPointer, option, sizeof(option));
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- type = pop();
- switch (type) {
- case 1: // number
- if (!strcmp((char *)option, "NoPrinting")) {
- push(1);
- } else if (!strcmp((char *)option, "TextOn")) {
- push(ConfMan.getBool("subtitles"));
- } else {
- push(ConfMan.getInt((char *)option));
- }
- break;
- case 2: // string
- entry = (ConfMan.get((char *)option).c_str());
-
- writeVar(0, 0);
- len = resStrLen((const byte *)entry);
- ah = defineArray(0, kStringArray, 0, len);
- memcpy(ah->data, entry, len);
-
- push(readVar(0));
- break;
- default:
- error("o70_readINI: default type %d", type);
- }
- debug(1, "o70_readINI: Option %s", option);
-}
-
-void ScummEngine_v70he::o70_writeINI() {
- int type, value;
- byte option[256], string[256];
- int len;
-
- type = pop();
- value = pop();
-
- convertMessageToString(_scriptPointer, option, sizeof(option));
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- switch (type) {
- case 1: // number
- ConfMan.set((char *)option, value);
- debug(1, "o70_writeINI: Option %s Value %d", option, value);
- break;
- case 2: // string
- convertMessageToString(_scriptPointer, string, sizeof(string));
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
- ConfMan.set((char *)option, (char *)string);
- debug(1, "o70_writeINI: Option %s String %s", option, string);
- break;
- default:
- error("o70_writeINI: default type %d", type);
- }
-}
-
-void ScummEngine_v70he::o70_getStringLenForWidth() {
- int chr, max;
- int array, len, pos, width = 0;
-
- max = pop();
- pos = pop();
- array = pop();
-
- len = resStrLen(getStringAddress(array));
-
- writeVar(0, array);
- while (pos <= len) {
- chr = readArray(0, 0, pos);
- width += getStringCharWidth(chr);
- if (width >= max) {
- push(pos);
- return;
- }
- pos++;
- }
-
- push(len);
-}
-
-void ScummEngine_v70he::o70_getCharIndexInString() {
- int array, end, len, pos, value;
-
- value = pop();
- end = pop();
- pos = pop();
- array = pop();
-
- if (end >= 0) {
- len = resStrLen(getStringAddress(array));
- if (len < end)
- end = len;
- } else {
- end = 0;
- }
-
- if (pos < 0)
- pos = 0;
-
- writeVar(0, array);
- if (end > pos) {
- while (end >= pos) {
- if (readArray(0, 0, pos) == value) {
- push(pos);
- return;
- }
- pos++;
- }
- } else {
- while (end <= pos) {
- if (readArray(0, 0, pos) == value) {
- push(pos);
- return;
- }
- pos--;
- }
- }
-
- push(-1);
-}
-
-void ScummEngine_v70he::o70_setFilePath() {
- // File related
- int len;
- byte filename[100];
-
- convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
- len = resStrLen(_scriptPointer);
- _scriptPointer += len + 1;
-
- debug(1,"stub o70_setFilePath(%s)", filename);
-}
-
-void ScummEngine_v70he::o70_setWindowCaption() {
- byte subOp = fetchScriptByte();
- int len = resStrLen(_scriptPointer);
- debug(1,"stub o70_setWindowCaption(%d, \"%s\")", subOp, _scriptPointer);
- _scriptPointer += len + 1;
-}
-
-void ScummEngine_v70he::o70_polygonOps() {
- int vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y;
- int id, fromId, toId;
- bool flag;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 68: // HE 100
- case 69: // HE 100
- case 246:
- case 248:
- vert4y = pop();
- vert4x = pop();
- vert3y = pop();
- vert3x = pop();
- vert2y = pop();
- vert2x = pop();
- vert1y = pop();
- vert1x = pop();
- flag = (subOp == 69 || subOp == 248);
- id = pop();
- _wiz->polygonStore(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
- break;
- case 28: // HE 100
- case 247:
- toId = pop();
- fromId = pop();
- _wiz->polygonErase(fromId, toId);
- break;
- default:
- error("o70_polygonOps: default case %d", subOp);
- }
-}
-
-void ScummEngine_v70he::o70_polygonHit() {
- int y = pop();
- int x = pop();
- push(_wiz->polygonHit(0, x, y));
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp
deleted file mode 100644
index b5f9f48466..0000000000
--- a/scumm/script_v8.cpp
+++ /dev/null
@@ -1,1496 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/config-manager.h"
-#include "common/system.h"
-#include "scumm/actor.h"
-#include "scumm/akos.h"
-#include "scumm/charset.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/intern.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/verbs.h"
-#include "scumm/smush/smush_player.h"
-#include "sound/mixer.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v8, x)
-
-void ScummEngine_v8::setupOpcodes() {
- static const OpcodeEntryV8 opcodes[256] = {
- /* 00 */
- OPCODE(o6_invalid),
- OPCODE(o6_pushWord),
- OPCODE(o6_pushWordVar),
- OPCODE(o6_wordArrayRead),
- /* 04 */
- OPCODE(o6_wordArrayIndexedRead),
- OPCODE(o6_dup),
- OPCODE(o6_pop),
- OPCODE(o6_not),
- /* 08 */
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- /* 0C */
- OPCODE(o6_le),
- OPCODE(o6_ge),
- OPCODE(o6_add),
- OPCODE(o6_sub),
- /* 10 */
- OPCODE(o6_mul),
- OPCODE(o6_div),
- OPCODE(o6_land),
- OPCODE(o6_lor),
- /* 14 */
- OPCODE(o6_band),
- OPCODE(o6_bor),
- OPCODE(o8_mod),
- OPCODE(o6_invalid),
- /* 18 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 48 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 4C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 50 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 54 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 58 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 5C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 60 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 64 */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o6_jump),
- OPCODE(o6_breakHere),
- /* 68 */
- OPCODE(o6_delayFrames),
- OPCODE(o8_wait),
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- /* 6C */
- OPCODE(o6_delayMinutes),
- OPCODE(o6_writeWordVar),
- OPCODE(o6_wordVarInc),
- OPCODE(o6_wordVarDec),
- /* 70 */
- OPCODE(o8_dimArray),
- OPCODE(o6_wordArrayWrite),
- OPCODE(o6_wordArrayInc),
- OPCODE(o6_wordArrayDec),
- /* 74 */
- OPCODE(o8_dim2dimArray),
- OPCODE(o6_wordArrayIndexedWrite),
- OPCODE(o8_arrayOps),
- OPCODE(o6_invalid),
- /* 78 */
- OPCODE(o6_invalid),
- OPCODE(o6_startScript),
- OPCODE(o6_startScriptQuick),
- OPCODE(o6_stopObjectCode),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_jumpToScript),
- OPCODE(o6_dummy), // O_RETURN boils down to a NOP
- OPCODE(o6_startObject),
- /* 80 */
- OPCODE(o6_stopObjectScript),
- OPCODE(o6_cutscene),
- OPCODE(o6_endCutscene),
- OPCODE(o6_freezeUnfreeze),
- /* 84 */
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_stopSentence),
- OPCODE(o6_invalid),
- /* 88 */
- OPCODE(o6_invalid),
- OPCODE(o6_setClass),
- OPCODE(o6_setState),
- OPCODE(o6_setOwner),
- /* 8C */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_printActor),
- /* 90 */
- OPCODE(o6_printEgo),
- OPCODE(o6_talkActor),
- OPCODE(o6_talkEgo),
- OPCODE(o6_printLine),
- /* 94 */
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- OPCODE(o8_blastText),
- /* 98 */
- OPCODE(o8_drawObject),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 9C */
- OPCODE(o8_cursorCommand),
- OPCODE(o6_loadRoom),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_walkActorToObj),
- /* A0 */
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- /* A4 */
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- OPCODE(o6_pickupObject),
- OPCODE(o6_setBoxFlags),
- /* A8 */
- OPCODE(o6_createBoxMatrix),
- OPCODE(o6_invalid),
- OPCODE(o8_resourceRoutines),
- OPCODE(o8_roomOps),
- /* AC */
- OPCODE(o8_actorOps),
- OPCODE(o8_cameraOps),
- OPCODE(o8_verbOps),
- OPCODE(o6_startSound),
- /* B0 */
- OPCODE(o6_startMusic),
- OPCODE(o6_stopSound),
- OPCODE(o6_soundKludge),
- OPCODE(o8_systemOps),
- /* B4 */
- OPCODE(o6_saveRestoreVerbs),
- OPCODE(o6_setObjectName),
- OPCODE(o6_getDateTime),
- OPCODE(o6_drawBox),
- /* B8 */
- OPCODE(o6_invalid),
- OPCODE(o8_startVideo),
- OPCODE(o8_kernelSetFunctions),
- OPCODE(o6_invalid),
- /* BC */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C0 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C8 */
- OPCODE(o6_startScriptQuick2),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_pickOneOf),
- OPCODE(o6_pickOneOfDefault),
- /* CC */
- OPCODE(o6_invalid),
- OPCODE(o6_isAnyOf),
- OPCODE(o6_getRandomNumber),
- OPCODE(o6_getRandomNumberRange),
- /* D0 */
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_getState),
- OPCODE(o6_getOwner),
- OPCODE(o6_isScriptRunning),
- /* D4 */
- OPCODE(o6_invalid),
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_abs),
- OPCODE(o6_invalid),
- /* D8 */
- OPCODE(o8_kernelGetFunctions),
- OPCODE(o6_isActorInBox),
- OPCODE(o6_getVerbEntrypoint),
- OPCODE(o6_getActorFromXY),
- /* DC */
- OPCODE(o6_findObject),
- OPCODE(o6_getVerbFromXY),
- OPCODE(o6_invalid),
- OPCODE(o6_findInventory),
- /* E0 */
- OPCODE(o6_getInventoryCount),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_getActorRoom),
- OPCODE(o6_getActorWalkBox),
- /* E4 */
- OPCODE(o6_getActorMoving),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorLayer),
- /* E8 */
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getActorWidth),
- OPCODE(o6_getObjectNewDir),
- OPCODE(o6_getObjectX),
- /* EC */
- OPCODE(o6_getObjectY),
- OPCODE(o8_getActorChore),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distPtPt),
- /* F0 */
- OPCODE(o8_getObjectImageX),
- OPCODE(o8_getObjectImageY),
- OPCODE(o8_getObjectImageWidth),
- OPCODE(o8_getObjectImageHeight),
- /* F4 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o8_getStringWidth),
- OPCODE(o8_getActorZPlane),
- /* F8 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* FC */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV8 = opcodes;
-}
-
-void ScummEngine_v8::executeOpcode(byte i) {
- OpcodeProcV8 op = _opcodesV8[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v8::getOpcodeDesc(byte i) {
- return _opcodesV8[i].desc;
-}
-
-// In V8, the word size is 4 byte, not 2 bytes as in V6/V7 games
-uint ScummEngine_v8::fetchScriptWord() {
- return fetchScriptDWord();
-}
-
-int ScummEngine_v8::fetchScriptWordSigned() {
- return (int32)fetchScriptDWordSigned();
-}
-
-int ScummEngine_v8::readVar(uint var) {
- debugC(DEBUG_VARS, "readvar(%d)", var);
-
- if (!(var & 0xF0000000)) {
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(r)");
- return _scummVars[var];
- }
-
- if (var & 0x80000000) {
- var &= 0x7FFFFFFF;
- checkRange(_numBitVariables - 1, 0, var, "Bit variable %d out of range(r)");
- return (_bitVars[var >> 3] & (1 << (var & 7))) ? 1 : 0;
- }
-
- if (var & 0x40000000) {
- var &= 0xFFFFFFF;
- checkRange(25, 0, var, "Local variable %d out of range(r)");
- return vm.localvar[_currentScript][var];
- }
-
- error("Illegal varbits (r)");
- return -1;
-}
-
-void ScummEngine_v8::writeVar(uint var, int value) {
- debugC(DEBUG_VARS, "writeVar(%d, %d)", var, value);
-
- if (!(var & 0xF0000000)) {
- checkRange(_numVariables - 1, 0, var, "Variable %d out of range(w)");
-
- if (var == VAR_CHARINC && ConfMan.hasKey("talkspeed")) {
- uint talkspeed = ConfMan.getInt("talkspeed");
- if (talkspeed <= 9)
- VAR(VAR_CHARINC) = talkspeed;
- } else
- _scummVars[var] = value;
-
- if ((_varwatch == (int)var) || (_varwatch == 0)) {
- if (vm.slot[_currentScript].number < 100)
- debugC(DEBUG_VARS, "vars[%d] = %d (via script-%d)", var, value, vm.slot[_currentScript].number);
- else
- debugC(DEBUG_VARS, "vars[%d] = %d (via room-%d-%d)", var, value, _currentRoom, vm.slot[_currentScript].number);
- }
- return;
- }
-
- if (var & 0x80000000) {
- var &= 0x7FFFFFFF;
- checkRange(_numBitVariables - 1, 0, var, "Bit variable %d out of range(w)");
-
- if (value)
- _bitVars[var >> 3] |= (1 << (var & 7));
- else
- _bitVars[var >> 3] &= ~(1 << (var & 7));
- return;
- }
-
- if (var & 0x40000000) {
- var &= 0xFFFFFFF;
- checkRange(25, 0, var, "Local variable %d out of range(w)");
- vm.localvar[_currentScript][var] = value;
- return;
- }
-
- error("Illegal varbits (w)");
-}
-
-void ScummEngine_v8::decodeParseString(int m, int n) {
- byte b = fetchScriptByte();
-
- switch (b) {
- case 0xC8: // SO_PRINT_BASEOP
- _string[m].loadDefault();
- if (n)
- _actorToPrintStrFor = pop();
- break;
- case 0xC9: // SO_PRINT_END
- _string[m].saveDefault();
- break;
- case 0xCA: // SO_PRINT_AT
- _string[m].ypos = pop();
- _string[m].xpos = pop();
- _string[m].overhead = false;
- break;
- case 0xCB: // SO_PRINT_COLOR
- _string[m].color = pop();
- break;
- case 0xCC: // SO_PRINT_CENTER
- _string[m].center = true;
- _string[m].overhead = false;
- break;
- case 0xCD: // SO_PRINT_CHARSET Set print character set
- _string[m].charset = pop();
- break;
- case 0xCE: // SO_PRINT_LEFT
- _string[m].center = false;
- _string[m].overhead = false;
- break;
- case 0xCF: // SO_PRINT_OVERHEAD
- _string[m].overhead = true;
- _string[m].no_talk_anim = false;
- break;
- case 0xD0: // SO_PRINT_MUMBLE
- _string[m].no_talk_anim = true;
- break;
- case 0xD1: // SO_PRINT_STRING
- if (m == 5)
- enqueueText(_scriptPointer, _string[m].xpos, _string[m].ypos, _string[m].color, _string[m].charset, _string[m].center);
- else
- printString(m, _scriptPointer);
- _scriptPointer += resStrLen(_scriptPointer) + 1;
-
- break;
- case 0xD2: // SO_PRINT_WRAP Set print wordwrap
- //debug(0, "decodeParseString: SO_PRINT_WRAP");
- break;
- default:
- error("decodeParseString: default case 0x%x", b);
- }
-}
-
-void ScummEngine_v8::readArrayFromIndexFile() {
- int num;
- int a, b;
-
- while ((num = _fileHandle->readUint32LE()) != 0) {
- a = _fileHandle->readUint32LE();
- b = _fileHandle->readUint32LE();
-
- if (b != 0)
- defineArray(num, kIntArray, b, a);
- else
- defineArray(num, kIntArray, a, b);
- }
-}
-
-void ScummEngine_v8::o8_mod() {
- int a = pop();
- push(pop() % a);
-}
-
-void ScummEngine_v8::o8_wait() {
- int actnum;
- int offs = -2;
- Actor *a;
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0x1E: // SO_WAIT_FOR_ACTOR Wait for actor (to finish current action?)
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o8_wait:SO_WAIT_FOR_ACTOR");
- if (a->isInCurrentRoom() && a->_moving)
- break;
- return;
- case 0x1F: // SO_WAIT_FOR_MESSAGE Wait for message
- if (VAR(VAR_HAVE_MSG))
- break;
- return;
- case 0x20: // SO_WAIT_FOR_CAMERA Wait for camera (to finish current action?)
- if (camera._dest != camera._cur)
- break;
- return;
- case 0x21: // SO_WAIT_FOR_SENTENCE
- if (_sentenceNum) {
- if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- }
- if (!isScriptInUse(VAR(VAR_SENTENCE_SCRIPT)))
- return;
- break;
- case 0x22: // SO_WAIT_FOR_ANIMATION
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o8_wait:SO_WAIT_FOR_ANIMATION");
- if (a->isInCurrentRoom() && a->_needRedraw)
- break;
- return;
- case 0x23: // SO_WAIT_FOR_TURN
- offs = fetchScriptWordSigned();
- actnum = pop();
- a = derefActor(actnum, "o8_wait:SO_WAIT_FOR_TURN");
- if (a->isInCurrentRoom() && a->_moving & MF_TURN)
- break;
- return;
- default:
- error("o8_wait: default case 0x%x", subOp);
- }
-
- _scriptPointer += offs;
- o6_breakHere();
-}
-
-void ScummEngine_v8::o8_dimArray() {
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord();
-
- switch (subOp) {
- case 0x0A: // SO_ARRAY_SCUMMVAR
- defineArray(array, kIntArray, 0, pop());
- break;
- case 0x0B: // SO_ARRAY_STRING
- defineArray(array, kStringArray, 0, pop());
- break;
- case 0x0C: // SO_ARRAY_UNDIM
- nukeArray(array);
- break;
- default:
- error("o8_dimArray: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_dim2dimArray() {
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord(), a, b;
-
- switch (subOp) {
- case 0x0A: // SO_ARRAY_SCUMMVAR
- b = pop();
- a = pop();
- defineArray(array, kIntArray, a, b);
- break;
- case 0x0B: // SO_ARRAY_STRING
- b = pop();
- a = pop();
- defineArray(array, kStringArray, a, b);
- break;
- case 0x0C: // SO_ARRAY_UNDIM
- nukeArray(array);
- break;
- default:
- error("o8_dim2dimArray: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_arrayOps() {
- byte subOp = fetchScriptByte();
- int array = fetchScriptWord();
- int b, c, d, len;
- ArrayHeader *ah;
- int list[128];
-
- switch (subOp) {
- case 0x14: // SO_ASSIGN_STRING
- b = pop();
- len = resStrLen(_scriptPointer);
- ah = defineArray(array, kStringArray, 0, len + 1);
- copyScriptString(ah->data + b);
- break;
- case 0x15: // SO_ASSIGN_SCUMMVAR_LIST
- b = pop();
- len = getStackList(list, ARRAYSIZE(list));
- d = readVar(array);
- if (d == 0) {
- defineArray(array, kIntArray, 0, b + len);
- }
- while (--len >= 0) {
- writeArray(array, 0, b + len, list[len]);
- }
- break;
- case 0x16: // SO_ASSIGN_2DIM_LIST
- b = pop();
- len = getStackList(list, ARRAYSIZE(list));
- d = readVar(array);
- if (d == 0)
- error("Must DIM a two dimensional array before assigning");
- c = pop();
- while (--len >= 0) {
- writeArray(array, c, b + len, list[len]);
- }
- break;
- default:
- error("o8_arrayOps: default case 0x%x (array %d)", subOp, array);
- }
-}
-
-void ScummEngine_v8::o8_blastText() {
- // FIXME
- decodeParseString(5, 0);
-}
-
-void ScummEngine_v8::o8_cursorCommand() {
- byte subOp = fetchScriptByte();
- int a, i;
- int args[16];
-
- switch (subOp) {
- case 0xDC: // SO_CURSOR_ON Turn cursor on
- _cursor.state = 1;
- verbMouseOver(0);
- break;
- case 0xDD: // SO_CURSOR_OFF Turn cursor off
- _cursor.state = 0;
- verbMouseOver(0);
- break;
- case 0xDE: // SO_CURSOR_SOFT_ON Turn soft cursor on
- _cursor.state++;
- verbMouseOver(0);
- break;
- case 0xDF: // SO_CURSOR_SOFT_OFF Turn soft cursor off
- _cursor.state--;
- verbMouseOver(0);
- break;
- case 0xE0: // SO_USERPUT_ON
- _userPut = 1;
- break;
- case 0xE1: // SO_USERPUT_OFF
- _userPut = 0;
- break;
- case 0xE2: // SO_USERPUT_SOFT_ON
- _userPut++;
- break;
- case 0xE3: // SO_USERPUT_SOFT_OFF
- _userPut--;
- break;
- case 0xE4: // SO_CURSOR_IMAGE Set cursor image
- {
- int idx = pop();
- int room, obj;
- obj = popRoomAndObj(&room);
- setCursorFromImg(obj, room, idx);
- }
- break;
- case 0xE5: // SO_CURSOR_HOTSPOT Set cursor hotspot
- a = pop();
- setCursorHotspot(pop(), a);
- break;
- case 0xE6: // SO_CURSOR_TRANSPARENT Set cursor transparent color
- setCursorTransparency(pop());
- break;
- case 0xE7: { // SO_CHARSET_SET
- int charset = pop();
- debugC(DEBUG_GENERAL, "Set userface charset to %d", charset);
-// loadCharset(charset);
- break;
- }
- case 0xE8: // SO_CHARSET_COLOR
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- break;
- case 0xE9: // SO_CURSOR_PUT
- {
- int y = pop();
- int x = pop();
-
- _system->warpMouse(x, y);
- }
- break;
- default:
- error("o8_cursorCommand: default case 0x%x", subOp);
- }
-
- VAR(VAR_CURSORSTATE) = _cursor.state;
- VAR(VAR_USERPUT) = _userPut;
-}
-
-void ScummEngine_v8::o8_resourceRoutines() {
- byte subOp = fetchScriptByte();
- int resid = pop();
-
- switch (subOp) {
- case 0x3C: // Dummy case
- break;
- case 0x3D: // SO_HEAP_LOAD_COSTUME Load costume to heap
- ensureResourceLoaded(rtCostume, resid);
- break;
- case 0x3E: // SO_HEAP_LOAD_OBJECT Load object to heap
- {
- int room = getObjectRoom(resid);
- loadFlObject(resid, room);
- }
- break;
- case 0x3F: // SO_HEAP_LOAD_ROOM Load room to heap
- ensureResourceLoaded(rtRoom, resid);
- break;
- case 0x40: // SO_HEAP_LOAD_SCRIPT Load script to heap
- ensureResourceLoaded(rtScript, resid);
- break;
- case 0x41: // SO_HEAP_LOAD_SOUND Load sound to heap
- ensureResourceLoaded(rtSound, resid);
- break;
-
- case 0x42: // SO_HEAP_LOCK_COSTUME Lock costume in heap
- res.lock(rtCostume, resid);
- break;
- case 0x43: // SO_HEAP_LOCK_ROOM Lock room in heap
- res.lock(rtRoom, resid);
- break;
- case 0x44: // SO_HEAP_LOCK_SCRIPT Lock script in heap
- res.lock(rtScript, resid);
- break;
- case 0x45: // SO_HEAP_LOCK_SOUND Lock sound in heap
- res.lock(rtSound, resid);
- break;
- case 0x46: // SO_HEAP_UNLOCK_COSTUME Unlock costume
- res.unlock(rtCostume, resid);
- break;
- case 0x47: // SO_HEAP_UNLOCK_ROOM Unlock room
- res.unlock(rtRoom, resid);
- break;
- case 0x48: // SO_HEAP_UNLOCK_SCRIPT Unlock script
- res.unlock(rtScript, resid);
- break;
- case 0x49: // SO_HEAP_UNLOCK_SOUND Unlock sound
- res.unlock(rtSound, resid);
- break;
- case 0x4A: // SO_HEAP_NUKE_COSTUME Remove costume from heap
- res.setResourceCounter(rtCostume, resid, 0x7F);
- break;
- case 0x4B: // SO_HEAP_NUKE_ROOM Remove room from heap
- res.setResourceCounter(rtRoom, resid, 0x7F);
- break;
- case 0x4C: // SO_HEAP_NUKE_SCRIPT Remove script from heap
- res.setResourceCounter(rtScript, resid, 0x7F);
- break;
- case 0x4D: // SO_HEAP_NUKE_SOUND Remove sound from heap
- res.setResourceCounter(rtSound, resid, 0x7F);
- break;
- default:
- error("o8_resourceRoutines: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_roomOps() {
- byte subOp = fetchScriptByte();
- int a, b, c, d, e;
-
- switch (subOp) {
- case 0x52: // SO_ROOM_PALETTE Set room palette
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- setPalColor(d, a, b, c);
- break;
- case 0x55: // SO_ROOM_INTENSITY Set room intensity
- // Not used in CMI???
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, a, a, b, c);
- break;
- case 0x57: // SO_ROOM_FADE Fade room
- a = pop();
- if (a) {
- _switchRoomEffect = (byte)(a);
- _switchRoomEffect2 = (byte)(a >> 8);
- } else {
- fadeIn(_newEffect);
- }
- break;
- case 0x58: // SO_ROOM_RGB_INTENSITY Set room color intensity
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- darkenPalette(a, b, c, d, e);
- break;
- case 0x59: // SO_ROOM_TRANSFORM Transform room
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- palManipulateInit(a, b, c, d);
- break;
- case 0x5A: // SO_ROOM_CYCLE_SPEED Set palette cycling speed
- case 0x5B: // SO_ROOM_COPY_PALETTE Copy palette
- error("o8_roomOps: unimplemented case %d", subOp);
- break;
- case 0x5C: // SO_ROOM_NEW_PALETTE New palette
- a = pop();
- setPalette(a);
- break;
- case 0x5D: // SO_ROOM_SAVE_GAME Save game
- _saveTemporaryState = true;
- _saveLoadSlot = 1;
- _saveLoadFlag = 1;
- break;
- case 0x5E: // SO_ROOM_LOAD_GAME Load game
- _saveTemporaryState = true;
- _saveLoadSlot = 1;
- _saveLoadFlag = 2;
- break;
- case 0x5F: // SO_ROOM_SATURATION Set saturation of room colors
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- desaturatePalette(a, b, c, d, e);
- break;
- default:
- error("o8_roomOps: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_actorOps() {
- byte subOp = fetchScriptByte();
- Actor *a;
- int i, j;
-
- if (subOp == 0x7A) {
- _curActor = pop();
- //printf("Setting current actor to %d\n", _curActor);
- return;
- }
-
- a = derefActorSafe(_curActor, "o8_actorOps");
- if (!a)
- return;
-
- switch (subOp) {
- case 0x64: // SO_ACTOR_COSTUME Set actor costume
- a->setActorCostume(pop());
- break;
- case 0x65: // SO_ACTOR_STEP_DIST Set actor width of steps
- j = pop();
- i = pop();
- a->setActorWalkSpeed(i, j);
- break;
- case 0x67: // SO_ACTOR_ANIMATION_DEFAULT Set actor animation to default
- a->_initFrame = 1;
- a->_walkFrame = 2;
- a->_standFrame = 3;
- a->_talkStartFrame = 4;
- a->_talkStopFrame = 5;
- break;
- case 0x68: // SO_ACTOR_ANIMATION_INIT Initialize animation
- a->_initFrame = pop();
- break;
- case 0x69: // SO_ACTOR_ANIMATION_TALK Set actor animation to talk animation
- a->_talkStopFrame = pop();
- a->_talkStartFrame = pop();
- break;
- case 0x6A: // SO_ACTOR_ANIMATION_WALK Set actor animation to walk animation
- a->_walkFrame = pop();
- break;
- case 0x6B: // SO_ACTOR_ANIMATION_STAND Set actor animation to standing animation
- a->_standFrame = pop();
- break;
- case 0x6C: // SO_ACTOR_ANIMATION_SPEED Set speed of animation
- a->setAnimSpeed(pop());
- break;
- case 0x6D: // SO_ACTOR_DEFAULT
- a->initActor(0);
- break;
- case 0x6E: // SO_ACTOR_ELEVATION
- a->setElevation(pop());
- break;
- case 0x6F: // SO_ACTOR_PALETTE Set actor palette
- j = pop();
- i = pop();
- checkRange(31, 0, i, "Illegal palette slot %d");
- a->setPalette(i, j);
- break;
- case 0x70: // SO_ACTOR_TALK_COLOR Set actor talk color
- a->_talkColor = pop();
- break;
- case 0x71: // SO_ACTOR_NAME Set name of actor
- loadPtrToResource(rtActorName, a->_number, NULL);
- break;
- case 0x72: // SO_ACTOR_WIDTH Set width of actor
- a->_width = pop();
- break;
- case 0x73: // SO_ACTOR_SCALE Set scaling of actor
- i = pop();
- a->setScale(i, i);
- break;
- case 0x74: // SO_ACTOR_NEVER_ZCLIP
- a->_forceClip = 0;
- break;
- case 0x75: // SO_ACTOR_ALWAYS_ZCLIP
- a->_forceClip = pop();
- // V8 uses 255 where we used to use 100
- if (a->_forceClip == 255)
- a->_forceClip = 100;
- break;
- case 0x76: // SO_ACTOR_IGNORE_BOXES Make actor ignore boxes
- a->_ignoreBoxes = true;
- a->_forceClip = 100;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 0x77: // SO_ACTOR_FOLLOW_BOXES Make actor follow boxes
- a->_ignoreBoxes = false;
- a->_forceClip = 100;
- if (a->isInCurrentRoom())
- a->putActor(a->_pos.x, a->_pos.y, a->_room);
- break;
- case 0x78: // SO_ACTOR_SPECIAL_DRAW
- a->_shadowMode = pop();
- break;
- case 0x79: // SO_ACTOR_TEXT_OFFSET Set text offset relative to actor
- a->_talkPosY = pop();
- a->_talkPosX = pop();
- break;
-// case 0x7A: // SO_ACTOR_INIT Set current actor (handled above)
- case 0x7B: // SO_ACTOR_VARIABLE Set actor variable
- i = pop();
- a->setAnimVar(pop(), i);
- break;
- case 0x7C: // SO_ACTOR_IGNORE_TURNS_ON Make actor ignore turns
- a->_ignoreTurns = true;
- break;
- case 0x7D: // SO_ACTOR_IGNORE_TURNS_OFF Make actor follow turns
- a->_ignoreTurns = false;
- break;
- case 0x7E: // SO_ACTOR_NEW New actor
- a->initActor(2);
- break;
- case 0x7F: // SO_ACTOR_DEPTH Set actor Z position
- a->_layer = pop();
- break;
- case 0x80: // SO_ACTOR_STOP
- a->stopActorMoving();
- a->startAnimActor(a->_standFrame);
- break;
- case 0x81: // SO_ACTOR_FACE Make actor face angle
- a->_moving &= ~MF_TURN;
- a->setDirection(pop());
- break;
- case 0x82: // SO_ACTOR_TURN Turn actor
- a->turnToDirection(pop());
- break;
- case 0x83: // SO_ACTOR_WALK_SCRIPT Set walk script for actor?
- a->_walkScript = pop();
- break;
- case 0x84: // SO_ACTOR_TALK_SCRIPT Set talk script for actor?
- a->_talkScript = pop();
- break;
- case 0x85: // SO_ACTOR_WALK_PAUSE
- a->_moving |= MF_FROZEN;
- break;
- case 0x86: // SO_ACTOR_WALK_RESUME
- a->_moving &= ~MF_FROZEN;
- break;
- case 0x87: // SO_ACTOR_VOLUME Set volume of actor speech
- a->_talkVolume = pop();
- break;
- case 0x88: // SO_ACTOR_FREQUENCY Set frequency of actor speech
- a->_talkFrequency = pop();
- break;
- case 0x89: // SO_ACTOR_PAN
- a->_talkPan = pop();
- break;
- default:
- error("o8_actorOps: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_cameraOps() {
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0x32: // SO_CAMERA_PAUSE
- //debug(0, "freezeCamera NYI");
- break;
- case 0x33: // SO_CAMERA_RESUME
- //debug(0, "unfreezeCamera NYI");
- break;
- default:
- error("o8_cameraOps: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_verbOps() {
- byte subOp = fetchScriptByte();
- VerbSlot *vs = NULL;
- int slot, a, b;
-
- if (subOp == 0x96) {
- _curVerb = pop();
- _curVerbSlot = getVerbSlot(_curVerb, 0);
- checkRange(_numVerbs - 1, 0, _curVerbSlot, "Illegal new verb slot %d");
- //printf("Setting current actor to %d\n", _curActor);
- return;
- }
-
- assert(0 <= _curVerbSlot && _curVerbSlot < _numVerbs);
- vs = &_verbs[_curVerbSlot];
- assert(vs);
-
- switch (subOp) {
- case 0x96: // SO_VERB_INIT Choose verb number for editing
- // handled above!
- break;
- case 0x97: // SO_VERB_NEW New verb
- if (_curVerbSlot == 0) {
- for (slot = 1; slot < _numVerbs; slot++) {
- if (_verbs[slot].verbid == 0)
- break;
- }
- if (slot >= _numVerbs) {
- error("Too many verbs");
- }
- _curVerbSlot = slot;
- }
- vs = &_verbs[_curVerbSlot];
- vs->verbid = _curVerb;
- vs->color = 2;
- vs->hicolor = 0;
- vs->dimcolor = 8;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 0;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
- break;
- case 0x98: // SO_VERB_DELETE Delete verb
- killVerb(_curVerbSlot);
- break;
- case 0x99: // SO_VERB_NAME Set verb name
- loadPtrToResource(rtVerb, _curVerbSlot, NULL);
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 0x9A: // SO_VERB_AT Set verb (X,Y) placement
- vs->curRect.top = pop();
- vs->curRect.left = pop();
- break;
- case 0x9B: // SO_VERB_ON Turn verb on
- vs->curmode = 1;
- break;
- case 0x9C: // SO_VERB_OFF Turn verb off
- vs->curmode = 0;
- break;
- case 0x9D: // SO_VERB_COLOR Set verb color
- vs->color = pop();
- break;
- case 0x9E: // SO_VERB_HICOLOR Set verb highlighted color
- vs->hicolor = pop();
- break;
- case 0xA0: // SO_VERB_DIMCOLOR Set verb dimmed (disabled) color
- vs->dimcolor = pop();
- break;
- case 0xA1: // SO_VERB_DIM
- vs->curmode = 2;
- break;
- case 0xA2: // SO_VERB_KEY Set keypress to associate with verb
- vs->key = pop();
- break;
- case 0xA3: // SO_VERB_IMAGE Set verb image
- b = pop();
- a = pop();
- if (_curVerbSlot && a != vs->imgindex) {
- setVerbObject(b, a, _curVerbSlot);
- vs->type = kImageVerbType;
- vs->imgindex = a;
- }
- break;
- case 0xA4: // SO_VERB_NAME_STR Set verb name
- a = pop();
- if (a == 0) {
- loadPtrToResource(rtVerb, _curVerbSlot, (const byte *)"");
- } else {
- loadPtrToResource(rtVerb, _curVerbSlot, getStringAddress(a));
- }
- vs->type = kTextVerbType;
- vs->imgindex = 0;
- break;
- case 0xA5: // SO_VERB_CENTER Center verb
- vs->center = 1;
- break;
- case 0xA6: // SO_VERB_CHARSET Choose charset for verb
- vs->charset_nr = pop();
- break;
- case 0xA7: // SO_VERB_LINE_SPACING Choose linespacing for verb
- // FIXME - TODO
- // Note: it seems that var596 stores the "line spacing". It is used by various
- // scripts that place verbs for that.
- // Also, var595 contains the vertical position at which to start placing verbs (330)
- a = pop();
- debug(0, "SO_VERB_LINE_SPACING %d: not yet implemented", a);
- break;
- default:
- error("o8_verbops: default case 0x%x", subOp);
- }
-}
-
-void ScummEngine_v8::o8_systemOps() {
- byte subOp = fetchScriptByte();
- switch (subOp) {
- case 0x28: // SO_SYSTEM_RESTART Restart game
- restart();
- break;
- case 0x29: // SO_SYSTEM_QUIT Quit game
- shutDown();
- break;
- default:
- error("o8_systemOps: invalid case 0x%x", subOp);
- }
-}
-
-
-void ScummEngine_v8::o8_startVideo() {
- int len = resStrLen(_scriptPointer);
-
- SmushPlayer *sp = new SmushPlayer(this, 12);
- sp->play((const char*)_scriptPointer);
- delete sp;
-
- _scriptPointer += len + 1;
-}
-
-void ScummEngine_v8::o8_kernelSetFunctions() {
- // TODO
- Actor *a;
- int args[30];
- int len = getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 11: { // lockObject
- int objidx = getObjectIndex(args[1]);
- assert(objidx != -1);
- res.lock(rtFlObject, _objs[objidx].fl_object_index);
- break;
- }
- case 12: { // unlockObject
- int objidx = getObjectIndex(args[1]);
- assert(objidx != -1);
- res.unlock(rtFlObject, _objs[objidx].fl_object_index);
- break;
- }
- case 13: // remapCostume
- a = derefActor(args[1], "o8_kernelSetFunctions:remapCostume");
- a->remapActorPalette(args[2], args[3], args[4], -1);
- break;
- case 14: // remapCostumeInsert
- a = derefActor(args[1], "o8_kernelSetFunctions:remapCostumeInsert");
- a->remapActorPalette(args[2], args[3], args[4], args[5]);
- break;
- case 15: // setVideoFrameRate
- // not used anymore (was smush frame rate)
- break;
- case 20: // setBoxScaleSlot
- setBoxScaleSlot(args[1], args[2]);
- break;
- case 21: // setScaleSlot
- setScaleSlot(args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
- break;
- case 22: // setBannerColors
-// debug(0, "o8_kernelSetFunctions: setBannerColors(%d, %d, %d, %d)", args[1], args[2], args[3], args[4]);
- break;
- case 23: // setActorChoreLimbFrame
- a = derefActor(args[1], "o8_kernelSetFunctions:setActorChoreLimbFrame");
-
- a->startAnimActor(args[2]);
- a->animateLimb(args[3], args[4]);
- break;
- case 24: // clearTextQueue
- removeBlastTexts();
- break;
- case 25: { // saveGameReadName
- char *address = (char*)getStringAddress(args[2]);
- char name[30];
-
- if (!address) {
- error("o8_kernelSetFunctions: saveGameReadName failed finding slot string %d", args[2]);
- break;
- }
- getSavegameName(args[1] - 1, name);
- if (strlen(name) > 0 && strlen(name) < 30)
- strcpy(address, name);
- break;
- }
- case 26: { // saveGame?
- //char *address = (char*)getStringAddress(args[2]);
- char address[30];
- debug(0, "o8_kernelSetFunctions: saveGame?(%d, %s)", args[1], address);
- break;
- }
- case 27: { // FIXME: This doesn't work
- // saveGameRead
- _saveLoadSlot = args[1];
- _saveLoadFlag = 2;
- _saveTemporaryState = false;
- debug(0, "Sgl: %d", args[1]);
- break;
- }
- case 28: // saveGameStampScreenshot
- debug(0, "o8_kernelSetFunctions: saveGameStampScreenshot(%d, %d, %d, %d, %d, %d)", args[1], args[2], args[3], args[4], args[5], args[6]);
- break;
- case 29: // setKeyScript
- _keyScriptKey = args[1];
- _keyScriptNo = args[2];
- break;
- case 30: // killAllScriptsButMe
- killAllScriptsExceptCurrent();
- break;
- case 31: // stopAllVideo
- debug(0, "o8_kernelSetFunctions: stopAllVideo()");
- break;
- case 32: // writeRegistryValue
- {
- int idx = args[1];
- int value = args[2];
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, idx);
-
- debugC(DEBUG_GENERAL,"o8_kernelSetFunctions: writeRegistryValue(%s, %d)", (char *)ah->data, value);
- }
- break;
- case 33: // paletteSetIntensity
- debug(0, "o8_kernelSetFunctions: paletteSetIntensity(%d, %d)", args[1], args[2]);
- break;
- case 34: // queryQuit
- if (_confirmExit)
- confirmExitDialog();
- else
- _quit = true;
- break;
- case 108: // buildPaletteShadow
- setupShadowPalette(args[1], args[2], args[3], args[4], args[5], args[6]);
- break;
- case 109: // setPaletteShadow
- setupShadowPalette(0, args[1], args[2], args[3], args[4], args[5]);
- break;
- case 118: // blastShadowObject
- enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 3);
- break;
- case 119: // superBlastObject
- enqueueObject(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], 0);
- break;
-
- default:
- error("o8_kernelSetFunctions: default case 0x%x (len = %d)", args[0], len);
- }
-}
-
-void ScummEngine_v8::o8_kernelGetFunctions() {
- int args[30];
- int len = getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 0x73: // getWalkBoxAt
- push(getSpecialBox(args[1], args[2]));
- break;
- case 0x74: // isPointInBox
- push(checkXYInBoxBounds(args[3], args[1], args[2]));
- break;
- case 0xD3: // getKeyState
- push(getKeyState(args[1]));
- break;
- case 0xCE: // getRGBSlot
- push(remapPaletteColor(args[1], args[2], args[3], -1));
- break;
- case 0xD7: // getBox
- push(checkXYInBoxBounds(args[3], args[1], args[2]));
- break;
- case 0xD8: { // findBlastObject
- int x = args[1] + (camera._cur.x & 7);
- int y = args[2] + _screenTop;
- BlastObject *eo;
-
- for (int i = _blastObjectQueuePos - 1; i >= 0; i--) {
- eo = &_blastObjectQueue[i];
-
- if (eo->rect.contains(x, y) && !getClass(eo->number, kObjectClassUntouchable)) {
- push(eo->number);
- return;
- }
- }
- push(0);
- break;
- }
- case 0xD9: { // actorHit - used, for example, to detect ship collision
- // during ship-to-ship combat.
- Actor *a = derefActor(args[1], "actorHit");
- push(a->actorHitTest(args[2], args[3] + _screenTop));
- break;
- }
- case 0xDA: // lipSyncWidth
- push(_imuseDigital->getCurVoiceLipSyncWidth());
- break;
- case 0xDB: // lipSyncHeight
- push(_imuseDigital->getCurVoiceLipSyncHeight());
- break;
- case 0xDC: // actorTalkAnimation
- {
- Actor *a = derefActor(args[1], "actorTalkAnimation");
- push(a->_talkStartFrame);
- }
- break;
- case 0xDD: // getGroupSfxVol
- push(_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2);
- break;
- case 0xDE: // getGroupVoiceVol
- push(_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2);
- break;
- case 0xDF: // getGroupMusicVol
- push(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2);
- break;
- case 0xE0: // readRegistryValue
- {
- int idx = args[1];
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, idx);
- if (!strcmp((char *)ah->data, "SFX Volume"))
- push(ConfMan.getInt("sfx_volume") / 2);
- else if (!strcmp((char *)ah->data, "Voice Volume"))
- push(ConfMan.getInt("speech_volume") / 2);
- else if (!strcmp((char *)ah->data, "Music Volume"))
- push(ConfMan.getInt("music_volume") / 2);
- else if (!strcmp((char *)ah->data, "Text Status"))
- push(ConfMan.getBool("subtitles"));
- else if (!strcmp((char *)ah->data, "Object Names"))
- push(ConfMan.getBool("object_labels"));
- else if (!strcmp((char *)ah->data, "Saveload Page"))
- push(14);
- else // Use defaults
- push(-1);
- debugC(DEBUG_GENERAL,"o8_kernelGetFunctions: readRegistryValue(%s)", (char *)ah->data);
- }
- break;
- case 0xE1: // imGetMusicPosition
- push(_imuseDigital->getCurMusicPosInMs());
- break;
- case 0xE2: // musicLipSyncWidth
- push(_imuseDigital->getCurMusicLipSyncWidth(args[1]));
- break;
- case 0xE3: // musicLipSyncHeight
- push(_imuseDigital->getCurMusicLipSyncHeight(args[1]));
- break;
- default:
- error("o8_kernelGetFunctions: default case 0x%x (len = %d)", args[0], len);
- }
-
-}
-
-void ScummEngine_v8::o8_getActorChore() {
- int actnum = pop();
- Actor *a = derefActor(actnum, "o8_getActorChore");
- push(a->_frame);
-}
-
-void ScummEngine_v8::o8_getActorZPlane() {
- int actnum = pop();
- Actor *a = derefActor(actnum, "o8_getActorZPlane");
-
- int z = a->_forceClip;
- if (z == 100) {
- z = getMaskFromBox(a->_walkbox);
- if (z > gdi._numZBuffer - 1)
- z = gdi._numZBuffer - 1;
- }
-
- push(z);
-}
-
-
-void ScummEngine_v8::o8_getObjectImageX() {
- int i = getObjectIndex(pop());
- assert(i);
- push(_objs[i].x_pos);
-}
-
-void ScummEngine_v8::o8_getObjectImageY() {
- int i = getObjectIndex(pop());
- assert(i);
- push(_objs[i].y_pos);
-}
-
-void ScummEngine_v8::o8_getObjectImageWidth() {
- int i = getObjectIndex(pop());
- assert(i);
- push(_objs[i].width);
-}
-
-void ScummEngine_v8::o8_getObjectImageHeight() {
- int i = getObjectIndex(pop());
- assert(i);
- push(_objs[i].height);
-}
-
-void ScummEngine_v8::o8_getStringWidth() {
- int charset = pop();
- int oldID = _charset->getCurID();
- int width;
- const byte *msg = _scriptPointer;
- byte transBuf[512];
-
- // Skip to the next instruction
- _scriptPointer += resStrLen(_scriptPointer) + 1;
-
- translateText(msg, transBuf);
- msg = transBuf;
-
- // Temporary set the specified charset id
- _charset->setCurID(_string[charset].charset);
- // Determine the strings width
- width = _charset->getStringWidth(0, msg);
- // Revert to old font
- _charset->setCurID(oldID);
-
- push(width);
-}
-
-void ScummEngine_v8::o8_drawObject() {
- int state = pop();
- int y = pop();
- int x = pop();
- int obj = pop();
- setObjectState(obj, state, x, y);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v80he.cpp b/scumm/script_v80he.cpp
deleted file mode 100644
index 307ab75d3f..0000000000
--- a/scumm/script_v80he.cpp
+++ /dev/null
@@ -1,811 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-file.h"
-#include "common/config-manager.h"
-#include "common/str.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v80he, x)
-
-void ScummEngine_v80he::setupOpcodes() {
- static const OpcodeEntryV80he opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o72_pushDWord),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o72_getScriptString),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o72_isAnyOf),
- /* 1C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 20 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 24 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 28 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 2C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 30 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 34 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 38 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o6_invalid),
- OPCODE(o80_createSound),
- OPCODE(o80_getFileSize),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o80_stringToInt),
- OPCODE(o80_getSoundVar),
- OPCODE(o80_localizeArrayToRoom),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o80_sourceDebug),
- OPCODE(o80_readConfigFile),
- OPCODE(o80_writeConfigFile),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o72_resetCutscene),
- OPCODE(o6_invalid),
- OPCODE(o72_findObjectWithClassOf),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o72_getObjectImageX),
- OPCODE(o72_getObjectImageY),
- OPCODE(o72_captureWizImage),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o72_getTimer),
- OPCODE(o72_setTimer),
- OPCODE(o72_getSoundPosition),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o72_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o72_startObject),
- OPCODE(o72_drawObject),
- OPCODE(o72_printWizImage),
- OPCODE(o72_getArrayDimSize),
- /* 64 */
- OPCODE(o72_getNumFreeArrays),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_invalid),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o80_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o80_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o70_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_invalid),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o70_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o70_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o6_invalid),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_invalid),
- OPCODE(o70_resourceRoutines),
- /* 9C */
- OPCODE(o72_roomOps),
- OPCODE(o72_actorOps),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o72_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o72_arrayOps),
- OPCODE(o6_invalid),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o60_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o6_getActorAnimCounter1),
- /* AC */
- OPCODE(o80_drawWizPolygon),
- OPCODE(o6_isAnyOf),
- OPCODE(o72_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o72_talkActor),
- OPCODE(o72_talkEgo),
- /* BC */
- OPCODE(o72_dimArray),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o72_dim2dimArray),
- OPCODE(o72_traceStatus),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o72_kernelGetFunctions),
- OPCODE(o70_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o72_drawWizImage),
- OPCODE(o72_debugInput),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o72_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o60_closeFile),
- OPCODE(o72_openFile),
- OPCODE(o72_readFile),
- /* DC */
- OPCODE(o72_writeFile),
- OPCODE(o72_findAllObjects),
- OPCODE(o72_deleteFile),
- OPCODE(o72_rename),
- /* E0 */
- OPCODE(o80_drawLine),
- OPCODE(o72_getPixel),
- OPCODE(o60_localizeArrayToScript),
- OPCODE(o80_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o70_seekFilePos),
- OPCODE(o72_redimArray),
- OPCODE(o60_readFilePos),
- /* EC */
- OPCODE(o70_copyString),
- OPCODE(o70_getStringWidth),
- OPCODE(o70_getStringLen),
- OPCODE(o70_appendString),
- /* F0 */
- OPCODE(o70_concatString),
- OPCODE(o70_compareString),
- OPCODE(o70_isResourceLoaded),
- OPCODE(o72_readINI),
- /* F4 */
- OPCODE(o72_writeINI),
- OPCODE(o70_getStringLenForWidth),
- OPCODE(o70_getCharIndexInString),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o72_getResourceSize),
- OPCODE(o72_setFilePath),
- OPCODE(o72_setWindowCaption),
- OPCODE(o70_polygonOps),
- /* FC */
- OPCODE(o70_polygonHit),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV80he = opcodes;
-}
-
-void ScummEngine_v80he::executeOpcode(byte i) {
- OpcodeProcV80he op = _opcodesV80he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v80he::getOpcodeDesc(byte i) {
- return _opcodesV80he[i].desc;
-}
-
-void ScummEngine_v80he::o80_createSound() {
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 27:
- createSound(_heSndResId, pop());
- break;
- case 217:
- createSound(_heSndResId, -1);
- break;
- case 232:
- _heSndResId = pop();
- break;
- case 255:
- // dummy case
- break;
- default:
- error("o80_createSound: default case %d", subOp);
- }
-}
-
-void ScummEngine_v80he::o80_getFileSize() {
- byte filename[256];
-
- copyScriptString(filename, sizeof(filename));
-
- Common::File f;
- if (!f.open((char *)filename)) {
- push(-1);
- } else {
- push(f.size());
- f.close();
- }
-}
-
-void ScummEngine_v80he::o80_stringToInt() {
- int id, len, val;
- byte *addr;
- char string[100];
-
- id = pop();
-
- addr = getStringAddress(id);
- if (!addr)
- error("o80_stringToInt: Reference to zeroed array pointer (%d)", id);
-
- len = resStrLen(getStringAddress(id)) + 1;
- memcpy(string, addr, len);
- val = atoi(string);
- push(val);
-}
-
-void ScummEngine_v80he::o80_getSoundVar() {
- int var = pop();
- int snd = pop();
- push(_sound->getSoundVar(snd, var));
-}
-
-void ScummEngine_v80he::o80_localizeArrayToRoom() {
- int slot = pop();
- localizeArray(slot, 0xFF);
-}
-
-void ScummEngine_v80he::o80_sourceDebug() {
- fetchScriptDWord();
- fetchScriptDWord();
-}
-
-void ScummEngine_v80he::o80_readConfigFile() {
- byte option[128], section[128], filename[256];
- ArrayHeader *ah;
- Common::String entry;
- int len;
-
- copyScriptString(option, sizeof(option));
- copyScriptString(section, sizeof(section));
- copyScriptString(filename, sizeof(filename));
- convertFilePath(filename, true);
-
- Common::ConfigFile ConfFile;
- ConfFile.loadFromFile((const char *)filename);
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 43: // HE 100
- case 6: // number
- ConfFile.getKey((const char *)option, (const char *)section, entry);
-
- push(atoi(entry.c_str()));
- break;
- case 77: // HE 100
- case 7: // string
- ConfFile.getKey((const char *)option, (const char *)section, entry);
-
- writeVar(0, 0);
- len = resStrLen((const byte *)entry.c_str());
- ah = defineArray(0, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, entry.c_str(), len);
- push(readVar(0));
- break;
- default:
- error("o80_readConfigFile: default type %d", subOp);
- }
-
- debug(1, "o80_readConfigFile: Filename %s Section %s Option %s Value %s", filename, section, option, entry.c_str());
-}
-
-void ScummEngine_v80he::o80_writeConfigFile() {
- byte filename[256], section[256], option[256], string[1024];
- int value;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 43: // HE 100
- case 6: // number
- value = pop();
- sprintf((char *)string, "%d", value);
- copyScriptString(option, sizeof(option));
- copyScriptString(section, sizeof(section));
- copyScriptString(filename, sizeof(filename));
- convertFilePath(filename, true);
- break;
- case 77: // HE 100
- case 7: // string
- copyScriptString(string, sizeof(string));
- copyScriptString(option, sizeof(option));
- copyScriptString(section, sizeof(section));
- copyScriptString(filename, sizeof(filename));
- convertFilePath(filename, true);
- break;
- default:
- error("o80_writeConfigFile: default type %d", subOp);
- }
-
- Common::ConfigFile ConfFile;
- ConfFile.loadFromFile((const char *)filename);
- ConfFile.setKey((char *)option, (char *)section, (char *)string);
- ConfFile.saveToFile((const char *)filename);
- debug(1,"o80_writeConfigFile: Filename %s Section %s Option %s String %s", filename, section, option, string);
-}
-
-void ScummEngine_v80he::o80_cursorCommand() {
- int a, i;
- int args[16];
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 0x13:
- case 0x14:
- a = pop();
- _wiz->loadWizCursor(a);
- break;
- case 0x3C:
- pop();
- a = pop();
- _wiz->loadWizCursor(a);
- break;
- case 0x90: // SO_CURSOR_ON Turn cursor on
- _cursor.state = 1;
- break;
- case 0x91: // SO_CURSOR_OFF Turn cursor off
- _cursor.state = 0;
- break;
- case 0x92: // SO_USERPUT_ON
- _userPut = 1;
- break;
- case 0x93: // SO_USERPUT_OFF
- _userPut = 0;
- break;
- case 0x94: // SO_CURSOR_SOFT_ON Turn soft cursor on
- _cursor.state++;
- if (_cursor.state > 1)
- error("Cursor state greater than 1 in script");
- break;
- case 0x95: // SO_CURSOR_SOFT_OFF Turn soft cursor off
- _cursor.state--;
- break;
- case 0x96: // SO_USERPUT_SOFT_ON
- _userPut++;
- break;
- case 0x97: // SO_USERPUT_SOFT_OFF
- _userPut--;
- break;
- case 0x9C: // SO_CHARSET_SET
- initCharset(pop());
- break;
- case 0x9D: // SO_CHARSET_COLOR
- getStackList(args, ARRAYSIZE(args));
- for (i = 0; i < 16; i++)
- _charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
- break;
- default:
- error("o80_cursorCommand: default case %x", subOp);
- }
-
- VAR(VAR_CURSORSTATE) = _cursor.state;
- VAR(VAR_USERPUT) = _userPut;
-}
-
-void ScummEngine_v80he::o80_setState() {
- int state = pop();
- int obj = pop();
-
- state &= 0x7FFF;
- putState(obj, state);
- removeObjectFromDrawQue(obj);
-}
-
-void ScummEngine_v80he::o80_drawWizPolygon() {
- WizImage wi;
- wi.x1 = wi.y1 = pop();
- wi.resNum = pop();
- wi.state = 0;
- wi.flags = kWIFIsPolygon;
- _wiz->displayWizImage(&wi);
-}
-
-/**
- * Draw a 'line' between two points.
- *
- * @param x1 the starting x coordinate
- * @param y1 the starting y coordinate
- * @param x the ending x coordinate
- * @param y the ending y coordinate
- * @param step the step size used to render the line, only ever 'step'th point is drawn
- * @param type the line type -- points are rendered by drawing actors (type == 2),
- * wiz images (type == 3), or pixels (any other type)
- * @param id the id of an actor, wizimage or color (low bit) & flag (high bit)
- */
-void ScummEngine_v80he::drawLine(int x1, int y1, int x, int y, int step, int type, int id) {
- if (step < 0) {
- step = -step;
- }
- if (step == 0) {
- step = 1;
- }
-
- const int dx = x - x1;
- const int dy = y - y1;
-
- const int absDX = ABS(dx);
- const int absDY = ABS(dy);
-
- const int maxDist = MAX(absDX, absDY);
-
- y = y1;
- x = x1;
-
-
- if (type == 2) {
- Actor *a = derefActor(id, "drawLine");
- a->drawActorToBackBuf(x, y);
- } else if (type == 3) {
- WizImage wi;
- wi.flags = 0;
- wi.y1 = y;
- wi.x1 = x;
- wi.resNum = id;
- wi.state = 0;
- _wiz->displayWizImage(&wi);
- } else {
- drawPixel(x, y, id);
- }
-
- int stepCount = 0;
- int tmpX = 0;
- int tmpY = 0;
- for (int i = 0; i <= maxDist; i++) {
- tmpX += absDX;
- tmpY += absDY;
-
- int drawFlag = 0;
-
- if (tmpX > maxDist) {
- drawFlag = 1;
- tmpX -= maxDist;
-
- if (dx >= 0) {
- x++;
- } else {
- x--;
- }
- }
- if (tmpY > maxDist) {
- drawFlag = dy;
- tmpY -= maxDist;
-
- if (dy >= 0) {
- y++;
- } else {
- y--;
- }
- }
-
- if (drawFlag == 0)
- continue;
-
- if ((stepCount++ % step) != 0 && maxDist != i)
- continue;
-
- if (type == 2) {
- Actor *a = derefActor(id, "drawLine");
- a->drawActorToBackBuf(x, y);
- } else if (type == 3) {
- WizImage wi;
- wi.flags = 0;
- wi.y1 = y;
- wi.x1 = x;
- wi.resNum = id;
- wi.state = 0;
- _wiz->displayWizImage(&wi);
- } else {
- drawPixel(x, y, id);
- }
- }
-}
-
-void ScummEngine_v80he::drawPixel(int x, int y, int flags) {
- byte *src, *dst;
- VirtScreen *vs;
-
- if (x < 0 || x > 639)
- return;
-
- if (y < 0)
- return;
-
- if ((vs = findVirtScreen(y)) == NULL)
- return;
-
- markRectAsDirty(vs->number, x, y, x, y + 1);
-
- if ((flags & 0x4000) || (flags & 0x2000000)) {
- src = vs->getPixels(x, y);
- dst = vs->getBackPixels(x, y);
- *dst = *src;
- } else if ((flags & 0x2000) || (flags & 4000000)) {
- src = vs->getBackPixels(x, y);
- dst = vs->getPixels(x, y);
- *dst = *src;
- } else if (flags & 0x8000000) {
- error("drawPixel: unsupported flag 0x%x", flags);
- } else {
- dst = vs->getPixels(x, y);
- *dst = flags;
- if ((flags & 0x8000) || (flags & 0x1000000)) {
- dst = vs->getBackPixels(x, y);
- *dst = flags;
- }
- }
-}
-
-void ScummEngine_v80he::o80_drawLine() {
- int id, step, x, y, x1, y1;
-
- step = pop();
- id = pop();
- y = pop();
- x = pop();
- y1 = pop();
- x1 = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 55:
- drawLine(x1, y1, x, y, step, 2, id);
- break;
- case 63:
- drawLine(x1, y1, x, y, step, 3, id);
- break;
- case 66:
- drawLine(x1, y1, x, y, step, 1, id);
- break;
- default:
- error("o80_drawLine: default case %d", subOp);
- }
-
-}
-
-void ScummEngine_v80he::o80_pickVarRandom() {
- int num;
- int args[100];
- int32 dim1end;
-
- num = getStackList(args, ARRAYSIZE(args));
- int value = fetchScriptWord();
-
- if (readVar(value) == 0) {
- defineArray(value, kDwordArray, 0, 0, 0, num);
- if (value & 0x8000)
- localizeArray(readVar(value), 0xFF);
- else if (value & 0x4000)
- localizeArray(readVar(value), _currentScript);
-
- if (num > 0) {
- int16 counter = 0;
- do {
- writeArray(value, 0, counter + 1, args[counter]);
- } while (++counter < num);
- }
-
- shuffleArray(value, 1, num);
- writeArray(value, 0, 0, 2);
- push(readArray(value, 0, 1));
- return;
- }
-
- num = readArray(value, 0, 0);
-
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(value));
- dim1end = FROM_LE_32(ah->dim1end);
-
- if (dim1end < num) {
- int32 var_2 = readArray(value, 0, num - 1);
- shuffleArray(value, 1, dim1end);
- num = 1;
- if (readArray(value, 0, 1) == var_2 && dim1end >= 3) {
- int32 tmp = readArray(value, 0, 2);
- writeArray(value, 0, num, tmp);
- writeArray(value, 0, 2, var_2);
- }
- }
-
- writeArray(value, 0, 0, num + 1);
- push(readArray(value, 0, num));
-}
-
-} // End of namespace Scumm
diff --git a/scumm/script_v90he.cpp b/scumm/script_v90he.cpp
deleted file mode 100644
index 0536506534..0000000000
--- a/scumm/script_v90he.cpp
+++ /dev/null
@@ -1,2636 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern_he.h"
-#include "scumm/logic_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/sprite_he.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-#define OPCODE(x) _OPCODE(ScummEngine_v90he, x)
-
-void ScummEngine_v90he::setupOpcodes() {
- static const OpcodeEntryV90he opcodes[256] = {
- /* 00 */
- OPCODE(o6_pushByte),
- OPCODE(o6_pushWord),
- OPCODE(o72_pushDWord),
- OPCODE(o6_pushWordVar),
- /* 04 */
- OPCODE(o72_getScriptString),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_wordArrayRead),
- /* 08 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o90_dup_n),
- OPCODE(o6_wordArrayIndexedRead),
- /* 0C */
- OPCODE(o6_dup),
- OPCODE(o6_not),
- OPCODE(o6_eq),
- OPCODE(o6_neq),
- /* 10 */
- OPCODE(o6_gt),
- OPCODE(o6_lt),
- OPCODE(o6_le),
- OPCODE(o6_ge),
- /* 14 */
- OPCODE(o6_add),
- OPCODE(o6_sub),
- OPCODE(o6_mul),
- OPCODE(o6_div),
- /* 18 */
- OPCODE(o6_land),
- OPCODE(o6_lor),
- OPCODE(o6_pop),
- OPCODE(o72_isAnyOf),
- /* 1C */
- OPCODE(o90_wizImageOps),
- OPCODE(o90_min),
- OPCODE(o90_max),
- OPCODE(o90_sin),
- /* 20 */
- OPCODE(o90_cos),
- OPCODE(o90_sqrt),
- OPCODE(o90_atan2),
- OPCODE(o90_getSegmentAngle),
- /* 24 */
- OPCODE(o90_getDistanceBetweenPoints),
- OPCODE(o90_getSpriteInfo),
- OPCODE(o90_setSpriteInfo),
- OPCODE(o90_getSpriteGroupInfo),
- /* 28 */
- OPCODE(o90_setSpriteGroupInfo),
- OPCODE(o90_getWizData),
- OPCODE(o90_getActorData),
- OPCODE(o90_startScriptUnk),
- /* 2C */
- OPCODE(o90_jumpToScriptUnk),
- OPCODE(o90_videoOps),
- OPCODE(o90_getVideoData),
- OPCODE(o90_floodFill),
- /* 30 */
- OPCODE(o90_mod),
- OPCODE(o90_shl),
- OPCODE(o90_shr),
- OPCODE(o90_xor),
- /* 34 */
- OPCODE(o90_findAllObjectsWithClassOf),
- OPCODE(o90_getPolygonOverlap),
- OPCODE(o90_cond),
- OPCODE(o90_dim2dim2Array),
- /* 38 */
- OPCODE(o90_redim2dimArray),
- OPCODE(o90_getLinesIntersectionPoint),
- OPCODE(o90_sortArray),
- OPCODE(o6_invalid),
- /* 3C */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* 40 */
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_writeWordVar),
- /* 44 */
- OPCODE(o90_getObjectData),
- OPCODE(o80_createSound),
- OPCODE(o80_getFileSize),
- OPCODE(o6_wordArrayWrite),
- /* 48 */
- OPCODE(o80_stringToInt),
- OPCODE(o80_getSoundVar),
- OPCODE(o80_localizeArrayToRoom),
- OPCODE(o6_wordArrayIndexedWrite),
- /* 4C */
- OPCODE(o80_sourceDebug),
- OPCODE(o80_readConfigFile),
- OPCODE(o80_writeConfigFile),
- OPCODE(o6_wordVarInc),
- /* 50 */
- OPCODE(o72_resetCutscene),
- OPCODE(o6_invalid),
- OPCODE(o72_findObjectWithClassOf),
- OPCODE(o6_wordArrayInc),
- /* 54 */
- OPCODE(o72_getObjectImageX),
- OPCODE(o72_getObjectImageY),
- OPCODE(o72_captureWizImage),
- OPCODE(o6_wordVarDec),
- /* 58 */
- OPCODE(o72_getTimer),
- OPCODE(o72_setTimer),
- OPCODE(o72_getSoundPosition),
- OPCODE(o6_wordArrayDec),
- /* 5C */
- OPCODE(o6_if),
- OPCODE(o6_ifNot),
- OPCODE(o72_startScript),
- OPCODE(o6_startScriptQuick),
- /* 60 */
- OPCODE(o72_startObject),
- OPCODE(o72_drawObject),
- OPCODE(o72_printWizImage),
- OPCODE(o72_getArrayDimSize),
- /* 64 */
- OPCODE(o72_getNumFreeArrays),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_endCutscene),
- /* 68 */
- OPCODE(o6_cutscene),
- OPCODE(o6_invalid),
- OPCODE(o6_freezeUnfreeze),
- OPCODE(o80_cursorCommand),
- /* 6C */
- OPCODE(o6_breakHere),
- OPCODE(o6_ifClassOfIs),
- OPCODE(o6_setClass),
- OPCODE(o6_getState),
- /* 70 */
- OPCODE(o80_setState),
- OPCODE(o6_setOwner),
- OPCODE(o6_getOwner),
- OPCODE(o6_jump),
- /* 74 */
- OPCODE(o70_startSound),
- OPCODE(o6_stopSound),
- OPCODE(o6_invalid),
- OPCODE(o6_stopObjectScript),
- /* 78 */
- OPCODE(o6_panCameraTo),
- OPCODE(o6_actorFollowCamera),
- OPCODE(o6_setCameraAt),
- OPCODE(o6_loadRoom),
- /* 7C */
- OPCODE(o6_stopScript),
- OPCODE(o6_walkActorToObj),
- OPCODE(o6_walkActorTo),
- OPCODE(o6_putActorAtXY),
- /* 80 */
- OPCODE(o6_putActorAtObject),
- OPCODE(o6_faceActor),
- OPCODE(o6_animateActor),
- OPCODE(o6_doSentence),
- /* 84 */
- OPCODE(o70_pickupObject),
- OPCODE(o6_loadRoomWithEgo),
- OPCODE(o6_invalid),
- OPCODE(o6_getRandomNumber),
- /* 88 */
- OPCODE(o6_getRandomNumberRange),
- OPCODE(o6_invalid),
- OPCODE(o6_getActorMoving),
- OPCODE(o6_isScriptRunning),
- /* 8C */
- OPCODE(o70_getActorRoom),
- OPCODE(o6_getObjectX),
- OPCODE(o6_getObjectY),
- OPCODE(o6_getObjectOldDir),
- /* 90 */
- OPCODE(o6_getActorWalkBox),
- OPCODE(o6_getActorCostume),
- OPCODE(o6_findInventory),
- OPCODE(o6_getInventoryCount),
- /* 94 */
- OPCODE(o90_getPaletteData),
- OPCODE(o6_beginOverride),
- OPCODE(o6_endOverride),
- OPCODE(o6_setObjectName),
- /* 98 */
- OPCODE(o6_isSoundRunning),
- OPCODE(o6_setBoxFlags),
- OPCODE(o6_invalid),
- OPCODE(o70_resourceRoutines),
- /* 9C */
- OPCODE(o72_roomOps),
- OPCODE(o72_actorOps),
- OPCODE(o90_paletteOps),
- OPCODE(o6_getActorFromXY),
- /* A0 */
- OPCODE(o72_findObject),
- OPCODE(o6_pseudoRoom),
- OPCODE(o6_getActorElevation),
- OPCODE(o6_getVerbEntrypoint),
- /* A4 */
- OPCODE(o72_arrayOps),
- OPCODE(o90_fontUnk),
- OPCODE(o6_drawBox),
- OPCODE(o6_pop),
- /* A8 */
- OPCODE(o6_getActorWidth),
- OPCODE(o60_wait),
- OPCODE(o6_getActorScaleX),
- OPCODE(o90_getActorAnimProgress),
- /* AC */
- OPCODE(o80_drawWizPolygon),
- OPCODE(o6_isAnyOf),
- OPCODE(o72_systemOps),
- OPCODE(o6_isActorInBox),
- /* B0 */
- OPCODE(o6_delay),
- OPCODE(o6_delaySeconds),
- OPCODE(o6_delayMinutes),
- OPCODE(o6_stopSentence),
- /* B4 */
- OPCODE(o6_printLine),
- OPCODE(o6_printText),
- OPCODE(o6_printDebug),
- OPCODE(o6_printSystem),
- /* B8 */
- OPCODE(o6_printActor),
- OPCODE(o6_printEgo),
- OPCODE(o72_talkActor),
- OPCODE(o72_talkEgo),
- /* BC */
- OPCODE(o72_dimArray),
- OPCODE(o6_stopObjectCode),
- OPCODE(o6_startObjectQuick),
- OPCODE(o6_startScriptQuick2),
- /* C0 */
- OPCODE(o72_dim2dimArray),
- OPCODE(o72_traceStatus),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* C4 */
- OPCODE(o6_abs),
- OPCODE(o6_distObjectObject),
- OPCODE(o6_distObjectPt),
- OPCODE(o6_distPtPt),
- /* C8 */
- OPCODE(o90_kernelGetFunctions),
- OPCODE(o90_kernelSetFunctions),
- OPCODE(o6_delayFrames),
- OPCODE(o6_pickOneOf),
- /* CC */
- OPCODE(o6_pickOneOfDefault),
- OPCODE(o6_stampObject),
- OPCODE(o72_drawWizImage),
- OPCODE(o72_debugInput),
- /* D0 */
- OPCODE(o6_getDateTime),
- OPCODE(o6_stopTalking),
- OPCODE(o6_getAnimateVariable),
- OPCODE(o6_invalid),
- /* D4 */
- OPCODE(o6_shuffle),
- OPCODE(o72_jumpToScript),
- OPCODE(o6_band),
- OPCODE(o6_bor),
- /* D8 */
- OPCODE(o6_isRoomScriptRunning),
- OPCODE(o60_closeFile),
- OPCODE(o72_openFile),
- OPCODE(o72_readFile),
- /* DC */
- OPCODE(o72_writeFile),
- OPCODE(o72_findAllObjects),
- OPCODE(o72_deleteFile),
- OPCODE(o72_rename),
- /* E0 */
- OPCODE(o80_drawLine),
- OPCODE(o72_getPixel),
- OPCODE(o60_localizeArrayToScript),
- OPCODE(o80_pickVarRandom),
- /* E4 */
- OPCODE(o6_setBoxSet),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- /* E8 */
- OPCODE(o6_invalid),
- OPCODE(o70_seekFilePos),
- OPCODE(o72_redimArray),
- OPCODE(o60_readFilePos),
- /* EC */
- OPCODE(o70_copyString),
- OPCODE(o70_getStringWidth),
- OPCODE(o70_getStringLen),
- OPCODE(o70_appendString),
- /* F0 */
- OPCODE(o70_concatString),
- OPCODE(o70_compareString),
- OPCODE(o70_isResourceLoaded),
- OPCODE(o72_readINI),
- /* F4 */
- OPCODE(o72_writeINI),
- OPCODE(o70_getStringLenForWidth),
- OPCODE(o70_getCharIndexInString),
- OPCODE(o6_invalid),
- /* F8 */
- OPCODE(o72_getResourceSize),
- OPCODE(o72_setFilePath),
- OPCODE(o72_setWindowCaption),
- OPCODE(o70_polygonOps),
- /* FC */
- OPCODE(o70_polygonHit),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- OPCODE(o6_invalid),
- };
-
- _opcodesV90he = opcodes;
-}
-
-void ScummEngine_v90he::executeOpcode(byte i) {
- OpcodeProcV90he op = _opcodesV90he[i].proc;
- (this->*op) ();
-}
-
-const char *ScummEngine_v90he::getOpcodeDesc(byte i) {
- return _opcodesV90he[i].desc;
-}
-
-void ScummEngine_v90he::o90_dup_n() {
- int num;
- int args[16];
-
- push(fetchScriptWord());
- num = getStackList(args, ARRAYSIZE(args));
-
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < num; j++)
- push(args[j]);
- }
-}
-
-void ScummEngine_v90he::o90_min() {
- int a = pop();
- int b = pop();
-
- if (b < a) {
- push(b);
- } else {
- push(a);
- }
-}
-
-void ScummEngine_v90he::o90_max() {
- int a = pop();
- int b = pop();
-
- if (b > a) {
- push(b);
- } else {
- push(a);
- }
-}
-
-void ScummEngine_v90he::o90_sin() {
- double a = pop() * PI / 180.;
- push((int)(sin(a) * 100000));
-}
-
-void ScummEngine_v90he::o90_cos() {
- double a = pop() * PI / 180.;
- push((int)(cos(a) * 100000));
-}
-
-void ScummEngine_v90he::o90_sqrt() {
- int i = pop();
- if (i < 2) {
- push(i);
- } else {
- push((int)sqrt((double)(i + 1)));
- }
-}
-
-void ScummEngine_v90he::o90_atan2() {
- int y = pop();
- int x = pop();
- int a = (int)(atan2((double)y, (double)x) * 180. / PI);
- if (a < 0) {
- a += 360;
- }
- push(a);
-}
-
-void ScummEngine_v90he::o90_getSegmentAngle() {
- int y1 = pop();
- int x1 = pop();
- int dy = y1 - pop();
- int dx = x1 - pop();
- int a = (int)(atan2((double)dy, (double)dx) * 180. / PI);
- if (a < 0) {
- a += 360;
- }
- push(a);
-}
-
-void ScummEngine_v90he::o90_getActorData() {
- Actor *a;
-
- int subOp = pop();
- int val = pop();
- int act = pop();
-
- a = derefActor(act, "o90_getActorData");
-
- switch (subOp) {
- case 1:
- push(a->isUserConditionSet(val));
- break;
- case 2:
- checkRange(15, 0, val, "Limb %d out of range");
- push(a->_cost.frame[val]);
- break;
- case 3:
- push(a->getAnimSpeed());
- break;
- case 4:
- push(a->_shadowMode);
- break;
- case 5:
- push(a->_layer);
- break;
- case 6:
- push(a->_hePaletteNum);
- break;
- default:
- error("o90_getActorData: Unknown actor property %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_startScriptUnk() {
- int args[25];
- int script, cycle;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- cycle = pop();
- script = pop();
- flags = fetchScriptByte();
- runScript(script, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args, cycle);
-}
-
-void ScummEngine_v90he::o90_jumpToScriptUnk() {
- int args[25];
- int script, cycle;
- byte flags;
-
- getStackList(args, ARRAYSIZE(args));
- cycle = pop();
- script = pop();
- flags = fetchScriptByte();
- stopObjectCode();
- runScript(script, (flags == 199 || flags == 200), (flags == 195 || flags == 200), args, cycle);
-}
-
-void ScummEngine_v90he::o90_videoOps() {
- // Uses Smacker video
- int status = fetchScriptByte();
- int subOp = status - 49;
-
- switch (subOp) {
- case 0:
- copyScriptString(_videoParams.filename, sizeof(_videoParams.filename));
- _videoParams.status = status;
- break;
- case 5:
- _videoParams.flags |= pop();
- break;
- case 8:
- memset(_videoParams.filename, 0, sizeof(_videoParams.filename));
- _videoParams.unk2 = pop();
- break;
- case 14:
- _videoParams.wizResNum = pop();
- if (_videoParams.wizResNum)
- _videoParams.flags |= 2;
- break;
- case 116:
- _videoParams.status = status;
- break;
- case 206:
- if (_videoParams.status == 49) {
- // Start video
- if (_videoParams.flags == 0)
- _videoParams.flags = 4;
-
- if (_videoParams.flags == 2) {
- // result = startVideo(_videoParams.filename, _videoParams.flags, _videoParams.wizResNum);
- // VAR(119) = result;
- } else {
- // result = startVideo(_videoParams.filename, _videoParams.flags);
- // VAR(119) = result;
- }
- } else if (_videoParams.status == 165) {
- // Stop video
- }
- break;
- default:
- error("o90_videoOps: unhandled case %d", subOp);
- }
-
- debug(1, "o90_videoOps stub (%d)", subOp);
-}
-
-void ScummEngine_v90he::o90_getVideoData() {
- // Uses Smacker video
- byte subOp = fetchScriptByte();
- subOp -= 32;
-
- switch (subOp) {
- case 0: // Get width
- pop();
- break;
- case 1: // Get height
- pop();
- break;
- case 4: // Get frame count
- pop();
- break;
- case 20: // Get current frame
- pop();
- break;
- case 31: // Get image number
- pop();
- break;
- case 107: // Get statistics
- pop();
- pop();
- break;
- default:
- error("o90_getVideoData: unhandled case %d", subOp);
- }
-
- push(-1);
- debug(1, "o90_getVideoData stub (%d)", subOp);
-}
-
-void ScummEngine_v90he::o90_wizImageOps() {
- int a, b;
-
- int subOp = fetchScriptByte();
- subOp -= 46;
-
- switch (subOp) {
- case -14: // HE99+
- _wizParams.processFlags |= kWPFUseDefImgWidth;
- _wizParams.resDefImgW = pop();
- break;
- case -13: // HE99+
- _wizParams.processFlags |= kWPFUseDefImgHeight;
- _wizParams.resDefImgH = pop();
- break;
- case 0:
- // Dummy case
- pop();
- break;
- case 1:
- _wizParams.box.bottom = pop();
- _wizParams.box.right = pop();
- _wizParams.box.top = pop();
- _wizParams.box.left = pop();
- break;
- case 2:
- _wizParams.processMode = 1;
- break;
- case 3:
- _wizParams.processFlags |= kWPFUseFile;
- _wizParams.processMode = 3;
- copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
- break;
- case 4:
- _wizParams.processFlags |= kWPFUseFile;
- _wizParams.processMode = 4;
- copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
- _wizParams.fileWriteMode = pop();
- break;
- case 5:
- _wizParams.processFlags |= kWPFClipBox | 0x100;
- _wizParams.processMode = 2;
- _wizParams.box.bottom = pop();
- _wizParams.box.right = pop();
- _wizParams.box.top = pop();
- _wizParams.box.left = pop();
- _wizParams.compType = pop();
- break;
- case 6:
- _wizParams.processFlags |= kWPFNewState;
- _wizParams.img.state = pop();
- break;
- case 7:
- _wizParams.processFlags |= kWPFRotate;
- _wizParams.angle = pop();
- break;
- case 8:
- _wizParams.processFlags |= kWPFNewFlags;
- _wizParams.img.flags |= pop();
- break;
- case 10:
- _wizParams.img.flags = pop();
- _wizParams.img.state = pop();
- _wizParams.img.y1 = pop();
- _wizParams.img.x1 = pop();
- _wizParams.img.resNum = pop();
- _wiz->displayWizImage(&_wizParams.img);
- break;
- case 11:
- _wizParams.img.resNum = pop();
- _wizParams.processMode = 0;
- _wizParams.processFlags = 0;
- _wizParams.remapNum = 0;
- _wizParams.img.flags = 0;
- _wizParams.field_184 = 0;
- _wizParams.field_180 = 0;
- _wizParams.spriteId = 0;
- _wizParams.spriteGroup = 0;
- break;
- case 16: // HE99+
- _wizParams.processFlags |= kWPFMaskImg;
- _wizParams.sourceImage = pop();
- break;
- case 19:
- case 108:
- _wizParams.processFlags |= kWPFSetPos;
- _wizParams.img.y1 = pop();
- _wizParams.img.x1 = pop();
- break;
- case 20:
- case 203: // HE98+
- b = pop();
- a = pop();
- _wizParams.processFlags |= kWPFRemapPalette;
- _wizParams.processMode = 6;
- if (_wizParams.remapNum == 0) {
- memset(_wizParams.remapIndex, 0, sizeof(_wizParams.remapIndex));
- } else {
- assert(_wizParams.remapNum < ARRAYSIZE(_wizParams.remapIndex));
- _wizParams.remapIndex[_wizParams.remapNum] = a;
- _wizParams.remapColor[a] = b;
- ++_wizParams.remapNum;
- }
- break;
- case 21:
- _wizParams.processFlags |= kWPFClipBox;
- _wizParams.box.bottom = pop();
- _wizParams.box.right = pop();
- _wizParams.box.top = pop();
- _wizParams.box.left = pop();
- break;
- case 40: // HE99+
- _wizParams.processFlags |= kWPFPaletteNum;
- _wizParams.img.palette = pop();
- break;
- case 46:
- _wizParams.processFlags |= kWPFScaled;
- _wizParams.scale = pop();
- break;
- case 52:
- _wizParams.processFlags |= kWPFShadow;
- _wizParams.img.shadow = pop();
- break;
- case 85: // HE99+
- _wizParams.processFlags |= 0x1000 | 0x100 | 0x2;
- _wizParams.processMode = 7;
- _wizParams.field_168 = pop();
- _wizParams.field_164 = pop();
- _wizParams.compType = pop();
- break;
- case 87: // HE99+
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 9;
- _wizParams.fillColor = pop();
- _wizParams.box2.bottom = pop();
- _wizParams.box2.right = pop();
- _wizParams.box2.top = pop();
- _wizParams.box2.left = pop();
- break;
- case 88: // HE99+
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 10;
- _wizParams.fillColor = pop();
- _wizParams.box2.bottom = pop();
- _wizParams.box2.right = pop();
- _wizParams.box2.top = pop();
- _wizParams.box2.left = pop();
- break;
- case 89: // HE99+
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 11;
- _wizParams.fillColor = pop();
- _wizParams.box2.top = _wizParams.box2.bottom = pop();
- _wizParams.box2.left = _wizParams.box2.right = pop();
- break;
- case 90: // HE99+
- _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
- _wizParams.processMode = 12;
- _wizParams.fillColor = pop();
- _wizParams.box2.top = _wizParams.box2.bottom = pop();
- _wizParams.box2.left = _wizParams.box2.right = pop();
- break;
- case 91: // HE99+
- _wizParams.processFlags |= kWPFDstResNum;
- _wizParams.dstResNum = pop();
- break;
- case 93: // HE99+
- _wizParams.processFlags |= 0x100000;
- _wizParams.field_180 = pop();
- _wizParams.field_184 = pop();
- break;
- case 95: // HE99+
- _wizParams.processMode = 13;
- break;
- case 96: // HE99+
- _wizParams.field_239D = pop();
- _wizParams.field_2399 = pop();
- _wizParams.field_23A5 = pop();
- _wizParams.field_23A1 = pop();
- copyScriptString(_wizParams.string2, sizeof(_wizParams.string2));
- _wizParams.processMode = 15;
- break;
- case 97: // HE99+
- _wizParams.processMode = 16;
- _wizParams.field_23AD = pop();
- _wizParams.field_23A9 = pop();
- copyScriptString(_wizParams.string1, sizeof(_wizParams.string1));
- break;
- case 143: // HE99+
- _wizParams.processMode = 17;
- _wizParams.field_23CD = pop();
- _wizParams.field_23C9 = pop();
- _wizParams.field_23C5 = pop();
- _wizParams.field_23C1 = pop();
- _wizParams.field_23BD = pop();
- _wizParams.field_23B9 = pop();
- _wizParams.field_23B5 = pop();
- _wizParams.field_23B1 = pop();
- break;
- case 150: // HE99+
- _wizParams.processMode = 14;
- break;
- case 171: // HE99+
- _wizParams.processMode = 8;
- break;
- case 200:
- _wizParams.processFlags |= kWPFNewFlags | kWPFSetPos | 2;
- _wizParams.img.flags |= kWIFIsPolygon;
- _wizParams.field_164 = _wizParams.img.y1 = _wizParams.img.x1 = pop();
- break;
- case 209:
- if (_wizParams.img.resNum)
- _wiz->processWizImage(&_wizParams);
- break;
- default:
- error("o90_wizImageOps: unhandled case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getDistanceBetweenPoints() {
- int x1, y1, z1, x2, y2, z2, dx, dy, dz, d;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 23: // HE100
- case 28:
- y2 = pop();
- x2 = pop();
- y1 = pop();
- x1 = pop();
- dx = x2 - x1;
- dy = y2 - y1;
- d = dx * dx + dy * dy;
- if (d < 2) {
- push(d);
- } else {
- push((int)sqrt((double)(d + 1)));
- }
- break;
- case 24: // HE100
- case 29:
- z2 = pop();
- y2 = pop();
- x2 = pop();
- z1 = pop();
- y1 = pop();
- x1 = pop();
- dx = x2 - x1;
- dy = y2 - y1;
- dz = z2 - z1;
- d = dx * dx + dy * dy + dz * dz;
- if (d < 2) {
- push(d);
- } else {
- push((int)sqrt((double)(d + 1)));
- }
- break;
- default:
- error("o90_getDistanceBetweenPoints: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getSpriteInfo() {
- int args[16];
- int spriteId, flags, groupId, type;
- int32 x, y;
-
- byte subOp = fetchScriptByte();
- subOp -= 30;
-
- switch (subOp) {
- case 0:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpritePosition(spriteId, x, y);
- push(x);
- } else {
- push(0);
- }
- break;
- case 1:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpritePosition(spriteId, x, y);
- push(y);
- } else {
- push(0);
- }
- break;
- case 2:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteImageDim(spriteId, x, y);
- push(x);
- } else {
- push(0);
- }
- break;
- case 3:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteImageDim(spriteId, x, y);
- push(y);
- } else {
- push(0);
- }
- break;
- case 4:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteDist(spriteId, x, y);
- push(x);
- } else {
- push(0);
- }
- break;
- case 5:
- spriteId = pop();
- if (spriteId) {
- _sprite->getSpriteDist(spriteId, x, y);
- push(y);
- } else {
- push(0);
- }
- break;
- case 6:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteImageStateCount(spriteId));
- else
- push(0);
- break;
- case 7:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteGroup(spriteId));
- else
- push(0);
- break;
- case 8:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteDisplayX(spriteId));
- else
- push(0);
- break;
- case 9:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteDisplayY(spriteId));
- else
- push(0);
- break;
- case 12:
- flags = pop();
- spriteId = pop();
- if (spriteId) {
- switch(flags) {
- case 0:
- push(_sprite->getSpriteFlagXFlipped(spriteId));
- break;
- case 1:
- push(_sprite->getSpriteFlagYFlipped(spriteId));
- break;
- case 2:
- push(_sprite->getSpriteFlagActive(spriteId));
- break;
- case 3:
- push(_sprite->getSpriteFlagDoubleBuffered(spriteId));
- break;
- case 4:
- push(_sprite->getSpriteFlagRemapPalette(spriteId));
- break;
- default:
- push(0);
- }
- } else {
- push(0);
- }
- break;
- case 13:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpritePriority(spriteId));
- else
- push(0);
- break;
- case 15:
- if (_heversion == 99) {
- flags = getStackList(args, ARRAYSIZE(args));
- type = pop();
- groupId = pop();
- y = pop();
- x = pop();
- push(_sprite->findSpriteWithClassOf(x, y, groupId, type, flags, args));
- } else if (_heversion == 98) {
- type = pop();
- groupId = pop();
- y = pop();
- x = pop();
- push(_sprite->findSpriteWithClassOf(x, y, groupId, type, 0, 0));
- } else {
- groupId = pop();
- y = pop();
- x = pop();
- push(_sprite->findSpriteWithClassOf(x, y, groupId, 0, 0, 0));
- }
- break;
- case 22:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteImageState(spriteId));
- else
- push(0);
- break;
- case 32:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteSourceImage(spriteId));
- else
- push(0);
- break;
- case 33:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteImage(spriteId));
- else
- push(0);
- break;
- case 38:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteFlagEraseType(spriteId));
- else
- push(1);
- break;
- case 52:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteFlagAutoAnim(spriteId));
- else
- push(0);
- break;
- case 56:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpritePalette(spriteId));
- else
- push(0);
- break;
- case 62:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteScale(spriteId));
- else
- push(0);
- break;
- case 67:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteAnimSpeed(spriteId));
- else
- push(1);
- break;
- case 68:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteShadow(spriteId));
- else
- push(0);
- break;
- case 94:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteFlagUpdateType(spriteId));
- else
- push(0);
- break;
- case 95:
- flags = getStackList(args, ARRAYSIZE(args));
- spriteId = pop();
- if (spriteId) {
- push(_sprite->getSpriteClass(spriteId, flags, args));
- } else {
- push(0);
- }
- break;
- case 109:
- flags = pop();
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteGeneralProperty(spriteId, flags));
- else
- push(0);
- break;
- case 110:
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteMaskImage(spriteId));
- else
- push(0);
- break;
- case 168:
- pop();
- spriteId = pop();
- if (spriteId)
- push(_sprite->getSpriteUserValue(spriteId));
- else
- push(0);
- break;
- default:
- error("o90_getSpriteInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_setSpriteInfo() {
- int args[16];
- int spriteId;
- int32 tmp[2];
- int n;
-
- byte subOp = fetchScriptByte();
- subOp -= 34;
-
- switch (subOp) {
- case 0:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++) {
- _sprite->getSpriteDist(spriteId, tmp[0], tmp[1]);
- _sprite->setSpriteDist(spriteId, args[0], tmp[1]);
- }
- break;
- case 1:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++) {
- _sprite->getSpriteDist(spriteId, tmp[0], tmp[1]);
- _sprite->setSpriteDist(spriteId, tmp[0], args[0]);
- }
- break;
- case 3:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteGroup(spriteId, args[0]);
- break;
- case 8:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- switch(args[1]) {
- case 0:
- _sprite->setSpriteFlagXFlipped(spriteId, args[0]);
- break;
- case 1:
- _sprite->setSpriteFlagYFlipped(spriteId, args[0]);
- break;
- case 2:
- _sprite->setSpriteFlagActive(spriteId, args[0]);
- break;
- case 3:
- _sprite->setSpriteFlagDoubleBuffered(spriteId, args[0]);
- break;
- case 4:
- _sprite->setSpriteFlagRemapPalette(spriteId, args[0]);
- break;
- default:
- break;
- }
- break;
- case 9:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpritePriority(spriteId, args[0]);
- break;
- case 10:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->moveSprite(spriteId, args[0], args[1]);
- break;
- case 18:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteImageState(spriteId, args[0]);
- break;
- case 19:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteAngle(spriteId, args[0]);
- break;
- case 23:
- if (_features & GF_HE_985 || _heversion >= 99) {
- _curMaxSpriteId = pop();
- _curSpriteId = pop();
-
- if (_curSpriteId > _curMaxSpriteId)
- SWAP(_curSpriteId, _curMaxSpriteId);
- } else {
- _curSpriteId = pop();
- _curMaxSpriteId = _curSpriteId; // to make all functions happy
- }
- break;
- case 28: // HE99+
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteSourceImage(spriteId, args[0]);
- break;
- case 29:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteImage(spriteId, args[0]);
- break;
- case 31:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpritePosition(spriteId, args[0], args[1]);
- break;
- case 34:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteFlagEraseType(spriteId, args[0]);
- break;
- case 43:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteDist(spriteId, args[0], args[1]);
- break;
- case 48:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteFlagAutoAnim(spriteId, args[0]);
- break;
- case 52: // HE 98+
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpritePalette(spriteId, args[0]);
- break;
- case 58: // HE 99+
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteScale(spriteId, args[0]);
- break;
- case 63: // HE 98+
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteAnimSpeed(spriteId, args[0]);
- break;
- case 64:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteShadow(spriteId, args[0]);
- break;
- case 90:
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteFlagUpdateType(spriteId, args[0]);
- break;
- case 91:
- n = getStackList(args, ARRAYSIZE(args));
- if (_curSpriteId != 0 && _curMaxSpriteId != 0 && n != 0) {
- int *p = &args[n - 1];
- do {
- int code = *p;
- if (code == 0) {
- for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
- _sprite->setSpriteResetClass(i);
- }
- } else if (code & 0x80) {
- for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
- _sprite->setSpriteSetClass(i, code & 0x7F, 1);
- }
- } else {
- for (int i = _curSpriteId; i <= _curMaxSpriteId; ++i) {
- _sprite->setSpriteSetClass(i, code & 0x7F, 0);
- }
- }
- --p;
- } while (--n);
- }
- break;
- case 105: // HE 99+
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteGeneralProperty(spriteId, args[0], args[1]);
- break;
- case 106: // HE 99+
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteMaskImage(spriteId, args[0]);
- break;
- case 124:
- _sprite->resetTables(true);
- break;
- case 164:
- args[1] = pop();
- args[0] = pop();
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->setSpriteUserValue(spriteId, args[0], args[1]);
- break;
- case 183:
- if (_curSpriteId > _curMaxSpriteId)
- break;
- spriteId = _curSpriteId;
- if (!spriteId)
- spriteId++;
-
- for (; spriteId <= _curMaxSpriteId; spriteId++)
- _sprite->resetSprite(spriteId);
- break;
- default:
- error("o90_setSpriteInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getSpriteGroupInfo() {
- int32 tx, ty;
- int spriteGroupId, type;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 8: // HE 99+
- spriteGroupId = pop();
- if (spriteGroupId)
- push(getGroupSpriteArray(spriteGroupId));
- else
- push(0);
- break;
- case 30:
- spriteGroupId = pop();
- if (spriteGroupId) {
- _sprite->getGroupPosition(spriteGroupId, tx, ty);
- push(tx);
- } else {
- push(0);
- }
- break;
- case 31:
- spriteGroupId = pop();
- if (spriteGroupId) {
- _sprite->getGroupPosition(spriteGroupId, tx, ty);
- push(ty);
- } else {
- push(0);
- }
- break;
- case 42: // HE 99+
- type = pop();
- spriteGroupId = pop();
- if (spriteGroupId) {
- switch(type) {
- case 0:
- push(_sprite->getGroupXMul(spriteGroupId));
- break;
- case 1:
- push(_sprite->getGroupXDiv(spriteGroupId));
- break;
- case 2:
- push(_sprite->getGroupYMul(spriteGroupId));
- break;
- case 3:
- push(_sprite->getGroupYDiv(spriteGroupId));
- break;
- default:
- push(0);
- }
- } else {
- push(0);
- }
- break;
- case 43:
- spriteGroupId = pop();
- if (spriteGroupId)
- push(_sprite->getGroupPriority(spriteGroupId));
- else
- push(0);
- break;
- case 63: // HE 99+
- spriteGroupId = pop();
- if (spriteGroupId)
- push(_sprite->getGroupDstResNum(spriteGroupId));
- else
- push(0);
- break;
- case 139: // HE 99+
- // dummy case
- pop();
- pop();
- push(0);
- break;
- default:
- error("o90_getSpriteGroupInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_setSpriteGroupInfo() {
- int type, value1, value2, value3, value4;
-
- byte subOp = fetchScriptByte();
- subOp -= 37;
-
- switch (subOp) {
- case 0:
- type = pop() - 1;
- switch (type) {
- case 0:
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->moveGroupMembers(_curSpriteGroupId, value1, value2);
- break;
- case 1:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersPriority(_curSpriteGroupId, value1);
- break;
- case 2:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersGroup(_curSpriteGroupId, value1);
- break;
- case 3:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersUpdateType(_curSpriteGroupId, value1);
- break;
- case 4:
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersResetSprite(_curSpriteGroupId);
- break;
- case 5:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersAnimationSpeed(_curSpriteGroupId, value1);
- break;
- case 6:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersAutoAnimFlag(_curSpriteGroupId, value1);
- break;
- case 7:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupMembersShadow(_curSpriteGroupId, value1);
- break;
- default:
- error("o90_setSpriteGroupInfo subOp 0: Unknown case %d", subOp);
- }
- break;
- case 5:
- type = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- switch (type) {
- case 0:
- _sprite->setGroupXMul(_curSpriteGroupId, value1);
- break;
- case 1:
- _sprite->setGroupXDiv(_curSpriteGroupId, value1);
- break;
- case 2:
- _sprite->setGroupYMul(_curSpriteGroupId, value1);
- break;
- case 3:
- _sprite->setGroupYDiv(_curSpriteGroupId, value1);
- break;
- default:
- error("o90_setSpriteGroupInfo subOp 5: Unknown case %d", subOp);
- }
- break;
- case 6:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupPriority(_curSpriteGroupId, value1);
- break;
- case 7:
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->moveGroup(_curSpriteGroupId, value1, value2);
- break;
- case 20:
- _curSpriteGroupId = pop();
- break;
- case 26:
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupImage(_curSpriteGroupId, value1);
- break;
- case 28:
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupPosition(_curSpriteGroupId, value1, value2);
- break;
- case 30:
- value4 = pop();
- value3 = pop();
- value2 = pop();
- value1 = pop();
- if (!_curSpriteGroupId)
- break;
-
- _sprite->setGroupBounds(_curSpriteGroupId, value1, value2, value3, value4);
- break;
- case 56:
- if (!_curSpriteGroupId)
- break;
-
- _sprite->resetGroupBounds(_curSpriteGroupId);
- break;
- case 180:
- if (!_curSpriteGroupId)
- break;
-
- _sprite->resetGroup(_curSpriteGroupId);
- break;
- default:
- error("o90_setSpriteGroupInfo: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getWizData() {
- byte filename[4096];
- int state, resId;
- int32 w, h;
- int32 x, y;
-
- byte subOp = fetchScriptByte();
- subOp -= 30;
-
- switch (subOp) {
- case 0:
- state = pop();
- resId = pop();
- _wiz->getWizImageSpot(resId, state, x, y);
- push(x);
- break;
- case 1:
- state = pop();
- resId = pop();
- _wiz->getWizImageSpot(resId, state, x, y);
- push(y);
- break;
- case 2:
- state = pop();
- resId = pop();
- _wiz->getWizImageDim(resId, state, w, h);
- push(w);
- break;
- case 3:
- state = pop();
- resId = pop();
- _wiz->getWizImageDim(resId, state, w, h);
- push(h);
- break;
- case 6:
- resId = pop();
- push(_wiz->getWizImageStates(resId));
- break;
- case 15:
- y = pop();
- x = pop();
- state = pop();
- resId = pop();
- push(_wiz->isWizPixelNonTransparent(resId, state, x, y, 0));
- break;
- case 36:
- y = pop();
- x = pop();
- state = pop();
- resId = pop();
- push(_wiz->getWizPixelColor(resId, state, x, y, 0));
- break;
- case 100:
- h = pop();
- w = pop();
- y = pop();
- x = pop();
- state = pop();
- resId = pop();
- if (x == -1 && y == -1 && w == -1 && h == -1) {
- _wiz->getWizImageDim(resId, state, w, h);
- x = 0;
- y = 0;
- }
- push(computeWizHistogram(resId, state, x, y, w, h));
- break;
- case 109:
- pop();
- pop();
- push(0);
- break;
- case 111:
- pop();
- copyScriptString(filename, sizeof(filename));
- pop();
- push(0);
- debug(0, "o90_getWizData() case 111 unhandled");
- break;
- default:
- error("o90_getWizData: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_floodFill() {
- byte subOp = fetchScriptByte();
- subOp -= 54;
-
- switch (subOp) {
- case 0:
- pop();
- break;
- case 3:
- memset(&_floodFillParams, 0, sizeof(_floodFillParams));
- _floodFillParams.box.left = 0;
- _floodFillParams.box.top = 0;
- _floodFillParams.box.right = 639;
- _floodFillParams.box.bottom = 479;
- break;
- case 11:
- _floodFillParams.y = pop();
- _floodFillParams.x = pop();
- break;
- case 12:
- _floodFillParams.flags = pop();
- break;
- case 13:
- _floodFillParams.box.bottom = pop();
- _floodFillParams.box.right = pop();
- _floodFillParams.box.top = pop();
- _floodFillParams.box.left = pop();
- break;
- case 201:
- floodFill(&_floodFillParams, this);
- break;
- default:
- error("o90_floodFill: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_shl() {
- int a = pop();
- push(pop() << a);
-}
-
-void ScummEngine_v90he::o90_shr() {
- int a = pop();
- push(pop() >> a);
-}
-
-void ScummEngine_v90he::o90_xor() {
- int a = pop();
- push(pop() ^ a);
-}
-
-void ScummEngine_v90he::o90_mod() {
- int a = pop();
- if (a == 0)
- error("modulus by zero");
- push(pop() % a);
-}
-
-void ScummEngine_v90he::o90_findAllObjectsWithClassOf() {
- int args[16];
- int cond, num, cls, tmp;
- bool b;
-
- num = getStackList(args, ARRAYSIZE(args));
- int room = pop();
- int numObjs = 0;
-
- if (room != _currentRoom)
- error("o90_findAllObjectsWithClassOf: current room is not %d", room);
-
- writeVar(0, 0);
- defineArray(0, kDwordArray, 0, 0, 0, _numLocalObjects);
- for (int i = 1; i < _numLocalObjects; i++) {
- cond = 1;
- tmp = num;
- while (--tmp >= 0) {
- cls = args[tmp];
- b = getClass(_objs[i].obj_nr, cls);
- if ((cls & 0x80 && !b) || (!(cls & 0x80) && b))
- cond = 0;
- }
-
- if (cond) {
- numObjs++;
- writeArray(0, 0, numObjs, _objs[i].obj_nr);
- }
- }
-
- writeArray(0, 0, 0, numObjs);
-
- push(readVar(0));
-}
-
-void ScummEngine_v90he::o90_getPolygonOverlap() {
- int args1[32];
- int args2[32];
-
- int n1 = getStackList(args1, ARRAYSIZE(args1));
- int n2 = getStackList(args2, ARRAYSIZE(args2));
-
- int subOp = pop();
-
- switch (subOp) {
- case 1:
- {
- Common::Rect r(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
- Common::Point p(args2[0], args2[1]);
- push(r.contains(p) ? 1 : 0);
- }
- break;
- case 2:
- {
- int dx = args2[0] - args1[0];
- int dy = args2[1] - args1[1];
- int dist = dx * dx + dy * dy;
- if (dist >= 2) {
- dist = (int)sqrt((double)(dist + 1));
- }
- if (_heversion >= 98) {
- push((dist <= args1[2]) ? 1 : 0);
- } else {
- push((dist > args1[2]) ? 1 : 0);
- }
- }
- break;
- case 3:
- {
- Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
- Common::Rect r2(args2[0], args2[1], args2[2] + 1, args2[3] + 1);
- push(r2.intersects(r1) ? 1 : 0);
- }
- break;
- case 4:
- {
- int dx = args2[0] - args1[0];
- int dy = args2[1] - args1[1];
- int dist = dx * dx + dy * dy;
- if (dist >= 2) {
- dist = (int)sqrt((double)(dist + 1));
- }
- push((dist < args1[2] && dist < args2[2]) ? 1 : 0);
- }
- break;
- case 5:
- {
- assert((n1 & 1) == 0);
- n1 /= 2;
- if (n1 == 0) {
- push(0);
- } else {
- WizPolygon wp;
- memset(&wp, 0, sizeof(wp));
- wp.numVerts = n1;
- assert(n1 < ARRAYSIZE(wp.vert));
- for (int i = 0; i < n1; ++i) {
- wp.vert[i].x = args1[i * 2 + 0];
- wp.vert[i].y = args1[i * 2 + 1];
- }
- push(_wiz->polygonContains(wp, args2[0], args2[1]) ? 1 : 0);
- }
- }
- break;
- // HE 98+
- case 6:
- {
- Common::Rect r1, r2;
- _sprite->getSpriteBounds(args2[0], false, r2);
- _sprite->getSpriteBounds(args1[0], false, r1);
- if (r2.isValidRect() == false) {
- push(0);
- break;
- }
-
- if (n2 == 3) {
- r2.left += args2[1];
- r2.right += args2[1];
- r2.top += args2[2];
- r2.bottom += args2[2];
- }
- if (n1 == 3) {
- r1.left += args1[1];
- r1.right += args1[1];
- r1.top += args1[2];
- r1.bottom += args1[2];
- }
- push(r2.intersects(r1) ? 1 : 0);
- }
- break;
- case 7:
- {
- Common::Rect r2;
- _sprite->getSpriteBounds(args2[0], false, r2);
- Common::Rect r1(args1[0], args1[1], args1[2], args1[3]);
- if (r2.isValidRect() == false) {
- push(0);
- break;
- }
-
- if (n2 == 3) {
- r2.left += args2[1];
- r2.right += args2[1];
- r2.top += args2[2];
- r2.bottom += args2[2];
- }
- push(r2.intersects(r1) ? 1 : 0);
- }
- break;
- case 8:
- case 10: // TODO: Draw sprites to buffer and compare.
- {
- Common::Rect r1, r2;
- _sprite->getSpriteBounds(args2[0], true, r2);
- _sprite->getSpriteBounds(args1[0], true, r1);
- if (r2.isValidRect() == false) {
- push(0);
- break;
- }
-
- if (n2 == 3) {
- r2.left += args2[1];
- r2.right += args2[1];
- r2.top += args2[2];
- r2.bottom += args2[2];
- }
- if (n1 == 3) {
- r1.left += args1[1];
- r1.right += args1[1];
- r1.top += args1[2];
- r1.bottom += args1[2];
- }
- push(r2.intersects(r1) ? 1 : 0);
- }
- break;
- case 9:
- {
- Common::Rect r2;
- _sprite->getSpriteBounds(args2[0], true, r2);
- Common::Rect r1(args1[0], args1[1], args1[2], args1[3]);
- if (r2.isValidRect() == false) {
- push(0);
- break;
- }
-
- if (n2 == 3) {
- r2.left += args2[1];
- r2.right += args2[1];
- r2.top += args2[2];
- r2.bottom += args2[2];
- }
- push(r2.intersects(r1) ? 1 : 0);
- }
- break;
- default:
- error("o90_getPolygonOverlap: default case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_cond() {
- int a = pop();
- int b = pop();
- int c = pop();
-
- if (!c)
- b = a;
- push(b);
-}
-
-void ScummEngine_v90he::o90_dim2dim2Array() {
- int data, dim1start, dim1end, dim2start, dim2end;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 2: // SO_BIT_ARRAY
- data = kBitArray;
- break;
- case 3: // SO_NIBBLE_ARRAY
- data = kNibbleArray;
- break;
- case 4: // SO_BYTE_ARRAY
- data = kByteArray;
- break;
- case 5: // SO_INT_ARRAY
- data = kIntArray;
- break;
- case 6:
- data = kDwordArray;
- break;
- case 7: // SO_STRING_ARRAY
- data = kStringArray;
- break;
- default:
- error("o90_dim2dim2Array: default case %d", subOp);
- }
-
- if (pop() == 2) {
- dim1end = pop();
- dim1start = pop();
- dim2end = pop();
- dim2start = pop();
- } else {
- dim2end = pop();
- dim2start = pop();
- dim1end = pop();
- dim1start = pop();
- }
-
- defineArray(fetchScriptWord(), data, dim2start, dim2end, dim1start, dim1end);
-}
-
-void ScummEngine_v90he::o90_redim2dimArray() {
- int a, b, c, d;
- d = pop();
- c = pop();
- b = pop();
- a = pop();
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 4:
- redimArray(fetchScriptWord(), a, b, c, d, kByteArray);
- break;
- case 5:
- redimArray(fetchScriptWord(), a, b, c, d, kIntArray);
- break;
- case 6:
- redimArray(fetchScriptWord(), a, b, c, d, kDwordArray);
- break;
- default:
- error("o90_redim2dimArray: default type %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getLinesIntersectionPoint() {
- int var_ix = fetchScriptWord();
- int var_iy = fetchScriptWord();
- int line2_y2 = pop();
- int line2_x2 = pop();
- int line2_y1 = pop();
- int line2_x1 = pop();
- int line1_y2 = pop();
- int line1_x2 = pop();
- int line1_y1 = pop();
- int line1_x1 = pop();
-
- int result = 0;
- int ix = 0;
- int iy = 0;
-
- bool isLine1Point = (line1_x1 == line1_x2 && line1_y1 == line1_y2);
- bool isLine2Point = (line2_x1 == line2_x2 && line2_y1 == line2_y2);
-
- if (isLine1Point) {
- if (isLine2Point) {
- if (line1_x1 == line2_x1 && line1_y1 == line2_y2) {
- ix = line1_x1;
- iy = line2_x1;
- result = 1;
- }
- } else {
- // 1 point and 1 line
- int dx2 = line2_x2 - line2_x1;
- if (dx2 != 0) {
- int dy2 = line2_y2 - line2_y1;
- float y = (float)dy2 / dx2 * (line1_x1 - line2_x1) + line2_y1 + .5f;
- if (line1_y1 == (int)y) {
- ix = line1_x1;
- iy = line1_y1;
- result = 1;
- }
- } else {
- // vertical line
- if (line1_x1 == line2_x1) {
- if (line2_y1 > line2_y2) {
- if (line1_y1 >= line2_y2 && line1_y1 <= line2_y1) {
- ix = line1_x1;
- iy = line1_y1;
- result = 1;
- }
- } else {
- if (line1_y1 >= line2_y1 && line1_y1 <= line2_y2) {
- ix = line1_x1;
- iy = line1_y1;
- result = 1;
- }
- }
- }
- }
- }
- } else {
- if (isLine2Point) {
- // 1 point and 1 line
- int dx1 = line1_x2 - line1_x1;
- if (dx1 != 0) {
- int dy1 = line1_y2 - line1_y1;
- float y = (float)dy1 / dx1 * (line2_x1 - line1_x1) + line1_y1 + .5f;
- if (line2_y1 == (int)y) {
- ix = line2_x1;
- iy = line2_y1;
- result = 1;
- }
- } else {
- // vertical line
- if (line2_x1 == line1_x1) {
- if (line1_y1 > line1_y2) {
- if (line2_y1 >= line1_y2 && line2_y1 <= line1_y1) {
- ix = line2_x1;
- iy = line2_y1;
- result = 1;
- }
- } else {
- if (line2_y1 >= line1_y1 && line2_y1 <= line1_y2) {
- ix = line2_x2;
- iy = line2_y1;
- result = 1;
- }
- }
- }
- }
- } else {
- // 2 lines
- int dy1 = line1_y2 - line1_y1;
- int dx1 = line1_x2 - line1_x1;
- int dy2 = line2_y2 - line2_y1;
- int dx2 = line2_x2 - line2_x1;
- int det = dx1 * dy2 - dx2 * dy1;
- int cross_p1 = dx1 * (line1_y1 - line2_y1) - dy1 * (line1_x1 - line2_x1);
- int cross_p2 = dx2 * (line1_y1 - line2_y1) - dy2 * (line1_x1 - line2_x1);
- if (det == 0) {
- // parallel lines
- if (cross_p2 == 0) {
- ix = ABS(line2_x2 + line2_x1) / 2;
- iy = ABS(line2_y2 + line2_y1) / 2;
- result = 2;
- }
- } else {
- float rcp1 = (float)cross_p1 / det;
- float rcp2 = (float)cross_p2 / det;
- if (rcp1 >= 0 && rcp1 <= 1 && rcp2 >= 0 && rcp2 <= 1) {
- ix = (int)(dx1 * rcp2 + line1_x1 + .5f);
- iy = (int)(dy1 * rcp2 + line1_y1 + .5f);
- result = 1;
- }
- }
- }
- }
-
- writeVar(var_ix, ix);
- writeVar(var_iy, iy);
- push(result);
-}
-
-void ScummEngine_v90he::getArrayDim(int array, int *dim2start, int *dim2end, int *dim1start, int *dim1end) {
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- assert(ah);
- if (dim2start && *dim2start == -1) {
- *dim2start = ah->dim2start;
- }
- if (dim2end && *dim2end == -1) {
- *dim2end = ah->dim2end;
- }
- if (dim1start && *dim1start == -1) {
- *dim1start = ah->dim1start;
- }
- if (dim1end && *dim1end == -1) {
- *dim1end = ah->dim1end;
- }
-}
-
-static int sortArrayOffset;
-
-static int compareByteArray(const void *a, const void *b) {
- int va = *((const uint8 *)a + sortArrayOffset);
- int vb = *((const uint8 *)a + sortArrayOffset);
- return va - vb;
-}
-
-static int compareByteArrayReverse(const void *a, const void *b) {
- int va = *((const uint8 *)a + sortArrayOffset);
- int vb = *((const uint8 *)a + sortArrayOffset);
- return vb - va;
-}
-
-static int compareIntArray(const void *a, const void *b) {
- int va = (int16)READ_LE_UINT16((const uint8 *)a + sortArrayOffset * 2);
- int vb = (int16)READ_LE_UINT16((const uint8 *)b + sortArrayOffset * 2);
- return va - vb;
-}
-
-static int compareIntArrayReverse(const void *a, const void *b) {
- int va = (int16)READ_LE_UINT16((const uint8 *)a + sortArrayOffset * 2);
- int vb = (int16)READ_LE_UINT16((const uint8 *)b + sortArrayOffset * 2);
- return vb - va;
-}
-
-static int compareDwordArray(const void *a, const void *b) {
- int va = (int32)READ_LE_UINT32((const uint8 *)a + sortArrayOffset * 4);
- int vb = (int32)READ_LE_UINT32((const uint8 *)b + sortArrayOffset * 4);
- return va - vb;
-}
-
-static int compareDwordArrayReverse(const void *a, const void *b) {
- int va = (int32)READ_LE_UINT32((const uint8 *)a + sortArrayOffset * 4);
- int vb = (int32)READ_LE_UINT32((const uint8 *)b + sortArrayOffset * 4);
- return vb - va;
-}
-
-void ScummEngine_v90he::sortArray(int array, int dim2start, int dim2end, int dim1start, int dim1end, int sortOrder) {
- debug(9, "sortArray(%d, [%d,%d,%d,%d], %d)", array, dim2start, dim2end, dim1start, dim1end, sortOrder);
-
- assert(dim1start == dim1end);
- checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
- ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
- assert(ah);
-
- const int num = dim2end - dim2start + 1;
- const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;
- const int offset = pitch * (dim2start - FROM_LE_32(ah->dim2start));
- sortArrayOffset = dim1start - FROM_LE_32(ah->dim1start);
-
- switch (FROM_LE_32(ah->type)) {
- case kByteArray:
- case kStringArray:
- if (sortOrder <= 0) {
- qsort(ah->data + offset, num, pitch, compareByteArray);
- } else {
- qsort(ah->data + offset, num, pitch, compareByteArrayReverse);
- }
- break;
- case kIntArray:
- if (sortOrder <= 0) {
- qsort(ah->data + offset * 2, num, pitch * 2, compareIntArray);
- } else {
- qsort(ah->data + offset * 2, num, pitch * 2, compareIntArrayReverse);
- }
- break;
- case kDwordArray:
- if (sortOrder <= 0) {
- qsort(ah->data + offset * 4, num, pitch * 4, compareDwordArray);
- } else {
- qsort(ah->data + offset * 4, num, pitch * 4, compareDwordArrayReverse);
- }
- break;
- default:
- error("Invalid array type", FROM_LE_32(ah->type));
- }
-}
-
-void ScummEngine_v90he::o90_sortArray() {
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 129:
- case 134: // HE100
- {
- int array = fetchScriptWord();
- int sortOrder = pop();
- int dim1end = pop();
- int dim1start = pop();
- int dim2end = pop();
- int dim2start = pop();
- getArrayDim(array, &dim2start, &dim2end, &dim1start, &dim1end);
- sortArray(array, dim2start, dim2end, dim1start, dim1end, sortOrder);
- }
- break;
- default:
- error("o90_sortArray: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getObjectData() {
- byte subOp = fetchScriptByte();
- subOp -= 32;
-
- switch (subOp) {
- case 0:
- if (_heObjectNum == -1)
- push(0);
- else
- push(_objs[_heObjectNum].width);
- break;
- case 1:
- if (_heObjectNum == -1)
- push(0);
- else
- push(_objs[_heObjectNum].height);
- break;
- case 4:
- push(getObjectImageCount(_heObject));
- break;
- case 6:
- if (_heObjectNum == -1)
- push(0);
- else
- push(_objs[_heObjectNum].x_pos);
- break;
- case 7:
- if (_heObjectNum == -1)
- push(0);
- else
- push(_objs[_heObjectNum].y_pos);
- break;
- case 20:
- push(getState(_heObject));
- break;
- case 25:
- _heObject = pop();
- _heObjectNum = getObjectIndex(_heObject);
- break;
- case 107:
- // Dummy case
- pop();
- push(0);
- break;
- default:
- error("o90_getObjectData: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_getPaletteData() {
- int b, c, d, e;
- int palSlot, color;
-
- byte subOp = fetchScriptByte();
- subOp -= 45;
-
- switch (subOp) {
- case 0:
- e = pop();
- d = pop();
- palSlot = pop();
- pop();
- c = pop();
- b = pop();
- push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
- break;
- case 7:
- c = pop();
- b = pop();
- palSlot = pop();
- push(getHEPaletteColorComponent(palSlot, b, c));
- break;
- case 21:
- color = pop();
- palSlot = pop();
- push(getHEPaletteColor(palSlot, color));
- break;
- case 87:
- c = pop();
- b = pop();
- push(getHEPaletteColorComponent(1, b, c));
- break;
- case 172:
- pop();
- c = pop();
- c = MAX(0, c);
- c = MIN(c, 255);
- b = pop();
- b = MAX(0, b);
- b = MIN(b, 255);
- push(getHEPaletteSimilarColor(1, b, c, 10, 245));
- break;
- default:
- error("o90_getPaletteData: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_paletteOps() {
- int a, b, c, d, e;
-
- byte subOp = fetchScriptByte();
- subOp -= 57;
-
- switch (subOp) {
- case 0:
- _hePaletteNum = pop();
- break;
- case 6:
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- setHEPaletteFromImage(_hePaletteNum, a, b);
- }
- break;
- case 9:
- e = pop();
- d = pop();
- c = pop();
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- for (; a <= b; ++a) {
- setHEPaletteColor(_hePaletteNum, a, c, d, e);
- }
- }
- break;
- case 13:
- c = pop();
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- for (; a <= b; ++a) {
- copyHEPaletteColor(_hePaletteNum, a, c);
- }
- }
- break;
- case 19: //HE99+
- a = pop();
- if (_hePaletteNum != 0) {
- setHEPaletteFromCostume(_hePaletteNum, a);
- }
- break;
- case 29:
- a = pop();
- if (_hePaletteNum != 0) {
- copyHEPalette(_hePaletteNum, a);
- }
- break;
- case 118:
- b = pop();
- a = pop();
- if (_hePaletteNum != 0) {
- setHEPaletteFromRoom(_hePaletteNum, a, b);
- }
- break;
- case 160:
- if (_hePaletteNum != 0) {
- restoreHEPalette(_hePaletteNum);
- }
- break;
- case 198:
- _hePaletteNum = 0;
- break;
- default:
- error("o90_paletteOps: Unknown case %d", subOp);
- }
-}
-
-void ScummEngine_v90he::o90_fontUnk() {
- // Font related
- byte string[80];
- int a;
-
- byte subOp = fetchScriptByte();
-
- switch (subOp) {
- case 60: // HE100
- case 42:
- a = pop();
- if (a == 2) {
- copyScriptString(string, sizeof(string));
- push(-1);
- } else if (a == 1) {
- pop();
- writeVar(0, 0);
- defineArray(0, kStringArray, 0, 0, 0, 0);
- writeArray(0, 0, 0, 0);
- push(readVar(0));
- }
- break;
- case 0: // HE100
- case 57:
- push(1);
- break;
- default:
- error("o90_fontUnk: Unknown case %d", subOp);
- }
-
- debug(1, "o90_fontUnk stub (%d)", subOp);
-}
-
-void ScummEngine_v90he::o90_getActorAnimProgress() {
- Actor *a = derefActor(pop(), "o90_getActorAnimProgress");
- push(a->getAnimProgress());
-}
-
-void ScummEngine_v90he::o90_kernelGetFunctions() {
- int args[29];
- int num, tmp;
- Actor *a;
-
- num = getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 1001:
- {
- double b = args[1] * PI / 180.;
- push((int)(sin(b) * 100000));
- }
- break;
- case 1002:
- {
- double b = args[1] * PI / 180.;
- push((int)(cos(b) * 100000));
- }
- break;
- case 1969:
- a = derefActor(args[1], "o90_kernelGetFunctions: 1969");
- tmp = a->_heCondMask;
- tmp &= 0x7FFF0000;
- push(tmp);
- break;
- case 2001:
- push(_logicHE->dispatch(args[1], num - 2, (int32 *)&args[2]));
- break;
- default:
- error("o90_kernelGetFunctions: default case %d", args[0]);
- }
-}
-
-void ScummEngine_v90he::o90_kernelSetFunctions() {
- int args[29];
- int num, tmp;
- Actor *a;
-
- num = getStackList(args, ARRAYSIZE(args));
-
- switch (args[0]) {
- case 20:
- a = derefActor(args[1], "o90_kernelSetFunctions: 20");
- queueAuxBlock(a);
- break;
- case 21:
- _skipDrawObject = 1;
- break;
- case 22:
- _skipDrawObject = 0;
- break;
- case 23:
- _charset->clearCharsetMask();
- _fullRedraw = true;
- break;
- case 24:
- _skipProcessActors = 1;
- redrawAllActors();
- break;
- case 25:
- _skipProcessActors = 0;
- redrawAllActors();
- break;
- case 27:
- // Used in readdemo
- break;
- case 42:
- _wiz->_rectOverrideEnabled = true;
- _wiz->_rectOverride.left = args[1];
- _wiz->_rectOverride.top = args[2];
- _wiz->_rectOverride.right = args[3];
- _wiz->_rectOverride.bottom = args[4];
- break;
- case 43:
- _wiz->_rectOverrideEnabled = false;
- break;
- case 714:
- debug(5, "o90_kernelSetFunctions: case 714: type %d resId %d unk1 %d", args[1], args[2], args[3]);
- break;
- case 1492:
- // Remote start script function
- break;
- case 1969:
- a = derefActor(args[1], "o90_kernelSetFunctions: 1969");
- tmp = a->_heCondMask;
- tmp ^= args[2];
- tmp &= 0x7FFF0000;
- a->_heCondMask ^= tmp;
- break;
- case 2001:
- _logicHE->dispatch(args[1], num - 2, (int32 *)&args[2]);
- break;
- default:
- error("o90_kernelSetFunctions: default case %d (param count %d)", args[0], num);
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/scumm-md5.h b/scumm/scumm-md5.h
deleted file mode 100644
index f442f38ba3..0000000000
--- a/scumm/scumm-md5.h
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- This file was generated by the md5table tool on Sat Feb 11 00:38:53 2006
- DO NOT EDIT MANUALLY!
- */
-
-struct MD5Table {
- const char *md5;
- const char *gameid;
- Common::Language language;
- Common::Platform platform;
-};
-
-static const MD5Table md5table[] = {
- { "0305e850382b812fec6e5998ef88a966", "pajama", Common::NL_NLD, Common::kPlatformWindows },
- { "035deab53b47bc43abc763560d0f8d4b", "atlantis", Common::EN_USA, Common::kPlatformPC },
- { "037385a953789190298494d92b89b3d0", "catalog", Common::EN_USA, Common::kPlatformWindows },
- { "0425954a9db5c340861672892c3e678d", "samnmax", Common::EN_USA, Common::kPlatformMacintosh },
- { "04401d747f1a2c1c4b388daff71ed378", "ft", Common::DE_DEU, Common::kPlatformMacintosh },
- { "04687cdf7f975a89d2474929f7b80946", "indy3", Common::EN_USA, Common::kPlatformFMTowns },
- { "0557df19f046a84c2fdc63507c6616cb", "farm", Common::NL_NLD, Common::kPlatformWindows },
- { "055ffe4f47753e47594ac67823220c54", "puttrace", Common::DE_DEU, Common::kPlatformUnknown },
- { "06b187468113f9ae5a400b148a847fac", "atlantis", Common::EN_USA, Common::kPlatformMacintosh },
- { "07433205acdca3bc553d0e731588b35f", "airport", Common::EN_USA, Common::kPlatformWindows },
- { "07b810e37be7489263f7bc7627d4765d", "freddi4", Common::RU_RUS, Common::kPlatformWindows },
- { "084ed0fa98a6d1e9368d67fe9cfbd417", "freddi", Common::EN_USA, Common::kPlatformWindows },
- { "0855496dde35356b1a9691e22ba84cdc", "freddi", Common::EN_USA, Common::kPlatformWindows },
- { "08656dd9698ddf1023ba9bf8a195e37b", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "08cc5c3eedaf72ebe12734eee94f7fa2", "balloon", Common::EN_USA, Common::kPlatformUnknown },
- { "09820417db26687bb7fe0c83cc4c553b", "ft", Common::EN_USA, Common::kPlatformUnknown },
- { "0a212fa35fa8421f31c1f3961272caf0", "monkey", Common::DE_DEU, Common::kPlatformAmiga },
- { "0a41311d462b6639fc45297b9044bf16", "monkey", Common::ES_ESP, Common::kPlatformAtariST },
- { "0ab19be9e2a3f6938226638b2a3744fe", "PuttTime", Common::EN_USA, Common::kPlatformUnknown },
- { "0ac41e2e3d2174e5a042a6b565328dba", "puttrace", Common::EN_USA, Common::kPlatformUnknown },
- { "0b3222aaa7efcf283eb621e0cefd26cc", "puttputt", Common::RU_RUS, Common::kPlatformPC },
- { "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", Common::DE_DEU, Common::kPlatformUnknown },
- { "0cccfa5223099a60e76cfcca57a1a141", "freddi3", Common::NL_NLD, Common::kPlatformWindows },
- { "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", Common::ES_ESP, Common::kPlatformPC },
- { "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", Common::EN_USA, Common::kPlatformPC },
- { "0e9b01430e31d9fcd94071d433bbc6bf", "loom", Common::FR_FRA, Common::kPlatformAtariST },
- { "0f5935bd5e88ba6f09e558d64459746d", "thinker1", Common::EN_USA, Common::kPlatformWindows },
- { "0f6f2e716ba896a44e5059bba1de7ca9", "samnmax", Common::IT_ITA, Common::kPlatformUnknown },
- { "0f9c7a76657f0840b8f7ccb5bffeb9f4", "indy3", Common::FR_FRA, Common::kPlatformAtariST },
- { "0fb73eddfcf584c02ba097984df131ba", "samnmax", Common::DE_DEU, Common::kPlatformUnknown },
- { "1005456bfe351c1b679e1ff2dc2849e9", "puttzoo", Common::UNK_LANG, Common::kPlatformWindows },
- { "114acdc2659a273c220f86ee9edb24c1", "maniac", Common::FR_FRA, Common::kPlatformPC },
- { "11ddf1fde76e3156eb3a38da213f484e", "monkey2", Common::IT_ITA, Common::kPlatformAmiga },
- { "11e6e244078ff09b0f3832e35420e0a7", "catalog", Common::EN_USA, Common::kPlatformWindows },
- { "132bff65e6367c09cc69318ce1b59333", "monkey2", Common::EN_USA, Common::kPlatformAmiga },
- { "145bd3373574feb668cc2eea2ec6cf86", "balloon", Common::RU_RUS, Common::kPlatformWindows },
- { "14d48c95b43ddeb983254cf6c43851f1", "freddi4", Common::NL_NLD, Common::kPlatformWindows },
- { "151071053a1d0021198216713939521d", "freddi2", Common::EN_USA, Common::kPlatformWindows },
- { "15240c59d3681ed53f714f8d925cb2d6", "maniac", Common::ES_ESP, Common::kPlatformAtariST },
- { "157367c3c21e0d03a0cba44361b4cf65", "indy3", Common::EN_USA, Common::kPlatformAtariST },
- { "15e03ffbfeddb9c2aebc13dcb2a4a8f4", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "15f588e887e857e8c56fe6ade4956168", "atlantis", Common::ES_ESP, Common::kPlatformAmiga },
- { "16542a7342a918bfe4ba512007d36c47", "FreddisFunShop", Common::EN_USA, Common::kPlatformUnknown },
- { "166553538ff320c69edafeee29525419", "samnmax", Common::EN_USA, Common::kPlatformMacintosh },
- { "16effd200aa6b8abe9c569c3e578814d", "freddi4", Common::NL_NLD, Common::kPlatformWindows },
- { "179879b6e35c1ead0d93aab26db0951b", "fbear", Common::EN_USA, Common::kPlatformWindows },
- { "17b5d5e6af4ae89d62631641d66d5a05", "indy3", Common::IT_ITA, Common::kPlatformPC },
- { "17f7296f63c78642724f057fd8e736a7", "maniac", Common::EN_USA, Common::kPlatformNES },
- { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", Common::FR_FRA, Common::kPlatformPC },
- { "182344899c2e2998fca0bebcd82aa81a", "atlantis", Common::EN_USA, Common::kPlatformPC },
- { "183d7464902d40d00800e8ee1f04117c", "maniac", Common::DE_DEU, Common::kPlatformPC },
- { "1875b90fade138c9253a8e967007031a", "indy3", Common::EN_USA, Common::kPlatformPC },
- { "187d315f6b5168f68680dfe8c3d76a3e", "loom", Common::HB_ISR, Common::kPlatformPC },
- { "1900e501a52fbf55bde6e4196f6d2aa6", "zak", Common::IT_ITA, Common::kPlatformPC },
- { "19263586f749a560c1adf8b3393a9593", "socks", Common::RU_RUS, Common::kPlatformWindows },
- { "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", Common::EN_USA, Common::kPlatformWindows },
- { "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", Common::EN_USA, Common::kPlatformMacintosh },
- { "1c792d28376d45e145cb916bca0400a2", "spyfox2", Common::NL_NLD, Common::kPlatformUnknown },
- { "1c7e7db2cfab1ad62746ab680a634204", "maniac", Common::FR_FRA, Common::kPlatformNES },
- { "1ca86e2cf9aaa2068738a1e5ba477e60", "zak", Common::JA_JPN, Common::kPlatformFMTowns },
- { "1d05cd189e4908f79b57e78a4402f292", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "1dd3c11ea4439adfe681e4e405b624e1", "monkey", Common::FR_FRA, Common::kPlatformPC },
- { "1dd7aa088e09f96d06818aa9a9deabe0", "indy3", Common::EN_USA, Common::kPlatformMacintosh },
- { "1fbebd7b2b692df5297870447a80cfed", "atlantis", Common::DE_DEU, Common::kPlatformPC },
- { "2012f854d83d9cc6f73b2b544cd8bbf8", "water", Common::RU_RUS, Common::kPlatformWindows },
- { "20da6fce37805423966aaa8f3c2426aa", "atlantis", Common::FR_FRA, Common::kPlatformAmiga },
- { "2108d83dcf09f8adb4bc524669c8cf51", "PuttTime", Common::EN_USA, Common::kPlatformUnknown },
- { "21a6592322f92550f144f68a8a4e685e", "dig", Common::FR_FRA, Common::kPlatformMacintosh },
- { "21abe302e1b1e2b66d6f5c12e241ebfd", "freddicove", Common::RU_RUS, Common::kPlatformWindows },
- { "2232b0b9411575b1f9961713ebc9de61", "balloon", Common::ES_ESP, Common::kPlatformWindows },
- { "225e18566e810c634bf7de63e7568e3e", "mustard", Common::EN_USA, Common::kPlatformUnknown },
- { "22c9eb04455440131ffc157aeb8d40a8", "fbear", Common::EN_USA, Common::kPlatformWindows },
- { "22d07d6c386c9c25aca5dac2a0c0d94b", "maniac", Common::SE_SWE, Common::kPlatformNES },
- { "22f4ea88a09da12df9308ba30bcb7d0f", "loom", Common::EN_USA, Common::kPlatformPC },
- { "257f8c14d8c584f7ddd601bcb00920c7", "maniac", Common::DE_DEU, Common::kPlatformNES },
- { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", Common::EN_USA, Common::kPlatformPC },
- { "27b3a4224ad63d5b04627595c1c1a025", "zak", Common::IT_ITA, Common::kPlatformAmiga },
- { "28d24a33448fab6795850bc9f159a4a2", "atlantis", Common::JA_JPN, Common::kPlatformFMTowns },
- { "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", Common::EN_USA, Common::kPlatformPC },
- { "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", Common::ES_ESP, Common::kPlatformPC },
- { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", Common::EN_USA, Common::kPlatformMacintosh },
- { "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", Common::DE_DEU, Common::kPlatformWindows },
- { "2ccd8891ce4d3f1a334d21bff6a88ca2", "monkey", Common::EN_USA, Common::kPlatformMacintosh },
- { "2d1e891fe52df707c30185e52c50cd92", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "2d388339d6050d8ccaa757b64633954e", "zak", Common::EN_USA, Common::kPlatformFMTowns },
- { "2d4536a56e01da4b02eb021e7770afa2", "zak", Common::EN_USA, Common::kPlatformFMTowns },
- { "2d9d46f23cb07bbc90b8ad464d3e4ff8", "atlantis", Common::EN_USA, Common::kPlatformMacintosh },
- { "2e85f7aa054930c692a5b1bed1dfc295", "football", Common::EN_USA, Common::kPlatformUnknown },
- { "2e8a1f76ea33bc5e04347646feee173d", "pajama3", Common::DE_DEU, Common::kPlatformUnknown },
- { "2fe369ad70f52a8cf7ad6077ee64f81a", "loom", Common::DE_DEU, Common::kPlatformAmiga },
- { "305d3dd57c96c65b017bc70c8c7cfb5e", "monkey", Common::DE_DEU, Common::kPlatformPC },
- { "30ba1e825d4ad2b448143ae8df18482a", "pajama2", Common::NL_NLD, Common::kPlatformUnknown },
- { "319a4dde52c7960b5aae8a1ec348d918", "monkey", Common::DE_DEU, Common::kPlatformAmiga },
- { "31aa57f460a3d12429f0552a46a90b39", "puttputt", Common::EN_USA, Common::kPlatformPC },
- { "31b8fda4c8c7413fa6b39997e776eba4", "loom", Common::JA_JPN, Common::kPlatformFMTowns },
- { "32709cbeeb3044b34129950860a83f14", "pajama2", Common::RU_RUS, Common::kPlatformWindows },
- { "32a433dea56b86a55b59e4ff7d755711", "ft", Common::EN_USA, Common::kPlatformPC },
- { "330f631502e381a4e199a3f7cb483c20", "indy3", Common::DE_DEU, Common::kPlatformAmiga },
- { "3433be9866ca4261b2d5d25374e3f243", "monkey", Common::FR_FRA, Common::kPlatformAmiga },
- { "3486ede0f904789267d4bcc5537a46d4", "puttzoo", Common::EN_USA, Common::kPlatformMacintosh },
- { "35a2d3040fa512f8232d9e443319d84d", "dig", Common::EN_USA, Common::kPlatformMacintosh },
- { "362c1d281fb9899254cda66ad246c66a", "dig", Common::EN_USA, Common::kPlatformUnknown },
- { "3686cf8f89e102ececf4366e1d2c8126", "monkey2", Common::EN_USA, Common::kPlatformPC },
- { "36a6750e03fb505fc19fc2bf3e4dbe91", "pajama2", Common::EN_USA, Common::kPlatformUnknown },
- { "37aed3f91c1ef959e0bd265f9b13781f", "pajama", Common::EN_USA, Common::kPlatformUnknown },
- { "37f56ceb13e401a7ac7d9e6b37fecaf7", "loom", Common::EN_USA, Common::kPlatformPC },
- { "37ff1b308999c4cca7319edfcc1280a0", "puttputt", Common::EN_USA, Common::kPlatformWindows },
- { "3824e60cdf639d22f6df92a03dc4b131", "fbear", Common::EN_USA, Common::kPlatformPC },
- { "387a544b8b10b26912d8413bab63a853", "monkey2", Common::EN_USA, Common::kPlatformPC },
- { "3905799e081b80a61d4460b7b733c206", "maniac", Common::EN_USA, Common::kPlatformNES },
- { "3938ee1aa4433fca9d9308c9891172b1", "zak", Common::EN_USA, Common::kPlatformFMTowns },
- { "399b217b0c8d65d0398076da486363a9", "indy3", Common::DE_DEU, Common::kPlatformPC },
- { "39cb9dec16fa16f38d79acd80effb059", "loom", Common::FR_FRA, Common::kPlatformAmiga },
- { "39cb9dec16fa16f38d79acd80effb059", "loom", Common::IT_ITA, Common::kPlatformAmiga },
- { "39fd6db10d0222d817025c4d3346e3b4", "farm", Common::EN_USA, Common::kPlatformMacintosh },
- { "3a03dab514e4038df192d8a8de469788", "atlantis", Common::EN_USA, Common::kPlatformAmiga },
- { "3a0c35f3c147b98a2bdf8d400cfc4ab5", "indy3", Common::JA_JPN, Common::kPlatformFMTowns },
- { "3a5ec90d556d4920976c5578bfbfaf79", "maniac", Common::DE_DEU, Common::kPlatformNES },
- { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", Common::EN_USA, Common::kPlatformPC },
- { "3cce1913a3bc586b51a75c3892ff18dd", "indy3", Common::RU_RUS, Common::kPlatformPC },
- { "3d219e7546039543307b55a91282bf18", "funpack", Common::EN_USA, Common::kPlatformPC },
- { "3de99ef0523f8ca7958faa3afccd035a", "spyfox", Common::EN_USA, Common::kPlatformUnknown },
- { "3df6ead57930488bc61e6e41901d0e97", "fbear", Common::EN_USA, Common::kPlatformMacintosh },
- { "3e48298920fab9b7aec5a971e1bd1fab", "pajama3", Common::EN_USA, Common::kPlatformWindows },
- { "40564ec47da48a67787d1f9bd043902a", "maniac", Common::EN_USA, Common::kPlatformPC },
- { "4167a92a1d46baa4f4127d918d561f88", "tentacle", Common::EN_USA, Common::kPlatformUnknown },
- { "425205754fa749f4f0b0dd9d09fa45fd", "football", Common::EN_USA, Common::kPlatformUnknown },
- { "430bc518017b6fac046f58bab6baad5d", "monkey2", Common::JA_JPN, Common::kPlatformFMTowns },
- { "45082a5c9f42ba14dacfe1fdeeba819d", "freddicove", Common::EN_USA, Common::kPlatformUnknown },
- { "45152f7cf2ba8f43cf8a8ea2e740ae09", "monkey", Common::ES_ESP, Common::kPlatformPC },
- { "4521138d15d1fd7649c31fb981746231", "pajama2", Common::DE_DEU, Common::kPlatformUnknown },
- { "46b53fd430adcfbed791b48a0d4b079f", "funpack", Common::EN_USA, Common::kPlatformPC },
- { "477dbafbd66a53c98416dc01aef019ad", "monkey", Common::IT_ITA, Common::kPlatformPC },
- { "47e75b1bdcb44c78cb94883d1731ccf8", "fbear", Common::EN_USA, Common::kPlatformPC },
- { "48b9f04b348bc5013327753f0d12a144", "loom", Common::ES_ESP, Common::kPlatformAmiga },
- { "49210e124e4c2b30f1290a9ef6306301", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "4973bbc3899e3826dbf316e1d7271ec7", "zak", Common::DE_DEU, Common::kPlatformC64 },
- { "499c958affc394f2a3868f1eb568c3ee", "freddi4", Common::NL_NLD, Common::kPlatformWindows },
- { "4af4a6b248103c1fe9edef619677f540", "puttmoon", Common::EN_USA, Common::kPlatformMacintosh },
- { "4ba37f835be11a59d969f90f272f575b", "water", Common::EN_USA, Common::kPlatformUnknown },
- { "4ba7fb331296c283e73d8f5b2096e551", "samnmax", Common::ES_ESP, Common::kPlatformUnknown },
- { "4bedb49943df95a9c900a5a82ccbe9de", "ft", Common::FR_FRA, Common::kPlatformUnknown },
- { "4cb9c3618f71668f8e4346c8f323fa82", "monkey2", Common::EN_USA, Common::kPlatformMacintosh },
- { "4ce2d5b355964bbcb5e5ce73236ef868", "freddicove", Common::RU_RUS, Common::kPlatformWindows },
- { "4d34042713958b971cb139fba4658586", "atlantis", Common::JA_JPN, Common::kPlatformFMTowns },
- { "4dbff3787aedcd96b0b325f2d92d7ad9", "maze", Common::EN_USA, Common::kPlatformUnknown },
- { "4dc780f1bc587a193ce8a97652791438", "loom", Common::EN_USA, Common::kPlatformAmiga },
- { "4e5867848ee61bc30d157e2c94eee9b4", "PuttTime", Common::EN_USA, Common::kPlatformUnknown },
- { "4edbf9d03550f7ba01e7f34d69b678dd", "spyfox", Common::NL_NLD, Common::kPlatformWindows },
- { "4f04b321a95d4315ce6d65f8e1dd0368", "maze", Common::EN_USA, Common::kPlatformUnknown },
- { "4f267a901719623de7dde83e47d5b474", "atlantis", Common::DE_DEU, Common::kPlatformAmiga },
- { "4f580a021eee026f3b4589e17d130d78", "freddi4", Common::UNK_LANG, Common::kPlatformUnknown },
- { "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", Common::NL_NLD, Common::kPlatformWindows },
- { "4fbbe9f64b8bc547503a379a301183ce", "tentacle", Common::IT_ITA, Common::kPlatformUnknown },
- { "5057fb0e99e5aa29df1836329232f101", "freddi2", Common::UNK_LANG, Common::kPlatformWindows },
- { "507bb360688dc4180fdf0d7597352a69", "freddi", Common::SE_SWE, Common::kPlatformWindows },
- { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", Common::IT_ITA, Common::kPlatformPC },
- { "51305e929e330e24a75a0351c8f9975e", "freddi2", Common::EN_USA, Common::kPlatformUnknown },
- { "5262a27afcaee04e5c4900220bd463e7", "PuttsFunShop", Common::EN_USA, Common::kPlatformUnknown },
- { "52a4bae0746a11d7b1e8554e91a6645c", "zak", Common::FR_FRA, Common::kPlatformPC },
- { "53e94115b55dd51d4b8ff0871aa1df1e", "spyfox", Common::EN_USA, Common::kPlatformUnknown },
- { "54a936ad06161ff7bfefcb96200f7bff", "monkey", Common::EN_USA, Common::kPlatformAmiga },
- { "55518cd73cf9c6d23ea29c51ee06bdfe", "ft", Common::IT_ITA, Common::kPlatformUnknown },
- { "55d3987641bf229c83bc729210173383", "zak", Common::EN_USA, Common::kPlatformC64 },
- { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", Common::RU_RUS, Common::kPlatformUnknown },
- { "566165a7338fa11029e7c14d94fa70d0", "freddi", Common::EN_USA, Common::kPlatformWindows },
- { "5798972220cd458be2626d54c80f71d7", "atlantis", Common::IT_ITA, Common::kPlatformAmiga },
- { "57b0d89af79befe1cabce3bece869e7f", "tentacle", Common::DE_DEU, Common::kPlatformPC },
- { "58436e634f4fae1d9973591c2ffa1fcb", "spyfox", Common::EN_USA, Common::kPlatformUnknown },
- { "589601b676c98b1c0c987bc031ab68b3", "chase", Common::EN_USA, Common::kPlatformUnknown },
- { "58fdf4c7ad13540a734e18f8584cad89", "puttzoo", Common::EN_USA, Common::kPlatformMacintosh },
- { "590e6546aacd0d374b7f3a4f53013ab1", "freddicove", Common::UNK_LANG, Common::kPlatformUnknown },
- { "59d5cfcc5e672a6e07baae01328b918b", "PuttTime", Common::FR_FRA, Common::kPlatformUnknown },
- { "5a35e36fd777e9c37a49c5b2faca52f9", "loom", Common::EN_USA, Common::kPlatformPC },
- { "5b08000a9c47b2887df6506ac767ca68", "fbear", Common::EN_USA, Common::kPlatformUnknown },
- { "5bd335265a61caa3d78956ad9f88ba23", "football", Common::EN_USA, Common::kPlatformUnknown },
- { "5c21fc49aee8f46e58fef21579e614a1", "thinker1", Common::EN_USA, Common::kPlatformUnknown },
- { "5d88b9d6a88e6f8e90cded9d01b7f082", "loom", Common::EN_USA, Common::kPlatformPC },
- { "5e8fb66971a60e523e5afbc4c129c0e8", "socks", Common::EN_USA, Common::kPlatformUnknown },
- { "5fbe557049892eb4b709d90916ec97ca", "indy3", Common::EN_USA, Common::kPlatformPC },
- { "600abd3e9f47e63e670188b7e4e86ac7", "spyozon", Common::EN_USA, Common::kPlatformUnknown },
- { "6027e9ca9c35746d95dee2068cec17e5", "zak", Common::DE_DEU, Common::kPlatformAmiga },
- { "60ba818dc3bede86d40357e3913f8505", "ft", Common::EN_USA, Common::kPlatformUnknown },
- { "613f64f78ea26c7353b2a5940eb61d6a", "zak", Common::FR_FRA, Common::kPlatformAtariST },
- { "624cdb93654667c869d204a64af7e57f", "maniac", Common::EN_USA, Common::kPlatformPC },
- { "6271130f440066830eca9056c1d7926f", "water", Common::RU_RUS, Common::kPlatformWindows },
- { "62b8c16b6db226ba95aaa8be73f9885c", "indy3", Common::ES_ESP, Common::kPlatformAmiga },
- { "63fdcdc95cdeea00060883aed38e5504", "PuttTime", Common::EN_USA, Common::kPlatformWindows },
- { "6508fd55530e6915507e1cc37f7f045d", "indy3", Common::EN_USA, Common::kPlatformPC },
- { "659942b9a6b519f123a13cca3c333a13", "jungle", Common::EN_USA, Common::kPlatformMacintosh },
- { "66236cd1aec24e1d4aff4c4cc93b7e18", "indy3", Common::FR_FRA, Common::kPlatformPC },
- { "663743c03ae0c007f3d665cf631c0e6b", "puttrace", Common::DE_DEU, Common::kPlatformUnknown },
- { "66fd5ff9a810dfeb6d6bdada18221140", "monkey", Common::IT_ITA, Common::kPlatformPC },
- { "672dec94b82f7f0877ebb5b5cf7f4bc1", "pajama", Common::EN_USA, Common::kPlatformUnknown },
- { "675d71151e9b5a968c8ce46d9fbf4cbf", "zak", Common::EN_USA, Common::kPlatformPC },
- { "68155a6bf082221525f431c2cbdac8ab", "SamsFunShop", Common::EN_USA, Common::kPlatformUnknown },
- { "684732efb5799c0f78804c99d8de9aba", "puttputt", Common::EN_USA, Common::kPlatformMacintosh },
- { "688328c5bdc4c8ec4145688dfa077bf2", "freddi4", Common::DE_DEU, Common::kPlatformUnknown },
- { "6886e5d08cee329b1f2e743ae2e3ceed", "monkey2", Common::DE_DEU, Common::kPlatformPC },
- { "695fe0b3963333b7e15b37514db3c745", "thinkerk", Common::EN_USA, Common::kPlatformUnknown },
- { "697c9b7c55a05d8199c48b48e379d2c8", "puttmoon", Common::HB_ISR, Common::kPlatformPC },
- { "69ea626f1f87eecb78ea0d6c6b983a1d", "monkey2", Common::IT_ITA, Common::kPlatformPC },
- { "6a30a07f353a75cdc602db27d73e1b42", "puttputt", Common::EN_USA, Common::kPlatformWindows },
- { "6af2419fe3db5c2fdb091ae4e5833770", "puttrace", Common::NL_NLD, Common::kPlatformUnknown },
- { "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", Common::NL_NLD, Common::kPlatformWindows },
- { "6b257bb2827dd894b8109a50a1a18b5a", "freddicove", Common::NL_NLD, Common::kPlatformUnknown },
- { "6b3ec67da214f558dc5ceaa2acd47453", "indy3", Common::EN_USA, Common::kPlatformPC },
- { "6b5a3fef241e90d4b2e77f1e222773ee", "maniac", Common::SE_SWE, Common::kPlatformNES },
- { "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", Common::UNK_LANG, Common::kPlatformWindows },
- { "6c2bff0e327f2962e809c2e1a82d7309", "monkey", Common::EN_USA, Common::kPlatformAmiga },
- { "6dead580b0ff14d5f7b33b4219f04159", "samnmax", Common::EN_USA, Common::kPlatformMacintosh },
- { "6df20c50c1ab19799de9be7ae7716881", "fbear", Common::EN_USA, Common::kPlatformMacintosh },
- { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", Common::DE_DEU, Common::kPlatformUnknown },
- { "6ea966b4d660c870b9ee790d1fbfc535", "monkey2", Common::ES_ESP, Common::kPlatformAmiga },
- { "6f0be328c64d689bb606d22a389e1b0f", "loom", Common::EN_USA, Common::kPlatformMacintosh },
- { "6f6ef668c608c7f534fea6e6d3878dde", "indy3", Common::DE_DEU, Common::kPlatformPC },
- { "6f8a22bfa397be1f7ed4b74aba0e397e", "loom", Common::FR_FRA, Common::kPlatformPC },
- { "701246819d1a70573f41bf33fc19214f", "soccer", Common::EN_USA, Common::kPlatformUnknown },
- { "7020931d5a2be0a49d68e7a1882363e4", "zak", Common::EN_USA, Common::kPlatformPC },
- { "71523b539491527d9860f4407faf0411", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "71fe97c3108678cf604f14abe342341b", "spyfox2", Common::NL_NLD, Common::kPlatformWindows },
- { "7222f260253f325c21fcfa68b5bfab67", "spyfox2", Common::EN_USA, Common::kPlatformUnknown },
- { "72ac6bc980d5101c2142189d746bd62f", "spyfox", Common::RU_RUS, Common::kPlatformWindows },
- { "732845548b1d6c2da572cb6a1bf81b07", "spyfox2", Common::DE_DEU, Common::kPlatformUnknown },
- { "73b8197e236da4bf49adc99fe8f5fa1b", "spyfox", Common::DE_DEU, Common::kPlatformUnknown },
- { "73e5ab7dbb9a8061cc6d25df02dbd1e7", "loom", Common::EN_USA, Common::kPlatformPC },
- { "746e88c172a5b7a1ae89ac0ee3ee681a", "freddi", Common::RU_RUS, Common::kPlatformWindows },
- { "754feb59d3bf86b8a00840df74fd7b26", "freddi3", Common::NL_NLD, Common::kPlatformWindows },
- { "75ba23fff4fd63fa446c02864f2a5a4b", "zak", Common::IT_ITA, Common::kPlatformPC },
- { "75bff95816b84672b877d22a911ab811", "freddi3", Common::RU_RUS, Common::kPlatformWindows },
- { "771bc18ec6f93837b839c992b211904b", "monkey", Common::DE_DEU, Common::kPlatformPC },
- { "77f5c9cc0986eb729c1a6b4c8823bbae", "zak", Common::EN_USA, Common::kPlatformFMTowns },
- { "780e4a0ae2ff17dc296f4a79543b44f8", "puttmoon", Common::UNK_LANG, Common::kPlatformPC },
- { "78bd5f036ea35a878b74e4f47941f784", "freddi4", Common::RU_RUS, Common::kPlatformWindows },
- { "7974365d3dc0f43a2748c975f91ff042", "monkey2", Common::ES_ESP, Common::kPlatformPC },
- { "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", Common::RU_RUS, Common::kPlatformUnknown },
- { "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", Common::EN_USA, Common::kPlatformUnknown },
- { "7c8100e360e8ef05f88069d4cfa0afd1", "puttrace", Common::EN_USA, Common::kPlatformWindows },
- { "7c980a1b1596a93f26917318884f48f7", "PuttTime", Common::DE_DEU, Common::kPlatformUnknown },
- { "7ddeaf52c8b9a50551ce0aa2ac811d07", "BluesABCTimeDemo", Common::EN_USA, Common::kPlatformUnknown },
- { "7e151c17adf624f1966c8fc5827c95e9", "puttputt", Common::EN_USA, Common::kPlatformUnknown },
- { "7ea2da67ebabea4ac20cee9f4f9d2934", "airport", Common::EN_USA, Common::kPlatformMacintosh },
- { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", Common::FR_FRA, Common::kPlatformUnknown },
- { "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", Common::EN_USA, Common::kPlatformPC },
- { "7f945525abcd48015adf1632637a44a1", "pajama", Common::FR_FRA, Common::kPlatformUnknown },
- { "7fc6cdb46b4c9d384c52327f4bca6416", "football", Common::EN_USA, Common::kPlatformUnknown },
- { "810a9da887aefa597b0cf3c77d262897", "BluesABCTimeDemo", Common::EN_USA, Common::kPlatformUnknown },
- { "81bbfa181184cb494e7a81dcfa94fbd9", "maniac", Common::FR_FRA, Common::kPlatformNES },
- { "8299d9b8a1b0e7b881bae7a9971dc5e2", "zak", Common::EN_USA, Common::kPlatformAtariST },
- { "8368f552b1e3eba559f8d559bcc4cadb", "freddi3", Common::UNK_LANG, Common::kPlatformUnknown },
- { "83cedbe26aa8b58988e984e3d34cac8e", "freddi3", Common::DE_DEU, Common::kPlatformUnknown },
- { "84e3c23a49ded8a6f9197735c8eb3de7", "PuttTime", Common::DE_DEU, Common::kPlatformWindows },
- { "861e59ed72a1cd0e6d454f7ee7e2bf3d", "comi", Common::RU_RUS, Common::kPlatformUnknown },
- { "86be8ada36371d4fdc35659d0e912a26", "indy3", Common::ES_ESP, Common::kPlatformPC },
- { "86c9902b7bec1a17926d4dae85beaa45", "airport", Common::EN_USA, Common::kPlatformWindows },
- { "870d1e3c86bc50846d808d14a36b4e08", "monkey", Common::ES_ESP, Common::kPlatformAmiga },
- { "87f6e8037b7cc996e13474b491a7a98e", "maniac", Common::IT_ITA, Common::kPlatformPC },
- { "8801fb4a1200b347f7a38523339526dd", "jungle", Common::EN_USA, Common::kPlatformWindows },
- { "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", Common::ES_ESP, Common::kPlatformUnknown },
- { "898ce8eb1234a955ef75e87141902bb3", "freddi3", Common::RU_RUS, Common::kPlatformWindows },
- { "898eaa21f79cf8d4f08db856244689ff", "pajama", Common::EN_USA, Common::kPlatformWindows },
- { "89cfc425566003ff74b7dc7b3e6fd469 ", "indy3", Common::FR_FRA, Common::kPlatformPC },
- { "8a484262363a8e18be87112454f1456b", "pjgames", Common::EN_USA, Common::kPlatformUnknown },
- { "8aa05d3cdb0e795436043f0546af2da2", "tentacle", Common::FR_FRA, Common::kPlatformUnknown },
- { "8afb3cf9f95abf208358e984f0c9e738", "funpack", Common::EN_USA, Common::kPlatformUnknown },
- { "8bdb0bf87b5e303dd35693afb9351215", "ft", Common::DE_DEU, Common::kPlatformUnknown },
- { "8d479e36f35e80257dfc102cf4b8a912", "farm", Common::EN_USA, Common::kPlatformWindows },
- { "8e3241ddd6c8dadf64305e8740d45e13", "balloon", Common::EN_USA, Common::kPlatformUnknown },
- { "8e4ee4db46954bfe2912e259a16fad82", "monkey2", Common::FR_FRA, Common::kPlatformPC },
- { "8eb84cee9b429314c7f0bdcf560723eb", "monkey", Common::EN_USA, Common::kPlatformFMTowns },
- { "8ee63cafb1fe9d62aa0d5a23117e70e7", "freddi2", Common::EN_USA, Common::kPlatformUnknown },
- { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", Common::IT_ITA, Common::kPlatformPC },
- { "8fec68383202d38c0d25e9e3b757c5df", "comi", Common::UNK_LANG, Common::kPlatformUnknown },
- { "8ffd618a776a4c0d8922bb28b09f8ce8", "airport", Common::EN_USA, Common::kPlatformWindows },
- { "90a329d8ad5b7ce0690429e98cfbb32f", "funpack", Common::HB_ISR, Common::kPlatformPC },
- { "90c755e1c9b9b8a4129d37b2259d0655", "chase", Common::EN_USA, Common::kPlatformUnknown },
- { "910e31cffb28226bd68c569668a0d6b4", "monkey", Common::ES_ESP, Common::kPlatformPC },
- { "91469353f7be1b122fa88d23480a1320", "zak", Common::FR_FRA, Common::kPlatformAmiga },
- { "91d5db93187fab54d823f73bd6441cb6", "maniac", Common::EN_USA, Common::kPlatformNES },
- { "927a764615c7fcdd72f591355e089d8c", "monkey", Common::DE_DEU, Common::kPlatformAtariST },
- { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", Common::FR_FRA, Common::kPlatformPC },
- { "92e7727e67f5cd979d8a1070e4eb8cb3", "puttzoo", Common::EN_USA, Common::kPlatformUnknown },
- { "92fc0073a4cf259ff36070ecb8628ba8", "thinkerk", Common::EN_USA, Common::kPlatformUnknown },
- { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", Common::FR_FRA, Common::kPlatformPC },
- { "96a3069a3c63caa7329588ce1fef41ee", "spyozon", Common::RU_RUS, Common::kPlatformUnknown },
- { "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", Common::EN_USA, Common::kPlatformPC },
- { "981e1e1891f2be7e25a01f50ae55a5af", "puttrace", Common::EN_USA, Common::kPlatformUnknown },
- { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", Common::EN_USA, Common::kPlatformPC },
- { "99a3699f80b8f776efae592b44b9b991", "maniac", Common::FR_FRA, Common::kPlatformPC },
- { "99b6f822b0b2612415407865438697d6", "atlantis", Common::EN_USA, Common::kPlatformPC },
- { "9b7452b5cd6d3ffb2b2f5118010af84f", "ft", Common::EN_USA, Common::kPlatformMacintosh },
- { "9bc548e179cdb0767009401c094d0895", "maniac", Common::DE_DEU, Common::kPlatformAmiga },
- { "9bd2a8f72613e715c199246dd511e10f", "atlantis", Common::ES_ESP, Common::kPlatformPC },
- { "9bda5fee51d2fda5253d02c642016bf4", "spyfox", Common::NL_NLD, Common::kPlatformWindows },
- { "9c0fee288ad564a7d25ec3e841810d79", "indy3", Common::EN_USA, Common::kPlatformAmiga },
- { "9c143c5905055d5df7a0f014ab379aee", "puttmoon", Common::EN_USA, Common::kPlatformWindows },
- { "9c92eeaf517a31b7221ec2546ab669fd", "puttmoon", Common::EN_USA, Common::kPlatformWindows },
- { "9cdd327c1034c046cb595d251c44da2f", "chase", Common::RU_RUS, Common::kPlatformWindows },
- { "9d4ab3e0e1d1ebc6ba8a6a4c470ed184", "spyfox", Common::EN_USA, Common::kPlatformUnknown },
- { "9d7b67be003fea60be4dcbd193611936", "ft", Common::EN_USA, Common::kPlatformMacintosh },
- { "9dc02577bf50d4cfaf3de3fbac06fbe2", "puttmoon", Common::EN_USA, Common::kPlatformMacintosh },
- { "9e5e0fb43bd22f4628719b7501adb717", "monkey", Common::FR_FRA, Common::kPlatformAtariST },
- { "a095e33061606d231ff37dca4c64c8ac", "pajama", Common::DE_DEU, Common::kPlatformUnknown },
- { "a0a7dea72003933b8b3f8b99b9f7ddeb", "loom", Common::EN_USA, Common::kPlatformAtariST },
- { "a194f15f51ee62badab74b9e7da97693", "baseball2001", Common::EN_USA, Common::kPlatformUnknown },
- { "a28135a7ade38cc0208b04507c46efd1", "spyfox", Common::DE_DEU, Common::kPlatformUnknown },
- { "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", Common::EN_USA, Common::kPlatformWindows },
- { "a3036878840720fbefa41e6965fa4a0a", "samnmax", Common::EN_USA, Common::kPlatformPC },
- { "a525c1753c1db5011c00417da37887ef", "PuttTime", Common::EN_USA, Common::kPlatformUnknown },
- { "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", Common::EN_USA, Common::kPlatformUnknown },
- { "a570381b028972d891052ee1e51dc011", "maniac", Common::EN_USA, Common::kPlatformAtariST },
- { "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", Common::EN_USA, Common::kPlatformUnknown },
- { "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", Common::EN_USA, Common::kPlatformUnknown },
- { "a85856675429fe88051744f755b72f93", "farm", Common::EN_USA, Common::kPlatformWindows },
- { "a86f9c49355579c30d4a55b477c0d869", "baseball2001", Common::EN_USA, Common::kPlatformUnknown },
- { "a9543ef0d79bcb47cd76ec197ad0a967", "puttmoon", Common::EN_USA, Common::kPlatformUnknown },
- { "a9f2f04b1ecaab9495b59befffe9bf88", "pajama3", Common::EN_USA, Common::kPlatformUnknown },
- { "aa6a91b7f6f119d1b7b1f2a4c9e24d59", "puttmoon", Common::EN_USA, Common::kPlatformPC },
- { "aa7a07d94ae853f6460be4ce0a1bf530", "monkey", Common::FR_FRA, Common::kPlatformPC },
- { "aa8a0cb65f3afbbe2c14c3f9f92775a3", "monkey", Common::FR_FRA, Common::kPlatformPC },
- { "aaa587701cde7e74692c68c1024b85eb", "puttrace", Common::NL_NLD, Common::kPlatformUnknown },
- { "ab0693e9324cfcf498fdcbb12acf8bb4", "puttcircus", Common::EN_USA, Common::kPlatformUnknown },
- { "ac1642b6edfb8521ca03760126f1c250", "tentacle", Common::DE_DEU, Common::kPlatformPC },
- { "ac62d50e39492ee3738b4e83a5ac780f", "freddi2", Common::NL_NLD, Common::kPlatformWindows },
- { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", Common::EN_USA, Common::kPlatformUnknown },
- { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", Common::ES_ESP, Common::kPlatformPC },
- { "b23f7cd7c304d7dff08e92a96120d5b4", "zak", Common::EN_USA, Common::kPlatformPC },
- { "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", Common::EN_USA, Common::kPlatformPC },
- { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", Common::IT_ITA, Common::kPlatformPC },
- { "b5298a5c15ffbe8b381d51ea4e26d35c", "freddi4", Common::DE_DEU, Common::kPlatformUnknown },
- { "b597e0403cc0002f69170e6caba7edd9", "indy3", Common::EN_USA, Common::kPlatformPC },
- { "b628506f7def772e40de0aa5440fb8e1", "activity", Common::EN_USA, Common::kPlatformWindows },
- { "b886b0a5d909c7158a914e1d7c1c6c65", "loom", Common::FR_FRA, Common::kPlatformPC },
- { "b8955d7d23b4972229060d1592489fef", "freddicove", Common::NL_NLD, Common::kPlatformWindows },
- { "ba888e6831517597859e91aa173f945c", "spyfox", Common::FR_FRA, Common::kPlatformUnknown },
- { "bbadf7309c4a2c2763e4bbba3c3be634", "freddi3", Common::FR_FRA, Common::kPlatformUnknown },
- { "bc4700bc0e12879f6d25d14d6be6cfdd", "spyfox2", Common::DE_DEU, Common::kPlatformUnknown },
- { "bd126753de619a495f9f22adc951c8d5", "monkey2", Common::IT_ITA, Common::kPlatformPC },
- { "be39a5d4db60e8aa736b9086778cb45c", "spyozon", Common::EN_USA, Common::kPlatformWindows },
- { "be83e882b44f2767bc08d4f766ebc347", "maniac", Common::DE_DEU, Common::kPlatformAtariST },
- { "bf8b52fdd9a69c67f34e8e9fec72661c", "farm", Common::EN_USA, Common::kPlatformWindows },
- { "bfdf584b01503f0762baded581f6a0a2", "SoccerMLS", Common::EN_USA, Common::kPlatformWindows },
- { "c0039ad982999c92d0de81910d640fa0", "freddi", Common::NL_NLD, Common::kPlatformWindows },
- { "c13225cb1bbd3bc9fe578301696d8021", "monkey", Common::EN_USA, Common::kPlatformSegaCD },
- { "c24c490373aeb48fbd54caa8e7ae376d", "loom", Common::DE_DEU, Common::kPlatformAtariST },
- { "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", Common::EN_USA, Common::kPlatformUnknown },
- { "c30ef068add4277104243c31ce46c12b", "monkey2", Common::FR_FRA, Common::kPlatformAmiga },
- { "c3196c5349e53e387aaff1533d95e53a", "samnmax", Common::EN_USA, Common::kPlatformPC },
- { "c3b22fa4654bb580b20325ebf4174841", "puttzoo", Common::NL_NLD, Common::kPlatformWindows },
- { "c3df37df9d3b481b45f75283a9907c47", "loom", Common::IT_ITA, Common::kPlatformPC },
- { "c4787c3e8b5e2dfda90850ee800af00f", "zak", Common::FR_FRA, Common::kPlatformPC },
- { "c4a7f7398ac9ae588940f9912ea5fd8f", "maniac", Common::DE_DEU, Common::kPlatformC64 },
- { "c4ffae9fac495475d6bc3343ccc8faf9", "Soccer2004", Common::EN_USA, Common::kPlatformUnknown },
- { "c5d10e190d4b4d59114b824f2fdbd00e", "loom", Common::EN_USA, Common::kPlatformFMTowns },
- { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", Common::EN_USA, Common::kPlatformPC },
- { "c666a998af90d81db447eccba9f72c8d", "monkey", Common::EN_USA, Common::kPlatformAtariST },
- { "c6907d44f1166941d982864cd42cdc89", "pajama2", Common::DE_DEU, Common::kPlatformUnknown },
- { "c7890e038806df2bb5c0c8c6f1986ea2", "monkey", Common::EN_USA, Common::kPlatformPC },
- { "c7be10f775404fd9785a8b92a06d240c", "atlantis", Common::EN_USA, Common::kPlatformFMTowns },
- { "c83079157ec765a28de445aec9768d60", "tentacle", Common::EN_USA, Common::kPlatformUnknown },
- { "c8aac5e3e701874e2fa4117896f9e1b1", "freddi", Common::EN_USA, Common::kPlatformMacintosh },
- { "cb1559e8405d17a5a278a6b5ad9338d1", "freddi3", Common::EN_USA, Common::kPlatformUnknown },
- { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", Common::EN_USA, Common::kPlatformMacintosh },
- { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", Common::DE_DEU, Common::kPlatformPC },
- { "cd9c05e755d7bf8e9b9590ad1ebe273e", "dig", Common::EN_USA, Common::kPlatformMacintosh },
- { "cdd760228cf1010c2903f37e788ea31c", "zak", Common::DE_DEU, Common::kPlatformPC },
- { "ce6a4cef315b20fef58a95bc40a2d8d3", "monkey", Common::FR_FRA, Common::kPlatformPC },
- { "ce7733f185b838e248927c7ba1a04204", "maniac", Common::FR_FRA, Common::kPlatformAmiga },
- { "ce7fd0c382389a6791fc3e199c117ef4", "indy3", Common::ES_ESP, Common::kPlatformPC },
- { "cea91e3dd47f2518ea418e41611aa77f", "spyfox2", Common::RU_RUS, Common::kPlatformUnknown },
- { "cf4ef315214c7d8cdab6302cdb7e50db", "freddi", Common::DE_DEU, Common::kPlatformWindows },
- { "cf8d13446ec6cb6222287a925fd47c1d", "baseball", Common::EN_USA, Common::kPlatformUnknown },
- { "cf8ef3a1fb483c5c4b1c584d1167b2c4", "freddi", Common::DE_DEU, Common::kPlatformWindows },
- { "cf90b4db5486ef798db78fe6fbf897e5", "pajama3", Common::EN_USA, Common::kPlatformWindows },
- { "d06fbe28818fef7bfc45c2cdf0c0849d", "zak", Common::DE_DEU, Common::kPlatformPC },
- { "d0b531227a27c6662018d2bd05aac52a", "monkey", Common::DE_DEU, Common::kPlatformPC },
- { "d220d154aafbfa12bd6f3ab1b2dae420", "puttzoo", Common::DE_DEU, Common::kPlatformMacintosh },
- { "d37c55388294b66e53e7ced3af88fa68", "freddi2", Common::EN_USA, Common::kPlatformUnknown },
- { "d43352a805d78b5f4936c6d7779bf575", "samnmax", Common::RU_RUS, Common::kPlatformPC },
- { "d4aac997e2f4e15341f0bfbf905419bd", "PuttTime", Common::EN_USA, Common::kPlatformWindows },
- { "d4b8ee426b1afd3e53bc0cf020418cf6", "dog", Common::EN_USA, Common::kPlatformWindows },
- { "d4cccb5af88f3e77f370896e9ba8c5f9", "freddi", Common::UNK_LANG, Common::kPlatformWindows },
- { "d4e79c3d8645b8266cd78c325bc35154", "pajama2", Common::EN_USA, Common::kPlatformUnknown },
- { "d55eff37c2100f5065cde9de428621fa", "zak", Common::EN_USA, Common::kPlatformAtariST },
- { "d62047a6729349ab36f7ee065bf26509", "dig", Common::RU_RUS, Common::kPlatformUnknown },
- { "d62d248c3df6ec177405e2cb23d923b2", "indy3", Common::IT_ITA, Common::kPlatformPC },
- { "d6334a5a9b61afe18c368540fdf522ca", "airport", Common::EN_USA, Common::kPlatformMacintosh },
- { "d6dd0646404768a63e963891a96daadd", "atlantis", Common::EN_USA, Common::kPlatformMacintosh },
- { "d7ab7cd6105546016e6a0d46fb36b964", "pajama", Common::EN_USA, Common::kPlatformUnknown },
- { "d7b247c26bf1f01f8f7daf142be84de3", "balloon", Common::EN_USA, Common::kPlatformWindows },
- { "d831f7c048574dd9d5d85db2a1468099", "maniac", Common::EN_USA, Common::kPlatformC64 },
- { "d8323015ecb8b10bf53474f6e6b0ae33", "dig", Common::UNK_LANG, Common::kPlatformUnknown },
- { "d8d07efcb88f396bee0b402b10c3b1c9", "maniac", Common::EN_USA, Common::kPlatformNES },
- { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", Common::EN_USA, Common::kPlatformUnknown },
- { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", Common::EN_USA, Common::kPlatformPC },
- { "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", Common::EN_USA, Common::kPlatformFMTowns },
- { "da6269b18fcb08189c0aa9c95533cce2", "monkey", Common::IT_ITA, Common::kPlatformPC },
- { "da669b20271b85182e9c17a2a37ea02e", "monkey2", Common::DE_DEU, Common::kPlatformAmiga },
- { "dd30a53035393baa5a5e222e716559af", "maniac", Common::FR_FRA, Common::kPlatformAtariST },
- { "de4efb910210736813c9a1185384bace", "puttzoo", Common::EN_USA, Common::kPlatformWindows },
- { "debe337f73d660e951ece7c1f1c81add", "zak", Common::EN_USA, Common::kPlatformPC },
- { "defb8cb9ec4b0f91acfb6b61c6129ad9", "PuttTime", Common::RU_RUS, Common::kPlatformWindows },
- { "df03ee021aa9b81d90cab9c26da07614", "indy3", Common::IT_ITA, Common::kPlatformAmiga },
- { "df047cc4792150f601290357566d36a6", "freddi", Common::EN_USA, Common::kPlatformUnknown },
- { "e01acc8c12ef44e8f778fe87e5f90f4e", "fbpack", Common::EN_USA, Common::kPlatformUnknown },
- { "e03ed1474ec14de78359970e0457a820", "freddi4", Common::EN_USA, Common::kPlatformWindows },
- { "e144f5f49d9241d2a9dee2576b3d09cb", "airport", Common::EN_USA, Common::kPlatformWindows },
- { "e17db1ddf91b39ca6bbc8ad3ed19e883", "monkey", Common::JA_JPN, Common::kPlatformFMTowns },
- { "e246e02db9630533a40d99c9f54a8e01", "monkey2", Common::EN_USA, Common::kPlatformMacintosh },
- { "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", Common::HB_ISR, Common::kPlatformPC },
- { "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", Common::RU_RUS, Common::kPlatformWindows },
- { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", Common::DE_DEU, Common::kPlatformAmiga },
- { "e63a0b9249b5ca4cc4d3ac34305ae360", "freddi", Common::NB_NOR, Common::kPlatformWindows },
- { "e689bdf67f98b1d760ce4487ec0e8d06", "indy3", Common::FR_FRA, Common::kPlatformAmiga },
- { "e6cd81b25ab1453a8a6d3482118c391e", "pass", Common::EN_USA, Common::kPlatformPC },
- { "e72bb4c2b613db2cf50f89ff6350e70a", "ft", Common::ES_ESP, Common::kPlatformUnknown },
- { "e781230da44a44e2f0770edb2b3b3633", "maniac", Common::EN_USA, Common::kPlatformAmiga },
- { "e94c7cc3686fce406d3c91b5eae5a72d", "zak", Common::EN_USA, Common::kPlatformAmiga },
- { "e98b982ceaf9d253d730bde8903233d6", "monkey", Common::DE_DEU, Common::kPlatformPC },
- { "eae95b2b3546d8ba86ae1d397c383253", "dog", Common::EN_USA, Common::kPlatformUnknown },
- { "ebd0b2c8a387f18887282afe6cad894a", "spyozon", Common::EN_USA, Common::kPlatformUnknown },
- { "ebd324dcf06a4c49e1ba5c231eee1060", "freddi4", Common::EN_USA, Common::kPlatformUnknown },
- { "ed2b074bc3166087a747acb2a3c6abb0", "freddi3", Common::DE_DEU, Common::kPlatformUnknown },
- { "ed361270102e355afe5236954216aba2", "lost", Common::EN_USA, Common::kPlatformUnknown },
- { "edfdb24a499d92c59f824c52987c0eec", "atlantis", Common::FR_FRA, Common::kPlatformPC },
- { "ef347474f3c7be3b29584eaa133cca05", "samnmax", Common::FR_FRA, Common::kPlatformPC },
- { "ef74d9071d4e564b037cb44bd6774de7", "fbear", Common::HB_ISR, Common::kPlatformPC },
- { "efe0a04a703e765ebebe92b6c8aa6b86", "baseball2003", Common::EN_USA, Common::kPlatformUnknown },
- { "f049e38c1f8302b5db6170f1872af89a", "monkey", Common::ES_ESP, Common::kPlatformPC },
- { "f06e66fd45b2f8b0f4a2833ff4476050", "fbpack", Common::HB_ISR, Common::kPlatformPC },
- { "f08145577e4f13584cc90b3d6e9caa55", "pajama3", Common::NL_NLD, Common::kPlatformUnknown },
- { "f1b0e0d587b85052de5534a3847e68fe", "water", Common::EN_USA, Common::kPlatformUnknown },
- { "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", Common::EN_USA, Common::kPlatformUnknown },
- { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", Common::DE_DEU, Common::kPlatformPC },
- { "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", Common::EN_USA, Common::kPlatformWindows },
- { "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", Common::EN_USA, Common::kPlatformMacintosh },
- { "f73883f13b5a302749a5bad31d909780", "tentacle", Common::DE_DEU, Common::kPlatformMacintosh },
- { "f7711f9264d4d43c2a1518ec7c10a607", "pajama3", Common::EN_USA, Common::kPlatformUnknown },
- { "f79e60c17cca601e411f1f75e8ee9b5a", "spyfox2", Common::UNK_LANG, Common::kPlatformUnknown },
- { "fa127d7c4bb47d05bb1c33ddcaa9f767", "loom", Common::DE_DEU, Common::kPlatformPC },
- { "fb66aa42de21675116346213f176a366", "monkey", Common::IT_ITA, Common::kPlatformAmiga },
- { "fbb697d89d2beca87360a145f467bdae", "PuttTime", Common::DE_DEU, Common::kPlatformUnknown },
- { "fbbbb38a81fc9d6a61d509278390a290", "farm", Common::EN_USA, Common::kPlatformMacintosh },
- { "fbdd947d21e8f5bac6d6f7a316af1c5a", "spyfox", Common::EN_USA, Common::kPlatformUnknown },
- { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", Common::ES_ESP, Common::kPlatformPC },
- { "fc6b6148e80d67939d9a18697c0f626a", "monkey", Common::DE_DEU, Common::kPlatformPC },
- { "fc8d197a22146e74766e9cb0cfcaf1da", "freddi2", Common::EN_USA, Common::kPlatformUnknown },
- { "fcb78ebecab2757264c590890c319cc5", "PuttTime", Common::NL_NLD, Common::kPlatformWindows },
- { "fce4b8010704b103acfeea9413788f32", "freddi2", Common::DE_DEU, Common::kPlatformUnknown },
- { "fe381e45117878b1e942cb876b050fd6", "ft", Common::EN_USA, Common::kPlatformMacintosh },
- { "fe60d6b5ff51b0553ac59963123b5777", "comi", Common::UNK_LANG, Common::kPlatformUnknown },
- { "ff05c07990061d97647f059c48c1d05a", "zak", Common::DE_DEU, Common::kPlatformAtariST },
- { 0, 0, Common::UNK_LANG, Common::kPlatformUnknown }
-};
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
deleted file mode 100644
index 5cd9ef9111..0000000000
--- a/scumm/scumm.cpp
+++ /dev/null
@@ -1,3472 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "backends/fs/fs.h"
-
-#include "base/gameDetector.h"
-#include "base/plugins.h"
-
-#include "common/config-manager.h"
-#include "common/md5.h"
-#include "common/system.h"
-
-#include "gui/message.h"
-#include "gui/newgui.h"
-
-#include "scumm/akos.h"
-#include "scumm/charset.h"
-#include "scumm/costume.h"
-#include "scumm/debugger.h"
-#include "scumm/dialogs.h"
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/insane/insane.h"
-#include "scumm/intern.h"
-#include "scumm/intern_he.h"
-#include "scumm/logic_he.h"
-#include "scumm/player_nes.h"
-#include "scumm/player_v1.h"
-#include "scumm/player_v2.h"
-#include "scumm/player_v2a.h"
-#include "scumm/player_v3a.h"
-#include "scumm/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/sprite_he.h"
-#include "scumm/util.h"
-
-#ifdef PALMOS_68K
-#include "extras/palm-scumm-md5.h"
-#else
-#include "scumm/scumm-md5.h"
-#endif
-#include "scumm/verbs.h"
-
-#include "sound/mixer.h"
-
-#ifdef MACOSX
-#include <sys/types.h>
-#include <sys/stat.h>
-#endif
-
-#ifdef _WIN32_WCE
-extern bool isSmartphone(void);
-#endif
-
-#if (defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
-namespace Graphics {
- extern void initfonts();
-}
-#endif
-
-static int generateSubstResFileName_(const char *filename, char *buf, int bufsize, int index);
-
-using Common::File;
-
-namespace Scumm {
-
-// Use g_scumm from error() ONLY
-ScummEngine *g_scumm = 0;
-
-struct ScummGameSettings {
- const char *gameid;
- const char *description;
- byte id, version, heversion;
- int midi; // MidiDriverFlags values
- uint32 features;
- Common::Platform platform;
-
- GameSettings toGameSettings() const {
- GameSettings dummy = { gameid, description, features };
- return dummy;
- }
-};
-
-
-enum {
- // We only compute the MD5 of the first megabyte of our data files.
- kMD5FileSizeLimit = 1024 * 1024
-};
-
-
-struct ObsoleteGameIDs {
- const char *from;
- const char *to;
- Common::Platform platform;
-
- GameSettings toGameSettings() const {
- GameSettings dummy = { from, "Obsolete game ID", 0 };
- return dummy;
- }
-};
-
-static const Common::Platform UNK = Common::kPlatformUnknown;
-
-/**
- * Conversion table mapping old obsolete game IDs to the
- * corresponding new game ID and platform combination.
- *
- * We use an ugly macro 'UNK' here to make the following table more readable.
- */
-static ObsoleteGameIDs obsoleteGameIDsTable[] = {
- {"comidemo", "comi", UNK},
- {"digdemo", "dig", UNK},
- {"digdemoMac", "dig", Common::kPlatformMacintosh},
- {"dottdemo", "tentacle", UNK},
- {"fate", "atlantis", UNK},
- {"ftMac", "ft", Common::kPlatformMacintosh},
- {"ftpcdemo", "ft", UNK},
- {"ftdemo", "ft", Common::kPlatformMacintosh},
- {"game", "monkey", UNK},
- {"indy3ega", "indy3", UNK},
- {"indy3towns", "indy3", Common::kPlatformFMTowns},
- {"indy4", "atlantis", Common::kPlatformFMTowns},
- {"indydemo", "atlantis", Common::kPlatformFMTowns},
- {"loomcd", "loom", UNK},
- {"loomTowns", "loom", Common::kPlatformFMTowns},
- {"mi2demo", "monkey2", UNK},
- {"monkey1", "monkey", UNK},
- {"monkeyEGA", "monkey", UNK},
- {"monkeyVGA", "monkey", UNK},
- {"playfate", "atlantis", UNK},
- {"samnmax-alt", "samnmax", UNK},
- {"samnmaxMac", "samnmax", Common::kPlatformMacintosh},
- {"samdemo", "samnmax", UNK},
- {"samdemoMac", "samnmax", Common::kPlatformMacintosh},
- {"snmdemo", "samnmax", UNK},
- {"snmidemo", "samnmax", UNK},
- {"tentacleMac", "tentacle", Common::kPlatformMacintosh},
- {"zakTowns", "zak", Common::kPlatformFMTowns},
- {NULL, NULL, UNK}
-};
-
-static const ScummGameSettings scumm_settings[] = {
- /* Scumm Version 1 */
- /* Scumm Version 2 */
-
- {"maniac", "Maniac Mansion", GID_MANIAC, 2, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
- {"zak", "Zak McKracken and the Alien Mindbenders", GID_ZAK, 2, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
-
- /* Scumm Version 3 */
- {"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
- {"loom", "Loom", GID_LOOM, 3, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
-
- /* Scumm Version 4 */
- {"pass", "Passport to Adventure", GID_PASS, 4, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
-
- /* Scumm version 5, small header -- we treat these as V4 games, since internally
- they really are much closer to the V4 games than to all other V5 games. */
- {"monkey", "The Secret of Monkey Island", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY, Common::kPlatformPC},
-
- /* Scumm version 5 */
- {"monkey2", "Monkey Island 2: LeChuck's Revenge", GID_MONKEY2, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformPC},
-
- {"atlantis", "Indiana Jones and the Fate of Atlantis", GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformPC},
-
- /* Scumm Version 6 */
- {"tentacle", "Day of the Tentacle", GID_TENTACLE, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformPC},
-
- {"samnmax", "Sam & Max Hit the Road", GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformPC},
-
-// {"test", "Test demo game", GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI, GF_NEW_OPCODES, Common::kPlatformUnknown},
-
-#ifndef DISABLE_SCUMM_7_8
- /* Scumm Version 7 */
- {"ft", "Full Throttle", GID_FT, 7, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE, Common::kPlatformPC},
-
- {"dig", "The Dig", GID_DIG, 7, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE, Common::kPlatformPC},
-
- /* Scumm Version 8 */
- {"comi", "The Curse of Monkey Island", GID_CMI, 8, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEFAULT_TO_1X_SCALER, Common::kPlatformWindows},
-
-#endif
-
- // Humongous Entertainment Scumm Version 6
- {"puttputt", "Putt-Putt Joins the Parade", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
- {"puttmoon", "Putt-Putt Goes to the Moon", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
- {"funpack", "Putt-Putt's Fun Pack", GID_FUNPACK, 6, 61, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
- {"fbpack", "Fatty Bear's Fun Pack", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
- {"fbear", "Fatty Bear's Birthday Surprise", GID_FBEAR, 6, 61, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformPC},
-
-#ifndef DISABLE_HE
- {"activity", "Putt-Putt & Fatty Bear's Activity Pack", GID_HEGAME, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 7.1
- // The first version to use 640x480 resolution
- // There are also 7.1 versions of freddemo, airdemo and farmdemo
- {"catalog", "Humongous Interactive Catalog", GID_HEGAME, 6, 71, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"freddi", "Freddi Fish 1: The Case of the Missing Kelp Seeds", GID_HEGAME, 6, 71, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 7.2
- {"airport", "Let's Explore the Airport with Buzzy", GID_HEGAME, 6, 72, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"puttzoo", "Putt-Putt Saves the Zoo", GID_HEGAME, 6, 72, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Changed o_getResourceSize to cover all resource types
- {"farm", "Let's Explore the Farm with Buzzy", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"jungle", "Let's Explore the Jungle with Buzzy", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 8.0 ? Scummsrc.80
- {"freddi2", "Freddi Fish 2: The Case of the Haunted Schoolhouse", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"pajama", "Pajama Sam 1: No Need to Hide When It's Dark Outside", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"putttime", "Putt-Putt Travels Through Time", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"balloon", "Putt-Putt and Pep's Balloon-O-Rama", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"dog", "Putt-Putt and Pep's Dog on a Stick", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"maze", "Freddi Fish and Luther's Maze Madness", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"socks", "Pajama Sam's Sock Works", GID_HEGAME, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"water", "Freddi Fish and Luther's Water Worries", GID_WATER, 6, 80, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 9.0 ? Scummsys.90
- {"baseball", "Backyard Baseball", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"thinkerk", "Big Thinkers Kindergarten", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"thinker1", "Big Thinkers First Grade", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"freddi3", "Freddi Fish 3: The Case of the Stolen Conch Shell", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"spyfox", "Spy Fox 1: Dry Cereal", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 9.5 ? Scummsys.95
- {"pajama2", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening", GID_HEGAME, 6, 95, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"chase", "Spy Fox in Cheese Chase", GID_HEGAME, 6, 95, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 9.8 ? Scummsys.98
- // these and later games can easily be identified by the .(a) file instead of a .he1
- // and INIB chunk in the .he0
- {"lost", "Pajama Sam's Lost & Found", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_CURSORLESS, Common::kPlatformWindows},
- {"puttrace", "Putt-Putt Enters the Race", GID_PUTTRACE, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"BluesABCTimeDemo", "Blue's ABC Time (Demo)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"soccer", "Backyard Soccer", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- // Global scripts increased to 2048
- {"freddi4", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
-
- // Humongous Entertainment Scumm Version 9.9 ? Scummsys.99
- {"football", "Backyard Football", GID_FOOTBALL, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"pajama3", "Pajama Sam 3: You Are What You Eat From Your Head to Your Feet", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
- {"puttcircus", "Putt-Putt Joins the Circus", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
- {"spyfox2", "Spy Fox 2: Some Assembly Required", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
- {"mustard", "Spy Fox in Hold the Mustard", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
-
- // Added the use of fonts
- {"FreddisFunShop", "Freddi Fish's One-Stop Fun Shop", GID_FUNSHOP, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
- {"SamsFunShop", "Pajama Sam's One-Stop Fun Shop", GID_FUNSHOP, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
- {"PuttsFunShop", "Putt-Putt's One-Stop Fun Shop", GID_FUNSHOP, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, Common::kPlatformWindows},
-
- // Added 16bit color
- {"baseball2001", "Backyard Baseball 2001", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"SoccerMLS", "Backyard Soccer MLS Edition", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"freddicove", "Freddi Fish 5: The Case of the Creature of Coral Cave", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED | GF_HE_NOSUBTITLES | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"spyozon", "Spy Fox 3: Operation Ozone", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows},
-
- // Restructured the Scumm engine
- {"pjgames", "Pajama Sam: Games to Play On Any Day", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows},
-
- // Uses bink in external files for logos
- {"Baseball2003", "Backyard Baseball 2003", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"basketball", "Backyard Basketball", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"Soccer2004", "Backyard Soccer 2004", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, Common::kPlatformWindows},
-
- // Uses smacker in external files, for testing only
- {"BluesBirthdayDemo", "Blue's Birthday Adventure (Demo)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"artdemo", "Blue's Art Time Activities (Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"readdemo", "Blue's Reading Time Activities (Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, Common::kPlatformWindows},
-
-
-#endif
- {NULL, NULL, 0, 0, 0, MDT_NONE, 0, Common::kPlatformUnknown}
-};
-
-// This additional table is used for MD5-based search
-//
-// Use main table to specify default flags and this table to override defaults.
-//
-// Please, add new entries sorted alpabetically by string name
-static const ScummGameSettings multiple_versions_md5_settings[] = {
-#ifndef PALMOS_68K
- {"2e85f7aa054930c692a5b1bed1dfc295", "Backyard Football 2002 (Demo Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformUnknown}, // Football2002
-
- {"037385a953789190298494d92b89b3d0", "Humongous Interactive Catalog (Updated)", GID_HEGAME, 6, 72, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"8fec68383202d38c0d25e9e3b757c5df", "The Curse of Monkey Island (Demo)", GID_CMI, 8, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEFAULT_TO_1X_SCALER | GF_DEMO, Common::kPlatformWindows},
-
- {"362c1d281fb9899254cda66ad246c66a", "The Dig (Demo)", GID_DIG, 7, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, Common::kPlatformPC},
- {"cd9c05e755d7bf8e9b9590ad1ebe273e", "The Dig (Demo Mac)", GID_DIG, 7, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, Common::kPlatformMacintosh},
-
- {"179879b6e35c1ead0d93aab26db0951b", "Fatty Bear's Birthday Surprise (Windows)", GID_FBEAR, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"22c9eb04455440131ffc157aeb8d40a8", "Fatty Bear's Birthday Surprise (Windows Demo)", GID_FBEAR, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"cf8ef3a1fb483c5c4b1c584d1167b2c4", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Updated German)", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"df047cc4792150f601290357566d36a6", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Updated)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"746e88c172a5b7a1ae89ac0ee3ee681a", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Updated Russian)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"507bb360688dc4180fdf0d7597352a69", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Updated Swedish)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"0855496dde35356b1a9691e22ba84cdc", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Demo)", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"566165a7338fa11029e7c14d94fa70d0", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Demo)", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"cf4ef315214c7d8cdab6302cdb7e50db", "Freddi Fish 1: The Case of the Missing Kelp Seeds (German Demo)", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"c8aac5e3e701874e2fa4117896f9e1b1", "Freddi Fish 1: The Case of the Missing Kelp Seeds (Macintosh Demo)", GID_HEGAME, 6, 73, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"8ee63cafb1fe9d62aa0d5a23117e70e7", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // FreddiCHSH
- {"51305e929e330e24a75a0351c8f9975e", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"e41de1c2a15abbcdbf9977e2d7e8a340", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Updated Russian)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // FreddiCHSH
- {"d37c55388294b66e53e7ced3af88fa68", "Freddi Fish 2: The Case of the Haunted Schoolhouse (Demo Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // FFHSDemo
-
- {"83cedbe26aa8b58988e984e3d34cac8e", "Freddi Fish 3: The Case of the Stolen Conch Shell (Updated German)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"75bff95816b84672b877d22a911ab811", "Freddi Fish 3: The Case of the Stolen Conch Shell (Updated Russian)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"ed2b074bc3166087a747acb2a3c6abb0", "Freddi Fish 3: The Case of the Stolen Conch Shell (Updated German Demo)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows}, // Fritzi3demo
-
- {"07b810e37be7489263f7bc7627d4765d", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Unencrypted Russian)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
- {"b5298a5c15ffbe8b381d51ea4e26d35c", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Updated German)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"78bd5f036ea35a878b74e4f47941f784", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Updated Russian)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"16effd200aa6b8abe9c569c3e578814d", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Updated Dutch Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // ff4demo
- {"499c958affc394f2a3868f1eb568c3ee", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Updated Dutch Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // ff4demo
- {"ebd324dcf06a4c49e1ba5c231eee1060", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Updated Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"e03ed1474ec14de78359970e0457a820", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (Updated Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"688328c5bdc4c8ec4145688dfa077bf2", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch (German Demo)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // Ff4demo
-
- {"b8955d7d23b4972229060d1592489fef", "Freddi Fish 5: The Case of the Creature of Coral Cave (Updated Dutch)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows}, // FreddiDZZ
- {"4ce2d5b355964bbcb5e5ce73236ef868", "Freddi Fish 5: The Case of the Creature of Coral Cave (Updated Russian)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"21abe302e1b1e2b66d6f5c12e241ebfd", "Freddi Fish 5: The Case of the Creature of Coral Cave (Unencrypted Russian)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"45082a5c9f42ba14dacfe1fdeeba819d", "Freddi Fish 5: The Case of the Creature of Coral Cave (Updated Demo)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows},
- {"6b257bb2827dd894b8109a50a1a18b5a", "Freddi Fish 5: The Case of the Creature of Coral Cave (Updated Dutch Demo)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, Common::kPlatformWindows}, // FF5Demo
-
- {"4dbff3787aedcd96b0b325f2d92d7ad9", "Freddi Fish and Luther's Maze Madness (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"f1b0e0d587b85052de5534a3847e68fe", "Freddi Fish and Luther's Water Worries (Updated)", GID_WATER, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"9d7b67be003fea60be4dcbd193611936", "Full Throttle (Mac Demo)", GID_FT, 7, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, Common::kPlatformMacintosh},
- {"32a433dea56b86a55b59e4ff7d755711", "Full Throttle (PC Demo)", GID_FT, 7, 0, MDT_NONE,
- GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, Common::kPlatformPC},
-
- {"157367c3c21e0d03a0cba44361b4cf65", "Indiana Jones and the Last Crusade (AtariST)", GID_INDY3, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformAtariST},
- {"0f9c7a76657f0840b8f7ccb5bffeb9f4", "Indiana Jones and the Last Crusade (AtariST Fr)", GID_INDY3, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformAtariST},
- {"1dd7aa088e09f96d06818aa9a9deabe0", "Indiana Jones and the Last Crusade (Macintosh)", GID_INDY3, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformMacintosh},
-
- {"1875b90fade138c9253a8e967007031a", "Indiana Jones and the Last Crusade (VGA)", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC},
- {"399b217b0c8d65d0398076da486363a9", "Indiana Jones and the Last Crusade (VGA De)", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC},
- {"17b5d5e6af4ae89d62631641d66d5a05", "Indiana Jones and the Last Crusade (VGA It)", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC},
- {"3cce1913a3bc586b51a75c3892ff18dd", "Indiana Jones and the Last Crusade (VGA Ru)", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC},
-
- {"04687cdf7f975a89d2474929f7b80946", "Indiana Jones and the Last Crusade (FM-TOWNS)", GID_INDY3, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
- {"3a0c35f3c147b98a2bdf8d400cfc4ab5", "Indiana Jones and the Last Crusade (FM-TOWNS Jp)", GID_INDY3, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
-
- {"86c9902b7bec1a17926d4dae85beaa45", "Let's Explore the Airport with Buzzy (Demo)", GID_HEGAME, 6, 71, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"bf8b52fdd9a69c67f34e8e9fec72661c", "Let's Explore the Farm with Buzzy (Demo)", GID_HEGAME, 6, 71, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"8d479e36f35e80257dfc102cf4b8a912", "Let's Explore the Farm with Buzzy (Updated Demo)", GID_HEGAME, 6, 72, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"0557df19f046a84c2fdc63507c6616cb", "Let's Explore the Farm with Buzzy (Updated Dutch Demo)", GID_HEGAME, 6, 72, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"a0a7dea72003933b8b3f8b99b9f7ddeb", "Loom (AtariST)", GID_LOOM, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformAtariST},
- {"c24c490373aeb48fbd54caa8e7ae376d", "Loom (AtariST De)", GID_LOOM, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformAtariST},
- {"0e9b01430e31d9fcd94071d433bbc6bf", "Loom (AtariST Fr)", GID_LOOM, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformAtariST},
- {"6f0be328c64d689bb606d22a389e1b0f", "Loom (Macintosh)", GID_LOOM, 3, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformMacintosh},
-
- {"5d88b9d6a88e6f8e90cded9d01b7f082", "Loom (256 color CD version)", GID_LOOM, 4, 0, MDT_NONE,
- GF_SMALL_HEADER | GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
- {"c5d10e190d4b4d59114b824f2fdbd00e", "Loom (FM-TOWNS)", GID_LOOM, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
- {"31b8fda4c8c7413fa6b39997e776eba4", "Loom (FM-TOWNS Jp)", GID_LOOM, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
-
- {"3905799e081b80a61d4460b7b733c206", "Maniac Mansion (NES E)", GID_MANIAC, 1, 0, MDT_NONE,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES},
- {"81bbfa181184cb494e7a81dcfa94fbd9", "Maniac Mansion (NES F)", GID_MANIAC, 1, 0, MDT_NONE,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES},
- {"257f8c14d8c584f7ddd601bcb00920c7", "Maniac Mansion (NES G)", GID_MANIAC, 1, 0, MDT_NONE,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES},
- {"22d07d6c386c9c25aca5dac2a0c0d94b", "Maniac Mansion (NES SW)", GID_MANIAC, 1, 0, MDT_NONE,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES},
- {"d8d07efcb88f396bee0b402b10c3b1c9", "Maniac Mansion (NES U)", GID_MANIAC, 1, 0, MDT_NONE,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES},
- {"7f45ddd6dbfbf8f80c0c0efea4c295bc", "Maniac Mansion (v1)", GID_MANIAC, 1, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformPC},
-
- {"898eaa21f79cf8d4f08db856244689ff", "Pajama Sam: No Need To Hide When It's Dark Outside (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"a095e33061606d231ff37dca4c64c8ac", "Pajama Sam: No Need To Hide When It's Dark Outside (Updated German)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // PYJAMA
- {"37aed3f91c1ef959e0bd265f9b13781f", "Pajama Sam: No Need To Hide When It's Dark Outside (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // PajamaNHD
- {"d7ab7cd6105546016e6a0d46fb36b964", "Pajama Sam: No Need To Hide When It's Dark Outside (Updated Demo)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // PJSamDemo
-
- {"30ba1e825d4ad2b448143ae8df18482a", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening (Updated Dutch Demo)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows}, // Pjs2demo
- {"32709cbeeb3044b34129950860a83f14", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening (Updated Russian)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // PajamaTAL
- {"c6907d44f1166941d982864cd42cdc89", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening (Updated German)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // PyjamaDBMN
- {"4521138d15d1fd7649c31fb981746231", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening (Updated German Demo)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows}, // PJP2DEMO
-
- {"a2bb6aa0537402c1b3c2ea899ccef64b", "Pajama Sam's Lost & Found (Test)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_CURSORLESS, Common::kPlatformWindows},
- {"a561d2e2413cc1c71d5a1bf87bf493ea", "Pajama Sam's Lost & Found (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_CURSORLESS, Common::kPlatformWindows},
-
- {"055ffe4f47753e47594ac67823220c54", "Putt-Putt Enters the Race (German)", GID_PUTTRACE, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows}, // ToffRennen
- {"6af2419fe3db5c2fdb091ae4e5833770", "Putt-Putt Enters the Race (Dutch Demo)", GID_PUTTRACE, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows}, // 500demo
- {"aaa587701cde7e74692c68c1024b85eb", "Putt-Putt Enters the Race (Updated Dutch Demo)", GID_PUTTRACE, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
- {"663743c03ae0c007f3d665cf631c0e6b", "Putt-Putt Enters the Race (German Demo)", GID_PUTTRACE, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows}, // Rennen
- {"7c8100e360e8ef05f88069d4cfa0afd1", "Putt-Putt Enters the Race (UK Demo)", GID_PUTTRACE, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
-
- {"9c92eeaf517a31b7221ec2546ab669fd", "Putt-Putt Goes To The Moon (Windows)", GID_HEGAME, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"9c143c5905055d5df7a0f014ab379aee", "Putt-Putt Goes To The Moon (Windows Demo)", GID_HEGAME, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"0b3222aaa7efcf283eb621e0cefd26cc", "Putt-Putt Joins the Parade (Russian)", GID_HEGAME, 6, 60, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformWindows},
- {"31aa57f460a3d12429f0552a46a90b39", "Putt-Putt Joins the Parade (Demo)", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformPC},
- {"f40a7f495f59188ca57a9d1d50301bb6", "Putt-Putt Joins the Parade (Macintosh Demo)", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_MIDI,
- GF_USE_KEY, Common::kPlatformPC},
- {"6a30a07f353a75cdc602db27d73e1b42", "Putt-Putt Joins the Parade (Windows)", GID_HEGAME, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"37ff1b308999c4cca7319edfcc1280a0", "Putt-Putt Joins the Parade (Windows Demo)", GID_HEGAME, 6, 70, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"92e7727e67f5cd979d8a1070e4eb8cb3", "Putt-Putt Saves the Zoo (Updated)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
-
- {"2108d83dcf09f8adb4bc524669c8cf51", "Putt-Putt Travels Through Time (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"d4aac997e2f4e15341f0bfbf905419bd", "Putt-Putt Travels Through Time (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"7c980a1b1596a93f26917318884f48f7", "Putt-Putt Travels Through Time (Updated German)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"defb8cb9ec4b0f91acfb6b61c6129ad9", "Putt-Putt Travels Through Time (Updated Russian)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"a525c1753c1db5011c00417da37887ef", "Putt-Putt Travels Through Time (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"fcb78ebecab2757264c590890c319cc5", "Putt-Putt Travels Through Time (Updated Dutch)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"4e5867848ee61bc30d157e2c94eee9b4", "Putt-Putt Travels Through Time (Demo)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"6b19d0e25cbf720d05822379b8b90ed9", "Putt-Putt Travels Through Time (Dutch Demo)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"59d5cfcc5e672a6e07baae01328b918b", "Putt-Putt Travels Through Time (French Demo)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // TEMPDEMO
- {"fbb697d89d2beca87360a145f467bdae", "Putt-Putt Travels Through Time (Updated German Demo)", GID_HEGAME, 6, 90, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // ZEITDEMO
- {"0ab19be9e2a3f6938226638b2a3744fe", "Putt-Putt Travels Through Time (Updated Demo)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"d7b247c26bf1f01f8f7daf142be84de3", "Putt-Putt and Pep's Balloon-O-Rama (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"8e3241ddd6c8dadf64305e8740d45e13", "Putt-Putt and Pep's Balloon-O-Rama (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"d4b8ee426b1afd3e53bc0cf020418cf6", "Putt-Putt and Pep's Dog on a Stick (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"1d05cd189e4908f79b57e78a4402f292", "The Secret of Monkey Island (EGA)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"49210e124e4c2b30f1290a9ef6306301", "The Secret of Monkey Island (EGA)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"e98b982ceaf9d253d730bde8903233d6", "The Secret of Monkey Island (EGA De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"fc6b6148e80d67939d9a18697c0f626a", "The Secret of Monkey Island (EGA De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"ce6a4cef315b20fef58a95bc40a2d8d3", "The Secret of Monkey Island (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"aa7a07d94ae853f6460be4ce0a1bf530", "The Secret of Monkey Island (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"1dd3c11ea4439adfe681e4e405b624e1", "The Secret of Monkey Island (EGA Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"477dbafbd66a53c98416dc01aef019ad", "The Secret of Monkey Island (EGA It)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"910e31cffb28226bd68c569668a0d6b4", "The Secret of Monkey Island (EGA Sp)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"c666a998af90d81db447eccba9f72c8d", "The Secret of Monkey Island (Atari)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformAtariST},
- {"927a764615c7fcdd72f591355e089d8c", "The Secret of Monkey Island (Atari De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformAtariST},
- {"9e5e0fb43bd22f4628719b7501adb717", "The Secret of Monkey Island (Atari Fr)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformAtariST},
- {"0a41311d462b6639fc45297b9044bf16", "The Secret of Monkey Island (Atari Sp)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformAtariST},
- {"71523b539491527d9860f4407faf0411", "The Secret of Monkey Island (Demo)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
- {"771bc18ec6f93837b839c992b211904b", "The Secret of Monkey Island (Demo De)", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
-
- {"2d1e891fe52df707c30185e52c50cd92", "The Secret of Monkey Island (CD)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
- {"305d3dd57c96c65b017bc70c8c7cfb5e", "The Secret of Monkey Island (CD De)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
- {"f049e38c1f8302b5db6170f1872af89a", "The Secret of Monkey Island (CD Sp)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
- {"da6269b18fcb08189c0aa9c95533cce2", "The Secret of Monkey Island (CD It)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
- {"aa8a0cb65f3afbbe2c14c3f9f92775a3", "The Secret of Monkey Island (CD Fr)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
- {"2ccd8891ce4d3f1a334d21bff6a88ca2", "The Secret of Monkey Island (Mac CD)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformMacintosh},
-
- {"8eb84cee9b429314c7f0bdcf560723eb", "The Secret of Monkey Island (FM-TOWNS)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
-
- {"e17db1ddf91b39ca6bbc8ad3ed19e883", "The Secret of Monkey Island (FM-TOWNS Jp)", GID_MONKEY, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
-
- {"c13225cb1bbd3bc9fe578301696d8021", "The Secret of Monkey Island (SegaCD)", GID_MONKEY, 5, 0, MDT_NONE,
- GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformSegaCD},
-
- {"3de99ef0523f8ca7958faa3afccd035a", "Spy Fox 1: Dry Cereal (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"58436e634f4fae1d9973591c2ffa1fcb", "Spy Fox 1: Dry Cereal (Updated)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"9bda5fee51d2fda5253d02c642016bf4", "Spy Fox 1: Dry Cereal (Updated Dutch)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
- {"a28135a7ade38cc0208b04507c46efd1", "Spy Fox 1: Dry Cereal (Updated German)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"72ac6bc980d5101c2142189d746bd62f", "Spy Fox 1: Dry Cereal (Updated Russian)", GID_HEGAME, 6, 99, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows}, // SPYFoxDC
- {"9d4ab3e0e1d1ebc6ba8a6a4c470ed184", "Spy Fox 1: Dry Cereal (Updated Demo)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
- {"4edbf9d03550f7ba01e7f34d69b678dd", "Spy Fox 1: Dry Cereal (Updated Dutch Demo)", GID_HEGAME, 6, 98, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, Common::kPlatformWindows},
-
- {"90c755e1c9b9b8a4129d37b2259d0655", "Spy Fox in Cheese Chase (Updated)", GID_HEGAME, 6, 100, MDT_NONE,
- GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
-
- {"b23f7cd7c304d7dff08e92a96120d5b4", "Zak McKracken and the Alien Mindbenders (v1)", GID_ZAK, 1, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformPC},
- {"7020931d5a2be0a49d68e7a1882363e4", "Zak McKracken and the Alien Mindbenders (v1)", GID_ZAK, 1, 0, MDT_PCSPK,
- GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformPC},
-
- {"2d4536a56e01da4b02eb021e7770afa2", "Zak McKracken and the Alien Mindbenders (FM-TOWNS)", GID_ZAK, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
- {"1ca86e2cf9aaa2068738a1e5ba477e60", "Zak McKracken and the Alien Mindbenders (FM-TOWNS Jp)", GID_ZAK, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
-
- {"2d388339d6050d8ccaa757b64633954e", "Indy/Loom Demo (FM-TOWNS)", GID_ZAK, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
- {"77f5c9cc0986eb729c1a6b4c8823bbae", "Zak/Loom Demo (FM-TOWNS)", GID_ZAK, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
- {"3938ee1aa4433fca9d9308c9891172b1", "Indy/Zak Demo (FM-TOWNS)", GID_ZAK, 3, 0, MDT_TOWNS,
- GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
-#endif
- {NULL, NULL, 0, 0, MDT_NONE, 0, 0, Common::kPlatformUnknown}
-};
-
-enum genMethods {
- kGenMac,
- kGenMacNoParens,
- kGenPC,
- kGenAsIs
-};
-
-struct SubstResFileNames {
- const char *winName;
- const char *macName;
- int genMethod;
-};
-
-static SubstResFileNames substResFileNameTable[] = {
- { "Intentionally/left/blank", "", kGenMacNoParens },
- { "00.LFL", "Maniac Mansion (E).prg", kGenAsIs },
- { "00.LFL", "Maniac Mansion (F).prg", kGenAsIs },
- { "00.LFL", "Maniac Mansion (SW).prg", kGenAsIs },
- { "00.LFL", "Maniac Mansion (U).prg", kGenAsIs },
- { "00.LFL", "Maniac Mansion (G).prg", kGenAsIs },
- { "00.LFL", "maniac1.d64", kGenAsIs }, // Do not
- { "01.LFL", "maniac2.d64", kGenAsIs }, // swap
- { "00.LFL", "zak1.d64", kGenAsIs }, // these
- { "01.LFL", "zak2.d64", kGenAsIs }, // lines
- { "atlantis.000", "Fate of Atlantis Data", kGenAsIs },
- { "atlantis", "fate", kGenPC },
- { "atlantis", "playfate", kGenPC },
- { "atlantis", "indy4", kGenPC },
- { "atlantis", "indydemo", kGenPC },
- { "tentacle.000", "Day of the Tentacle Data", kGenAsIs },
- { "tentacle", "dottdemo", kGenPC },
- { "tentacle.000", "Day of the Tentacle Demo Data", kGenAsIs },
- { "monkey", "monkey1", kGenPC },
- { "monkey", "monkeyk", kGenPC }, // FM-TOWNS Jap
- { "monkey", "game", kGenPC }, // SegaCD
- { "monkey2", "mi2demo", kGenPC },
- { "samnmax.000", "Sam & Max Data", kGenAsIs },
- { "samnmax.000", "Sam & Max Demo Data", kGenAsIs },
- { "samnmax", "ramnmax", kGenPC }, // Used in some releases of Russian Sam'n'Max
- { "samnmax", "samdemo", kGenPC },
- { "samnmax", "snmdemo", kGenPC },
- { "samnmax", "snmidemo", kGenPC },
- { "samnmax", "sdemo", kGenPC },
-#ifndef DISABLE_SCUMM_7_8
- { "dig.la0", "The Dig Data", kGenAsIs },
- { "dig.la0", "The Dig Demo Data", kGenAsIs },
- { "ft.la0", "Full Throttle Data", kGenAsIs },
- { "ft.la0", "Full Throttle Demo Data", kGenAsIs },
- { "ft.la0", "Vollgas Data", kGenAsIs },
- { "ft.la0", "Vollgas Demo Data", kGenAsIs },
- { "ft", "ftdemo", kGenPC },
-#endif
- { "fbear", "fbdemo", kGenPC },
- { "fbear", "Fatty Bear Demo", kGenMacNoParens },
- { "fbear", "Fatty Bear", kGenMacNoParens },
- { "puttmoon", "moondemo", kGenPC },
- { "puttmoon", "Putt-Putt Moon Demo", kGenMacNoParens },
- { "puttmoon", "Putt-Putt Moon", kGenMacNoParens },
- { "puttputt", "puttdemo", kGenPC },
- { "puttputt", "Putt-Putt's Demo", kGenMacNoParens },
- { "puttputt", "Putt-Putt Parade", kGenMacNoParens },
-#ifndef DISABLE_HE
- { "airport", "airdemo", kGenPC },
- { "airport", "Airport Demo", kGenMac },
- { "airport", "The AirPort", kGenMac },
- { "balloon", "Balloon-O-Rama", kGenMac },
- { "baseball", "BaseBall", kGenMac },
- { "baseball2001", "bb2demo", kGenPC },
- { "baseball2001", "Baseball 2001 Demo", kGenMac },
- { "baseball2001", "Baseball 2001", kGenMac },
- { "baseball2001", "baseball 2001", kGenPC },
- { "Baseball2003", "Baseball 2003", kGenMac },
- { "basketball", "Basketball", kGenMac },
- { "BluesABCTimeDemo", "BluesABCTimeDemo", kGenMac },
- { "catalog", "catalog2", kGenPC },
- { "chase", "Cheese Chase", kGenMac },
- { "dog", "Dog on a Stick", kGenMac },
- { "farm", "farmdemo", kGenPC },
- { "farm", "Farm Demo", kGenMac },
- { "football", "FootBall", kGenMac },
- { "football", "FootBall Demo", kGenMac },
- { "football", "FootBall2002", kGenPC },
- { "football", "footdemo", kGenPC },
- { "freddi", "freddemo", kGenPC },
- { "freddi", "Freddi Demo", kGenMac },
- { "freddi", "Freddi Fish", kGenMac },
- { "freddi", "FreddiD", kGenPC },
- { "freddi2", "ff2-demo", kGenPC },
- { "freddi2", "FFHSDemo", kGenMac },
- { "freddi2", "FFHSDemo", kGenPC },
- { "freddi2", "Freddi Fish 2 Demo", kGenMac },
- { "freddi2", "Freddi Fish 2", kGenMac },
- { "freddi2", "FreddiCHSH", kGenPC },
- { "freddi2", "Fritzi Fisch 2", kGenMac },
- { "freddi3", "F3-mdemo", kGenMac },
- { "freddi3", "F3-Mdemo", kGenMac },
- { "freddi3", "f3-mdemo", kGenPC },
- { "freddi3", "FF3-DEMO", kGenPC },
- { "freddi3", "Freddi Fish 3", kGenMac },
- { "freddi3", "FreddiFGT", kGenPC },
- { "freddi3", "FreddiFGT", kGenMac },
- { "freddi3", "FreddiSCS", kGenPC },
- { "freddi3", "Fritzi3demo", kGenMac },
- { "freddi3", "Fritzi3demo", kGenPC },
- { "freddi3", "MM3-DEMO", kGenPC },
- { "freddi3", "MM3-Demo", kGenMac }, // FR Mac demo
- { "freddi4", "f4-demo", kGenPC },
- { "freddi4", "ff4demo", kGenPC },
- { "freddi4", "Ff4demo", kGenMac },
- { "freddi4", "Freddi 4", kGenMac },
- { "freddi4", "Freddi 4 Demo", kGenMac },
- { "freddi4", "FreddiGS", kGenPC },
- { "freddi4", "FreddiGS", kGenMac },
- { "freddi4", "FreddiHRBG", kGenPC },
- { "freddicove", "FreddiCCC", kGenPC },
- { "freddicove", "FreddiCove", kGenMac },
- { "freddicove", "FreddiDZZ", kGenPC },
- { "freddicove", "ff5demo", kGenPC },
- { "freddicove", "FFCoveDemo", kGenPC },
- { "freddicove", "FreddiCoveDemo", kGenMac },
- { "freddicove", "FF5Demo", kGenMac }, // NL Mac demo
- { "FreddisFunShop", "Freddi's FunShop", kGenMac },
- { "jungle", "The Jungle", kGenMac },
- { "lost", "Lost and Found", kGenMac },
- { "lost", "smaller", kGenPC },
- { "maze", "Maze Madness", kGenMac},
- { "mustard", "Mustard", kGenMac },
- { "pajama", "Pyjama Pit", kGenMac },
- { "pajama", "Pajama Sam", kGenMac },
- { "pajama", "PajamaNHD", kGenPC },
- { "pajama", "PJS-DEMO", kGenPC },
- { "pajama", "PYJAMA", kGenPC },
- { "pajama", "SAMDEMO", kGenPC },
- { "pajama", "SAMDEMO", kGenMac }, // FR Mac demo
- { "pajama2", "Pajama Sam 2", kGenMac },
- { "pajama2", "PajamaTAL", kGenPC },
- { "pajama2", "PyjamaDBMN", kGenPC },
- { "pajama2", "PyjamaDBMN", kGenMac },
- { "pajama2", "Pyjama Pit 2 Demo", kGenMac },
- { "pajama2", "PJP2DEMO", kGenPC },
- { "pajama2", "PJ2Demo", kGenMac },
- { "pajama2", "pj2demo", kGenPC },
- { "pajama2", "Pjs2demo", kGenPC },
- { "pajama2", "PJ2 Demo", kGenMac }, // NL Mac demo
- { "pajama3", "GPJ3Demo", kGenPC },
- { "pajama3", "Pajama Sam 3", kGenMac },
- { "pajama3", "Pajama Sam 3-Demo", kGenMac },
- { "pajama3", "pj3-demo", kGenPC },
- { "pajama3", "pj3demo", kGenPC },
- { "pajama3", "PJ3Demo", kGenMac },
- { "pajama3", "Pajama Sam Demo", kGenMac },
- { "pajama3", "PjSamDemo", kGenMac },
- { "pajama3", "PjSamDemo", kGenPC },
- { "pajama3", "PyjamaSKS", kGenPC },
- { "pajama3", "PyjamaSKS", kGenMac },
- { "pjgames", "PJGames", kGenMac },
- { "puttcircus", "circdemo", kGenPC },
- { "puttcircus", "Putt Circus Demo", kGenMac },
- { "puttcircus", "Putt Circus", kGenMac },
- { "puttrace", "500demo", kGenPC },
- { "puttrace", "racedemo", kGenPC },
- { "puttrace", "RaceDemo", kGenMac },
- { "puttrace", "Rennen", kGenPC },
- { "puttrace", "Putt500 demo", kGenMac }, // NL Mac demo
- { "puttrace", "Putt Race", kGenMac },
- { "puttrace", "ToffRennen", kGenPC },
- { "puttrace", "ToffRennen", kGenMac },
- { "PuttsFunShop", "Putt's FunShop", kGenMac },
- { "putttime", "PuttPuttTTT", kGenPC },
- { "putttime", "PuttPuttTTT", kGenMac },
- { "putttime", "PuttTijd", kGenPC },
- { "putttime", "Putt Time", kGenMac },
- { "putttime", "PuttTTT", kGenMac },
- { "putttime", "PuttTTT", kGenPC },
- { "putttime", "TIJDDEMO", kGenPC },
- { "putttime", "timedemo", kGenPC },
- { "putttime", "TimeDemo", kGenMac },
- { "putttime", "TEMPDEMO", kGenPC },
- { "putttime", "Tempdemo", kGenMac }, // FR Mac demo
- { "putttime", "toffzeit", kGenPC }, // German T’¨¢öff-T’¨¢öff: Reist durch die Zeit
- { "putttime", "toffzeit", kGenMac }, // German T’¨¢öff-T’¨¢öff: Reist durch die Zeit
- { "putttime", "ZeitDemo", kGenMac },
- { "putttime", "ZEITDEMO", kGenPC },
- { "puttzoo", "Puttzoo Demo", kGenMac },
- { "puttzoo", "PuttZoo", kGenMac },
- { "puttzoo", "zoodemo", kGenPC },
- { "puttzoo", "Zoo Demo", kGenMac },
- { "SamsFunShop", "Sam's FunShop", kGenMac },
- { "soccer", "Soccer", kGenMac },
- { "Soccer2004", "Soccer 2004", kGenMac },
- { "socks", "SockWorks", kGenMac },
- { "spyfox", "Fuchsdem", kGenMac },
- { "spyfox", "FUCHSDEM", kGenPC},
- { "spyfox", "FoxDemo", kGenMac },
- { "spyfox", "foxdemo", kGenPC},
- { "spyfox", "JAMESDEM", kGenPC },
- { "spyfox", "Spydemo", kGenMac},
- { "spyfox", "Spydemo", kGenPC},
- { "spyfox", "SPYFox", kGenMac },
- { "spyfox", "SPYFoxDC", kGenPC },
- { "spyfox", "SPYFoxDC", kGenMac },
- { "spyfox", "SpyFoxDMK", kGenPC },
- { "spyfox", "SpyFoxDMK", kGenMac },
- { "spyfox", "Spy Fox Demo", kGenMac }, // NL Mac demo
- { "spyfox", "JR-Demo", kGenMac }, // FR Mac demo
- { "spyfox2", "sf2-demo", kGenPC },
- { "spyfox2", "sf2demo", kGenPC },
- { "spyfox2", "Sf2demo", kGenMac },
- { "spyfox2", "Spy Fox 2 - Demo", kGenMac },
- { "spyfox2", "Spy Fox 2", kGenMac },
- { "spyfox2", "SpyFoxOR", kGenPC },
- { "spyfox2", "SpyFoxOR", kGenMac },
- { "spyfox2", "spyfoxsr", kGenPC },
- { "spyozon", "sf3-demo", kGenPC },
- { "spyozon", "Spy Ozone Demo", kGenMac },
- { "spyozon", "SPYFoxOZU", kGenPC },
- { "spyozon", "SpyOzon", kGenMac },
- { "thinker1", "1grademo", kGenPC },
- { "thinker1", "Thinker1", kGenMac },
- { "thinkerk", "kinddemo", kGenPC },
- { "thinkerk", "KindDemo", kGenMac },
- { "thinkerk", "ThinkerK", kGenMac },
- { "water", "Water Worries", kGenMac },
-#endif
- { NULL, NULL, 0 }
-};
-
-static int compareMD5Table(const void *a, const void *b) {
- const char *key = (const char *)a;
- const MD5Table *elem = (const MD5Table *)b;
- return strcmp(key, elem->md5);
-}
-
-ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : Engine(syst),
- _gameId(gs.id),
- _version(gs.version),
- _heversion(gs.heversion),
- _features(gs.features),
- _platform(gs.platform),
- _midi(gs.midi),
- _substResFileNameIndex(substResFileNameIndex),
- _substResFileNameIndexBundle(0),
- _debugger(0),
- _currentScript(0xFF), // Let debug() work on init stage
- gdi(this),
- res(this),
- _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0),
- _targetName(detector->_targetName) {
-
- // Copy MD5 checksum
- memcpy(_gameMD5, md5sum, 16);
-
- // Check for unknown MD5
- char md5str[32+1];
- for (int j = 0; j < 16; j++) {
- sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
- }
- const MD5Table *elem;
-#ifdef PALMOS_68K
- uint32 arraySize = MemPtrSize((void *)md5table) / sizeof(MD5Table) - 1;
-#else
- uint32 arraySize = ARRAYSIZE(md5table) - 1;
-#endif
- elem = (const MD5Table *)bsearch(md5str, md5table, arraySize, sizeof(MD5Table), compareMD5Table);
- if (!elem)
- printf("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str);
-
- if (_gameId == GID_FT) {
- // WORKAROUND for bug #1407789. See checkAndRunSentenceScript()
- // for the actual workaround.
-
- // FIXME: We do not yet have all necessary information, but the
- // following is known:
- //
- // * The US PC version uses scripts 28 and 103.
- // * The French PC version uses scripts 29 and 104.
- // * The German, Italian, Portuguese and Spanish PC versions
- // use script 29. The other script is not currently known.
- // * The US Mac demo uses script 28.
- //
- // For now, assume that the PC and Mac versions are the same,
- // that all localized versions use scripts 29 and 104, and that
- // any completely unknown version is localized.
-
- if (elem && elem->language == Common::EN_USA) {
- _defaultFTSentenceScript = 28;
- _buggyFTSentenceScript = 103;
- } else {
- _defaultFTSentenceScript = 29;
- _buggyFTSentenceScript = 104;
- }
- }
-
- // Add default file directories.
- if (((_platform == Common::kPlatformAmiga) || (_platform == Common::kPlatformAtariST)) && (_version <= 4)) {
- // This is for the Amiga version of Indy3/Loom/Maniac/Zak
- File::addDefaultDirectory(_gameDataPath + "ROOMS/");
- File::addDefaultDirectory(_gameDataPath + "rooms/");
- }
-
- if ((_platform == Common::kPlatformMacintosh) && (_version == 3)) {
- // This is for the Mac version of Indy3/Loom
- File::addDefaultDirectory(_gameDataPath + "Rooms 1/");
- File::addDefaultDirectory(_gameDataPath + "Rooms 2/");
- File::addDefaultDirectory(_gameDataPath + "Rooms 3/");
- }
-
-#ifndef DISABLE_SCUMM_7_8
-#ifdef MACOSX
- if (_version == 8 && !memcmp(_gameDataPath.c_str(), "/Volumes/MONKEY3_", 17)) {
- // Special case for COMI on Mac OS X. The mount points on OS X depend
- // on the volume name. Hence if playing from CD, we'd get a problem.
- // So if loading of a resource file fails, we fall back to the (fixed)
- // CD mount points (/Volumes/MONKEY3_1 and /Volumes/MONKEY3_2).
- //
- // This check for whether we play from CD is very crude, though.
-
- File::addDefaultDirectory("/Volumes/MONKEY3_1/RESOURCE/");
- File::addDefaultDirectory("/Volumes/MONKEY3_1/resource/");
- File::addDefaultDirectory("/Volumes/MONKEY3_2/");
- File::addDefaultDirectory("/Volumes/MONKEY3_2/RESOURCE/");
- File::addDefaultDirectory("/Volumes/MONKEY3_2/resource/");
- } else
-#endif
- if (_version == 8) {
- // This is for COMI
- File::addDefaultDirectory(_gameDataPath + "RESOURCE/");
- File::addDefaultDirectory(_gameDataPath + "resource/");
- }
-
- if (_version == 7) {
- // This is for Full Throttle & The Dig
- File::addDefaultDirectory(_gameDataPath + "VIDEO/");
- File::addDefaultDirectory(_gameDataPath + "video/");
- File::addDefaultDirectory(_gameDataPath + "DATA/");
- File::addDefaultDirectory(_gameDataPath + "data/");
- }
-#endif
-
- // We read data directly from NES ROM instead of extracting it with
- // external tool
- if ((_platform == Common::kPlatformNES) && _substResFileNameIndex) {
- char tmpBuf[128];
- generateSubstResFileName("00.LFL", tmpBuf, sizeof(tmpBuf));
- _fileHandle = new ScummNESFile();
- _containerFile = tmpBuf;
- } else if ((_platform == Common::kPlatformC64) && _substResFileNameIndex) {
- char tmpBuf1[128], tmpBuf2[128];
- generateSubstResFileName("00.LFL", tmpBuf1, sizeof(tmpBuf1));
- generateSubstResFileName("01.LFL", tmpBuf2, sizeof(tmpBuf2));
-
- _fileHandle = new ScummC64File(tmpBuf1, tmpBuf2, _gameId == GID_MANIAC);
-
- _containerFile = tmpBuf1;
- } else
- _fileHandle = new ScummFile();
-
- // The mac versions of Indy4, Sam&Max, DOTT, FT and The Dig used a
- // special meta (container) file format to store the actual SCUMM data
- // files. The rescumm utility used to be used to extract those files.
- // While that is still possible, we now support reading those files
- // directly. The first step is to check whether one of them is present
- // (we do that here); the rest is handled by the ScummFile class and
- // code in openResourceFile() (and in the Sound class, for MONSTER.SOU
- // handling).
- if (_version >= 5 && _heversion == 0 && _substResFileNameIndex &&
- _platform == Common::kPlatformMacintosh &&
- substResFileNameTable[_substResFileNameIndex].genMethod == kGenAsIs) {
- if (_fileHandle->open(substResFileNameTable[_substResFileNameIndex].macName)) {
- _containerFile = substResFileNameTable[_substResFileNameIndex].macName;
- _substResFileNameIndex = 0;
- }
- }
-
- // Init all vars
- _imuse = NULL;
- _imuseDigital = NULL;
- _musicEngine = NULL;
- _verbs = NULL;
- _objs = NULL;
- _storedFlObjects = NULL;
- _debugFlags = 0;
- _sound = NULL;
- memset(&vm, 0, sizeof(vm));
- _smushVideoShouldFinish = false;
- _smushPaused = false;
- _insaneRunning = false;
- _quit = false;
- _pauseDialog = NULL;
- _mainMenuDialog = NULL;
- _versionDialog = NULL;
- _fastMode = 0;
- _actors = NULL;
- _arraySlot = NULL;
- _inventory = NULL;
- _newNames = NULL;
- _scummVars = NULL;
- _roomVars = NULL;
- _varwatch = 0;
- _bitVars = NULL;
- _numVariables = 0;
- _numBitVariables = 0;
- _numRoomVariables = 0;
- _numLocalObjects = 0;
- _numGlobalObjects = 0;
- _numStoredFlObjects = 0;
- _numArray = 0;
- _numVerbs = 0;
- _numFlObject = 0;
- _numInventory = 0;
- _numRooms = 0;
- _numScripts = 0;
- _numSounds = 0;
- _numCharsets = 0;
- _numNewNames = 0;
- _numGlobalScripts = 0;
- _numCostumes = 0;
- _numImages = 0;
- _numLocalScripts = 60;
- _numSprites = 0;
- _numTalkies = 0;
- _numPalettes = 0;
- _numUnk = 0;
- _curActor = 0;
- _curVerb = 0;
- _curVerbSlot = 0;
- _curPalIndex = 0;
- _currentRoom = 0;
- _egoPositioned = false;
- _keyPressed = 0;
- _lastKeyHit = 0;
- _mouseAndKeyboardStat = 0;
- _leftBtnPressed = 0;
- _rightBtnPressed = 0;
- _bootParam = 0;
- _dumpScripts = false;
- _debugMode = 0;
- _heV7DiskOffsets = NULL;
- _heV7RoomIntOffsets = NULL;
- _objectOwnerTable = NULL;
- _objectRoomTable = NULL;
- _objectStateTable = NULL;
- _numObjectsInRoom = 0;
- _userPut = 0;
- _userState = 0;
- _activeObject = 0;
- _resourceHeaderSize = 8;
- _saveLoadFlag = 0;
- _saveLoadSlot = 0;
- _lastSaveTime = 0;
- _saveTemporaryState = false;
- memset(_saveLoadName, 0, sizeof(_saveLoadName));
- memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets));
- _scriptPointer = NULL;
- _scriptOrgPointer = NULL;
- _opcode = 0;
- vm.numNestedScripts = 0;
- _lastCodePtr = NULL;
- _resultVarNumber = 0;
- _scummStackPos = 0;
- memset(_vmStack, 0, sizeof(_vmStack));
- _keyScriptKey = 0;
- _keyScriptNo = 0;
- _fileOffset = 0;
- memset(_resourceMapper, 0, sizeof(_resourceMapper));
- _lastLoadedRoom = 0;
- _roomResource = 0;
- OF_OWNER_ROOM = 0;
- _verbMouseOver = 0;
- _inventoryOffset = 0;
- _classData = NULL;
- _actorToPrintStrFor = 0;
- _sentenceNum = 0;
- memset(_sentence, 0, sizeof(_sentence));
- memset(_string, 0, sizeof(_string));
- _screenB = 0;
- _screenH = 0;
- _roomHeight = 0;
- _roomWidth = 0;
- _screenHeight = 0;
- _screenWidth = 0;
- memset(virtscr, 0, sizeof(virtscr));
- memset(&camera, 0, sizeof(CameraData));
- memset(_colorCycle, 0, sizeof(_colorCycle));
- memset(_colorUsedByCycle, 0, sizeof(_colorUsedByCycle));
- _ENCD_offs = 0;
- _EXCD_offs = 0;
- _CLUT_offs = 0;
- _EPAL_offs = 0;
- _IM00_offs = 0;
- _PALS_offs = 0;
- _fullRedraw = false;
- _bgNeedsRedraw = false;
- _screenEffectFlag = false;
- _completeScreenRedraw = false;
- memset(&_cursor, 0, sizeof(_cursor));
- memset(_grabbedCursor, 0, sizeof(_grabbedCursor));
- _currentCursor = 0;
- _newEffect = 0;
- _switchRoomEffect2 = 0;
- _switchRoomEffect = 0;
- _scrollBuffer = NULL;
-
- _doEffect = false;
- memset(&_flashlight, 0, sizeof(_flashlight));
- _bompActorPalettePtr = NULL;
- _shakeEnabled = false;
- _shakeFrame = 0;
- _screenStartStrip = 0;
- _screenEndStrip = 0;
- _screenTop = 0;
- _drawObjectQueNr = 0;
- memset(_drawObjectQue, 0, sizeof(_drawObjectQue));
- _palManipStart = 0;
- _palManipEnd = 0;
- _palManipCounter = 0;
- _palManipPalette = NULL;
- _palManipIntermediatePal = NULL;
- memset(gfxUsageBits, 0, sizeof(gfxUsageBits));
- _hePalettes = NULL;
- _shadowPalette = NULL;
- _shadowPaletteSize = 0;
- memset(_currentPalette, 0, sizeof(_currentPalette));
- memset(_darkenPalette, 0, sizeof(_darkenPalette));
- memset(_HEV7ActorPalette, 0, sizeof(_HEV7ActorPalette));
- _palDirtyMin = 0;
- _palDirtyMax = 0;
- _haveMsg = 0;
- _haveActorSpeechMsg = false;
- _useTalkAnims = false;
- _defaultTalkDelay = 0;
- _musicType = MDT_NONE;
- _tempMusic = 0;
- _saveSound = 0;
- memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));
- memset(_scaleSlots, 0, sizeof(_scaleSlots));
- _charset = NULL;
- _charsetColor = 0;
- memset(_charsetColorMap, 0, sizeof(_charsetColorMap));
- memset(_charsetData, 0, sizeof(_charsetData));
- _charsetBufPos = 0;
- memset(_charsetBuffer, 0, sizeof(_charsetBuffer));
- _copyProtection = false;
- _demoMode = false;
- _confirmExit = false;
- _voiceMode = 0;
- _talkDelay = 0;
- _NES_lastTalkingActor = 0;
- _NES_talkColor = 0;
- _keepText = false;
- _costumeLoader = NULL;
- _costumeRenderer = NULL;
- _2byteFontPtr = 0;
- _V1TalkingActor = 0;
- _NESStartStrip = 0;
-
- _actorClipOverride.top = 0;
- _actorClipOverride.bottom = 480;
- _actorClipOverride.left = 0;
- _actorClipOverride.right = 640;
-
- _skipDrawObject = 0;
- memset(_heTimers, 0, sizeof(_heTimers));
-
- memset(_akosQueue, 0, sizeof(_akosQueue));
- _akosQueuePos = 0;
-
- //
- // Init all VARS to 0xFF
- //
- VAR_LANGUAGE = 0xFF;
- VAR_KEYPRESS = 0xFF;
- VAR_SYNC = 0xFF;
- VAR_EGO = 0xFF;
- VAR_CAMERA_POS_X = 0xFF;
- VAR_HAVE_MSG = 0xFF;
- VAR_ROOM = 0xFF;
- VAR_OVERRIDE = 0xFF;
- VAR_MACHINE_SPEED = 0xFF;
- VAR_ME = 0xFF;
- VAR_NUM_ACTOR = 0xFF;
- VAR_CURRENT_LIGHTS = 0xFF;
- VAR_CURRENTDRIVE = 0xFF; // How about merging this with VAR_CURRENTDISK?
- VAR_CURRENTDISK = 0xFF;
- VAR_TMR_1 = 0xFF;
- VAR_TMR_2 = 0xFF;
- VAR_TMR_3 = 0xFF;
- VAR_MUSIC_TIMER = 0xFF;
- VAR_ACTOR_RANGE_MIN = 0xFF;
- VAR_ACTOR_RANGE_MAX = 0xFF;
- VAR_CAMERA_MIN_X = 0xFF;
- VAR_CAMERA_MAX_X = 0xFF;
- VAR_TIMER_NEXT = 0xFF;
- VAR_VIRT_MOUSE_X = 0xFF;
- VAR_VIRT_MOUSE_Y = 0xFF;
- VAR_ROOM_RESOURCE = 0xFF;
- VAR_LAST_SOUND = 0xFF;
- VAR_CUTSCENEEXIT_KEY = 0xFF;
- VAR_OPTIONS_KEY = 0xFF;
- VAR_TALK_ACTOR = 0xFF;
- VAR_CAMERA_FAST_X = 0xFF;
- VAR_SCROLL_SCRIPT = 0xFF;
- VAR_ENTRY_SCRIPT = 0xFF;
- VAR_ENTRY_SCRIPT2 = 0xFF;
- VAR_EXIT_SCRIPT = 0xFF;
- VAR_EXIT_SCRIPT2 = 0xFF;
- VAR_VERB_SCRIPT = 0xFF;
- VAR_SENTENCE_SCRIPT = 0xFF;
- VAR_INVENTORY_SCRIPT = 0xFF;
- VAR_CUTSCENE_START_SCRIPT = 0xFF;
- VAR_CUTSCENE_END_SCRIPT = 0xFF;
- VAR_CHARINC = 0xFF;
- VAR_CHARCOUNT = 0xFF;
- VAR_WALKTO_OBJ = 0xFF;
- VAR_DEBUGMODE = 0xFF;
- VAR_HEAPSPACE = 0xFF;
- VAR_RESTART_KEY = 0xFF;
- VAR_PAUSE_KEY = 0xFF;
- VAR_MOUSE_X = 0xFF;
- VAR_MOUSE_Y = 0xFF;
- VAR_TIMER = 0xFF;
- VAR_TMR_4 = 0xFF;
- VAR_SOUNDCARD = 0xFF;
- VAR_VIDEOMODE = 0xFF;
- VAR_MAINMENU_KEY = 0xFF;
- VAR_FIXEDDISK = 0xFF;
- VAR_CURSORSTATE = 0xFF;
- VAR_USERPUT = 0xFF;
- VAR_SOUNDRESULT = 0xFF;
- VAR_TALKSTOP_KEY = 0xFF;
- VAR_FADE_DELAY = 0xFF;
- VAR_NOSUBTITLES = 0xFF;
-
- VAR_SOUNDPARAM = 0xFF;
- VAR_SOUNDPARAM2 = 0xFF;
- VAR_SOUNDPARAM3 = 0xFF;
- VAR_MOUSEPRESENT = 0xFF;
- VAR_MEMORY_PERFORMANCE = 0xFF;
- VAR_VIDEO_PERFORMANCE = 0xFF;
- VAR_ROOM_FLAG = 0xFF;
- VAR_GAME_LOADED = 0xFF;
- VAR_NEW_ROOM = 0xFF;
- VAR_VERSION_KEY = 0xFF;
-
- VAR_V5_TALK_STRING_Y = 0xFF;
-
- VAR_ROOM_WIDTH = 0xFF;
- VAR_ROOM_HEIGHT = 0xFF;
- VAR_SUBTITLES = 0xFF;
- VAR_V6_EMSSPACE = 0xFF;
-
- VAR_CAMERA_POS_Y = 0xFF;
- VAR_CAMERA_MIN_Y = 0xFF;
- VAR_CAMERA_MAX_Y = 0xFF;
- VAR_CAMERA_THRESHOLD_X = 0xFF;
- VAR_CAMERA_THRESHOLD_Y = 0xFF;
- VAR_CAMERA_SPEED_X = 0xFF;
- VAR_CAMERA_SPEED_Y = 0xFF;
- VAR_CAMERA_ACCEL_X = 0xFF;
- VAR_CAMERA_ACCEL_Y = 0xFF;
- VAR_CAMERA_DEST_X = 0xFF;
- VAR_CAMERA_DEST_Y = 0xFF;
- VAR_CAMERA_FOLLOWED_ACTOR = 0xFF;
-
- VAR_LEFTBTN_DOWN = 0xFF;
- VAR_RIGHTBTN_DOWN = 0xFF;
- VAR_LEFTBTN_HOLD = 0xFF;
- VAR_RIGHTBTN_HOLD = 0xFF;
-
- VAR_SAVELOAD_SCRIPT = 0xFF;
- VAR_SAVELOAD_SCRIPT2 = 0xFF;
-
- VAR_DEFAULT_TALK_DELAY = 0xFF;
- VAR_CHARSET_MASK = 0xFF;
-
- VAR_CUSTOMSCALETABLE = 0xFF;
- VAR_V6_SOUNDMODE = 0xFF;
-
- VAR_ACTIVE_VERB = 0xFF;
- VAR_ACTIVE_OBJECT1 = 0xFF;
- VAR_ACTIVE_OBJECT2 = 0xFF;
- VAR_VERB_ALLOWED = 0xFF;
- VAR_CLICK_AREA = 0xFF;
-
- VAR_BLAST_ABOVE_TEXT = 0xFF;
- VAR_VOICE_MODE = 0xFF;
- VAR_MUSIC_BUNDLE_LOADED = 0xFF;
- VAR_VOICE_BUNDLE_LOADED = 0xFF;
-
- VAR_REDRAW_ALL_ACTORS = 0xFF;
- VAR_SKIP_RESET_TALK_ACTOR = 0xFF;
-
- VAR_SOUND_CHANNEL = 0xFF;
- VAR_TALK_CHANNEL = 0xFF;
- VAR_SOUNDCODE_TMR = 0xFF;
- VAR_RESERVED_SOUND_CHANNELS = 0xFF;
-
- VAR_MAIN_SCRIPT = 0xFF;
-
- VAR_NUM_SCRIPT_CYCLES = 0xFF;
- VAR_SCRIPT_CYCLE = 0xFF;
-
- VAR_NUM_GLOBAL_OBJS = 0xFF;
- VAR_KEY_STATE = 0xFF;
- VAR_MOUSE_STATE = 0xFF;
-
- // Use g_scumm from error() ONLY
- g_scumm = this;
-
- // Read settings from the detector & config manager
- _debugMode = (gDebugLevel >= 0);
- _dumpScripts = detector->_dumpScripts;
- _bootParam = ConfMan.getInt("boot_param");
- // Boot params often need debugging switched on to work
- if (_bootParam)
- _debugMode = true;
-
- // Allow the user to override the game name with a custom string.
- // This allows some game versions to work which use filenames
- // differing from the regular version(s) of that game.
- _baseName = ConfMan.hasKey("basename") ? ConfMan.get("basename") : gs.gameid;
-
- _copyProtection = ConfMan.getBool("copy_protection");
- _demoMode = ConfMan.getBool("demo_mode");
- if (ConfMan.hasKey("nosubtitles")) {
- printf("Configuration key 'nosubtitles' is deprecated. Use 'subtitles' instead\n");
- if (!ConfMan.hasKey("subtitles"))
- ConfMan.set("subtitles", !ConfMan.getBool("nosubtitles"));
- }
-
- // Make sure that at least subtitles are enabled
- if (ConfMan.getBool("speech_mute") && !ConfMan.getBool("subtitles"))
- ConfMan.set("subtitles", 1);
-
- // TODO Detect subtitle only versions of scumm6 games
- if (ConfMan.getBool("speech_mute"))
- _voiceMode = 2;
- else
- _voiceMode = ConfMan.getBool("subtitles");
-
- _confirmExit = ConfMan.getBool("confirm_exit");
-
- if (ConfMan.hasKey("render_mode")) {
- _renderMode = Common::parseRenderMode(ConfMan.get("render_mode").c_str());
- } else {
- _renderMode = Common::kRenderDefault;
- }
-
- // Do some render mode restirctions
- if (_version == 1)
- _renderMode = Common::kRenderDefault;
-
- switch (_renderMode) {
- case Common::kRenderHercA:
- case Common::kRenderHercG:
- if (_version > 2 && _gameId != GID_MONKEY_EGA)
- _renderMode = Common::kRenderDefault;
- break;
-
- case Common::kRenderCGA:
- case Common::kRenderEGA:
- case Common::kRenderAmiga:
- if (!(_features & GF_16COLOR))
- _renderMode = Common::kRenderDefault;
- break;
-
- default:
- break;
- }
-
- _hexdumpScripts = false;
- _showStack = false;
-
- if (_platform == Common::kPlatformFMTowns && _version == 3) { // FM-TOWNS V3 games use 320x240
- _screenWidth = 320;
- _screenHeight = 240;
- } else if (_features & GF_DEFAULT_TO_1X_SCALER) {
- _screenWidth = 640;
- _screenHeight = 480;
- } else if (_platform == Common::kPlatformNES) {
- _screenWidth = 256;
- _screenHeight = 240;
- } else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- _features |= GF_DEFAULT_TO_1X_SCALER;
- _screenWidth = 320;
- _screenHeight = 200;
- } else {
- _screenWidth = 320;
- _screenHeight = 200;
- }
-
- _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight);
-
- _herculesBuf = 0;
- if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- _herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH);
- }
-}
-
-ScummEngine::~ScummEngine() {
- if (_musicEngine) {
- _musicEngine->terminate();
- delete _musicEngine;
- }
-
- _mixer->stopAll();
-
- delete [] _actors;
- delete [] _sortedActors;
-
- delete _2byteFontPtr;
- delete _charset;
- delete _pauseDialog;
- delete _mainMenuDialog;
- delete _versionDialog;
- delete _fileHandle;
-
- delete _sound;
-
- delete _costumeLoader;
- delete _costumeRenderer;
-
- free(_shadowPalette);
-
- free(_palManipPalette);
- free(_palManipIntermediatePal);
-
- res.freeResources();
-
- free(_objectStateTable);
- free(_objectRoomTable);
- free(_objectOwnerTable);
- free(_inventory);
- free(_verbs);
- free(_objs);
- free(_roomVars);
- free(_scummVars);
- free(_bitVars);
- free(_newNames);
- free(_classData);
- free(_arraySlot);
-
- free(_compositeBuf);
- free(_herculesBuf);
-
- delete _debugger;
-}
-
-ScummEngine_v4::ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v5(detector, syst, gs, md5sum, substResFileNameIndex) {
- _resourceHeaderSize = 6;
-}
-
-ScummEngine_v3::ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v4(detector, syst, gs, md5sum, substResFileNameIndex) {
-}
-
-ScummEngine_v3old::ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v3(detector, syst, gs, md5sum, substResFileNameIndex) {
- _resourceHeaderSize = 4;
-}
-
-ScummEngine_v2::ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v3old(detector, syst, gs, md5sum, substResFileNameIndex) {
-}
-
-ScummEngine_c64::ScummEngine_c64(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v2(detector, syst, gs, md5sum, substResFileNameIndex) {
-
- _currentAction = 0;
- _currentMode = 0;
-}
-
-ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine(detector, syst, gs, md5sum, substResFileNameIndex) {
- _blastObjectQueuePos = 0;
- memset(_blastObjectQueue, 0, sizeof(_blastObjectQueue));
- _blastTextQueuePos = 0;
- memset(_blastTextQueue, 0, sizeof(_blastTextQueue));
-
- _smushFrameRate = 0;
-
- VAR_VIDEONAME = 0xFF;
- VAR_RANDOM_NR = 0xFF;
- VAR_STRING2DRAW = 0xFF;
-
- VAR_TIMEDATE_YEAR = 0xFF;
- VAR_TIMEDATE_MONTH = 0xFF;
- VAR_TIMEDATE_DAY = 0xFF;
- VAR_TIMEDATE_HOUR = 0xFF;
- VAR_TIMEDATE_MINUTE = 0xFF;
- VAR_TIMEDATE_SECOND = 0xFF;
-}
-
-#ifndef DISABLE_HE
-ScummEngine_v70he::ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v60he(detector, syst, gs, md5sum, substResFileNameIndex) {
- if (_platform == Common::kPlatformMacintosh && (_heversion >= 72 && _heversion <= 73))
- _resExtractor = new MacResExtractor(this);
- else
- _resExtractor = new Win32ResExtractor(this);
-
- _wiz = new Wiz(this);
-
- _heV7RoomOffsets = NULL;
-
- _heSndSoundId = 0;
- _heSndOffset = 0;
- _heSndChannel = 0;
- _heSndFlags = 0;
- _heSndSoundFreq = 0;
-
- _skipProcessActors = 0;
-
- VAR_NUM_SOUND_CHANNELS = 0xFF;
- VAR_WIZ_TCOLOR = 0xFF;
-}
-
-ScummEngine_v70he::~ScummEngine_v70he() {
- delete _resExtractor;
- delete _wiz;
- free(_heV7DiskOffsets);
- free(_heV7RoomIntOffsets);
- free(_heV7RoomOffsets);
- free(_storedFlObjects);
-}
-
-ScummEngine_v71he::ScummEngine_v71he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v70he(detector, syst, gs, md5sum, substResFileNameIndex) {
- _auxBlocksNum = 0;
- memset(_auxBlocks, 0, sizeof(_auxBlocks));
- _auxEntriesNum = 0;
- memset(_auxEntries, 0, sizeof(_auxEntries));
-}
-
-ScummEngine_v72he::ScummEngine_v72he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v71he(detector, syst, gs, md5sum, substResFileNameIndex) {
- VAR_NUM_ROOMS = 0xFF;
- VAR_NUM_SCRIPTS = 0xFF;
- VAR_NUM_SOUNDS = 0xFF;
- VAR_NUM_COSTUMES = 0xFF;
- VAR_NUM_IMAGES = 0xFF;
- VAR_NUM_CHARSETS = 0xFF;
- VAR_POLYGONS_ONLY = 0xFF;
-}
-
-ScummEngine_v80he::ScummEngine_v80he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v72he(detector, syst, gs, md5sum, substResFileNameIndex) {
- _heSndResId = 0;
- _curSndId = 0;
- _sndPtrOffs = 0;
- _sndTmrOffs = 0;
-
- VAR_PLATFORM = 0xFF;
- VAR_WINDOWS_VERSION = 0xFF;
- VAR_CURRENT_CHARSET = 0xFF;
- VAR_COLOR_DEPTH = 0xFF;
-}
-
-ScummEngine_v90he::ScummEngine_v90he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v80he(detector, syst, gs, md5sum, substResFileNameIndex) {
- _sprite = new Sprite(this);
-
- VAR_NUM_SPRITE_GROUPS = 0xFF;
- VAR_NUM_SPRITES = 0xFF;
- VAR_NUM_PALETTES = 0xFF;
- VAR_NUM_UNK = 0xFF;
-
- VAR_U32_VERSION = 0xFF;
- VAR_U32_ARRAY_UNK = 0xFF;
-}
-
-ScummEngine_v90he::~ScummEngine_v90he() {
- delete _sprite;
- if (_heversion >= 98) {
- delete _logicHE;
- }
- if (_heversion >= 99) {
- free(_hePalettes);
- }
-}
-#endif
-
-#ifndef DISABLE_SCUMM_7_8
-ScummEngine_v7::ScummEngine_v7(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v6(detector, syst, gs, md5sum, substResFileNameIndex) {
- _existLanguageFile = false;
- _languageBuffer = NULL;
- _languageIndex = NULL;
- clearSubtitleQueue();
-}
-
-ScummEngine_v7::~ScummEngine_v7() {
- free(_languageBuffer);
- free(_languageIndex);
-}
-
-ScummEngine_v8::ScummEngine_v8(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex)
- : ScummEngine_v7(detector, syst, gs, md5sum, substResFileNameIndex) {
- _objectIDMap = 0;
-}
-
-ScummEngine_v8::~ScummEngine_v8() {
- delete [] _objectIDMap;
-}
-#endif
-
-#pragma mark -
-#pragma mark --- Initialization ---
-#pragma mark -
-
-int ScummEngine::init(GameDetector &detector) {
-
- // Initialize backend
- _system->beginGFXTransaction();
- initCommonGFX(detector);
- if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
- _system->initSize(Common::kHercW, Common::kHercH, 1);
- _features |= GF_DEFAULT_TO_1X_SCALER;
- _system->setGraphicsMode("1x");
- } else {
- _system->initSize(_screenWidth, _screenHeight, (detector._force1xOverlay ? 1 : 2));
- if (_features & GF_DEFAULT_TO_1X_SCALER)
- _system->setGraphicsMode("1x");
- }
- _system->endGFXTransaction();
-
- // On some systems it's not safe to run CD audio games from the CD.
- if (_features & GF_AUDIOTRACKS)
- checkCD();
-
- int cd_num = ConfMan.getInt("cdrom");
- if (cd_num >= 0 && (_features & GF_AUDIOTRACKS))
- _system->openCD(cd_num);
-
- // Create the sound manager
- _sound = new Sound(this);
-
- // Setup the music engine
- setupMusic(_midi);
-
- // TODO: We shouldn't rely on the global Language values matching those COMI etc. expect.
- // Rather we should explicitly translate them.
- _language = Common::parseLanguage(ConfMan.get("language"));
-
- // Load localization data, if present
- loadLanguageBundle();
-
- // Load CJK font, if present
- loadCJKFont();
-
- // Create the charset renderer
- if (_platform == Common::kPlatformNES)
- _charset = new CharsetRendererNES(this);
- else if (_version <= 2)
- _charset = new CharsetRendererV2(this, _language);
- else if (_version == 3)
- _charset = new CharsetRendererV3(this);
-#ifndef DISABLE_SCUMM_7_8
- else if (_version == 8)
- _charset = new CharsetRendererNut(this);
-#endif
- else
- _charset = new CharsetRendererClassic(this);
-
- // Create the costume renderer
- if (_features & GF_NEW_COSTUMES) {
- _costumeRenderer = new AkosRenderer(this);
- _costumeLoader = new AkosCostumeLoader(this);
- } else if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
- _costumeRenderer = new C64CostumeRenderer(this);
- _costumeLoader = new C64CostumeLoader(this);
- } else if (_platform == Common::kPlatformNES) {
- _costumeRenderer = new NESCostumeRenderer(this);
- _costumeLoader = new NESCostumeLoader(this);
- } else {
- _costumeRenderer = new ClassicCostumeRenderer(this);
- _costumeLoader = new ClassicCostumeLoader(this);
- }
-
-#ifndef DISABLE_SCUMM_7_8
- // Create FT INSANE object
- if (_gameId == GID_FT)
- _insane = new Insane((ScummEngine_v6 *)this);
- else
-#endif
- _insane = 0;
-
- // Load game from specified slot, if any
- if (ConfMan.hasKey("save_slot")) {
- requestLoad(ConfMan.getInt("save_slot"));
- }
-
- allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0);
-
- setupScummVars();
-
- setupOpcodes();
-
- if (_version == 8)
- _numActors = 80;
- else if (_version == 7)
- _numActors = 30;
- else if (_gameId == GID_SAMNMAX)
- _numActors = 30;
- else if (_gameId == GID_MANIAC)
- _numActors = 25;
- else if (_heversion >= 80)
- _numActors = 62;
- else if (_heversion >= 72)
- _numActors = 30;
- else
- _numActors = 13;
-
- if (_version >= 7)
- OF_OWNER_ROOM = 0xFF;
- else
- OF_OWNER_ROOM = 0x0F;
-
- // if (_gameId==GID_MONKEY2 && _bootParam == 0)
- // _bootParam = 10001;
-
- if (!_copyProtection && _gameId == GID_INDY4 && _bootParam == 0) {
- _bootParam = -7873;
- }
-
- if (!_copyProtection && _gameId == GID_SAMNMAX && _bootParam == 0) {
- _bootParam = -1;
- }
-
- readIndexFile();
-
-#ifdef PALMOS_68K
- if (_features & GF_NEW_COSTUMES)
- res._maxHeapThreshold = gVars->memory[kMemScummNewCostGames];
- else
- res._maxHeapThreshold = gVars->memory[kMemScummOldCostGames];
-#else
- if (_features & GF_NEW_COSTUMES) {
- // Since the new costumes are very big, we increase the heap limit, to avoid having
- // to constantly reload stuff from the data files.
- res._maxHeapThreshold = 6 * 1024 * 1024;
- } else {
- res._maxHeapThreshold = 550000;
- }
-#endif
- res._minHeapThreshold = 400000;
-
- scummInit();
- initScummVars();
-
- if (VAR_DEBUGMODE != 0xFF) {
- VAR(VAR_DEBUGMODE) = _debugMode;
- if (_heversion >= 80 && _debugMode)
- VAR(85) = 1;
- }
-
- if (_imuse) {
- _imuse->setBase(res.address[rtSound]);
- }
-
- if (_version >= 5)
- _sound->setupSound();
-
-#if (defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
- Graphics::initfonts();
-#endif
-
- // Create debugger
- if (!_debugger)
- _debugger = new ScummDebugger(this);
-
- return 0;
-}
-
-void ScummEngine::scummInit() {
- int i;
-
- _tempMusic = 0;
- debug(9, "scummInit");
-
- if ((_gameId == GID_MANIAC) && (_version == 1) && !(_platform == Common::kPlatformNES)) {
- if (_platform == Common::kPlatformC64)
- initScreens(8, 144);
- else
- initScreens(16, 152);
- } else if (_version >= 7 || _heversion >= 71) {
- initScreens(0, _screenHeight);
- } else {
- initScreens(16, 144);
- }
-
- _palManipCounter = 0;
-
- for (i = 0; i < 256; i++)
- _roomPalette[i] = i;
- if (_version == 1) {
- // Use 17 color table for v1 games to allow
- // correct color for inventory and sentence
- // line
- // Original games used some kind of dynamic
- // color table remapping between rooms
- if (_platform == Common::kPlatformC64) {
- setupC64Palette();
- } else if (_platform == Common::kPlatformNES) {
- setupNESPalette();
- } else {
- setupV1Palette();
- }
- } else if (_features & GF_16COLOR) {
- for (i = 0; i < 16; i++)
- _shadowPalette[i] = i;
-
- switch (_renderMode) {
- case Common::kRenderEGA:
- setupEGAPalette();
- break;
-
- case Common::kRenderAmiga:
- setupAmigaPalette();
- break;
-
- case Common::kRenderCGA:
- setupCGAPalette();
- break;
-
- case Common::kRenderHercA:
- case Common::kRenderHercG:
- setupHercPalette();
- break;
-
- default:
- if ((_platform == Common::kPlatformAmiga) || (_platform == Common::kPlatformAtariST))
- setupAmigaPalette();
- else
- setupEGAPalette();
- }
- }
-
- if (_version > 3 && _version < 8)
- loadCharset(1);
-
- if (_features & GF_OLD_BUNDLE)
- loadCharset(0); // FIXME - HACK ?
-
- setShake(0);
- setupCursor();
-
- // Allocate and Initialize actors
- Actor::initActorClass(this);
- _actors = new Actor[_numActors];
- _sortedActors = new Actor * [_numActors];
- for (i = 0; i < _numActors; i++) {
- _actors[i]._number = i;
- _actors[i].initActor(1);
-
- // this is from IDB
- if ((_version == 1) || (_gameId == GID_MANIAC && _demoMode))
- _actors[i].setActorCostume(i);
- }
-
- if (_gameId == GID_MANIAC && _version == 1) {
- setupV1ActorTalkColor();
- } else if (_gameId == GID_MANIAC && _version == 2 && _demoMode) {
- // HACK Some palette changes needed for demo script
- // in Maniac Mansion (Enhanced)
- _actors[3].setPalette(3, 1);
- _actors[9]._talkColor = 15;
- _actors[10]._talkColor = 7;
- _actors[11]._talkColor = 2;
- _actors[13]._talkColor = 5;
- _actors[23]._talkColor = 14;
- }
-
- vm.numNestedScripts = 0;
- vm.cutSceneStackPointer = 0;
-
- memset(vm.cutScenePtr, 0, sizeof(vm.cutScenePtr));
- memset(vm.cutSceneData, 0, sizeof(vm.cutSceneData));
-
- for (i = 0; i < _numVerbs; i++) {
- _verbs[i].verbid = 0;
- _verbs[i].curRect.right = _screenWidth - 1;
- _verbs[i].oldRect.left = -1;
- _verbs[i].type = 0;
- _verbs[i].color = 2;
- _verbs[i].hicolor = 0;
- _verbs[i].charset_nr = 1;
- _verbs[i].curmode = 0;
- _verbs[i].saveid = 0;
- _verbs[i].center = 0;
- _verbs[i].key = 0;
- }
-
- if (_version == 7) {
- VAR(VAR_CAMERA_THRESHOLD_X) = 100;
- VAR(VAR_CAMERA_THRESHOLD_Y) = 70;
- VAR(VAR_CAMERA_ACCEL_X) = 100;
- VAR(VAR_CAMERA_ACCEL_Y) = 100;
- } else if (!(_features & GF_NEW_CAMERA)) {
- if (_platform == Common::kPlatformNES) {
- camera._leftTrigger = 6; // 6
- camera._rightTrigger = 21; // 25
- } else {
- camera._leftTrigger = 10;
- camera._rightTrigger = (_heversion >= 71) ? 70 : 30;
- }
- camera._mode = 0;
- }
- camera._follows = 0;
-
- virtscr[0].xstart = 0;
-
- if (VAR_CURRENT_LIGHTS != 0xFF) {
- // Setup light
- _flashlight.xStrips = 7;
- _flashlight.yStrips = 7;
- _flashlight.buffer = NULL;
- }
-
- _mouse.x = 104;
- _mouse.y = 56;
-
- _ENCD_offs = 0;
- _EXCD_offs = 0;
-
- _currentScript = 0xFF;
- _sentenceNum = 0;
-
- _currentRoom = 0;
- _numObjectsInRoom = 0;
- _actorToPrintStrFor = 0;
-
- _charsetBufPos = 0;
- _haveMsg = 0;
- _haveActorSpeechMsg = false;
-
- _varwatch = -1;
- _screenStartStrip = 0;
-
- _defaultTalkDelay = 3;
- _talkDelay = 0;
- _keepText = false;
-
- _currentCursor = 0;
- _cursor.state = 0;
- _userPut = 0;
-
- _newEffect = 129;
- _fullRedraw = true;
-
- clearDrawObjectQueue();
-
- if (_platform == Common::kPlatformNES)
- decodeNESBaseTiles();
-
- for (i = 0; i < 6; i++) {
- if (_version == 3) { // FIXME - what is this?
- _string[i]._default.xpos = 0;
- _string[i]._default.ypos = 0;
- } else {
- _string[i]._default.xpos = 2;
- _string[i]._default.ypos = 5;
- }
- _string[i]._default.right = _screenWidth - 1;
- _string[i]._default.height = 0;
- _string[i]._default.color = 0xF;
- _string[i]._default.center = 0;
- _string[i]._default.charset = 0;
- }
-
- // all keys are released
- for (i = 0; i < 512; i++)
- _keyDownMap[i] = false;
-
- _lastSaveTime = _system->getMillis();
-}
-
-void ScummEngine_c64::scummInit() {
- ScummEngine::scummInit();
- initC64Verbs();
-}
-
-void ScummEngine_v2::scummInit() {
- ScummEngine::scummInit();
-
- if (_platform == Common::kPlatformNES) {
- initNESMouseOver();
- _switchRoomEffect2 = _switchRoomEffect = 6;
- } else {
- initV2MouseOver();
- // Seems in V2 there was only a single room effect (iris),
- // so we set that here.
- _switchRoomEffect2 = 1;
- _switchRoomEffect = 5;
- }
-
- _inventoryOffset = 0;
-}
-
-void ScummEngine_v6::scummInit() {
- ScummEngine::scummInit();
- setDefaultCursor();
-}
-
-void ScummEngine_v60he::scummInit() {
- ScummEngine::scummInit();
-
- // HACK cursor hotspot is wrong
- // Original games used
- // setCursorHotspot(8, 7);
- if (_gameId == GID_FUNPACK)
- setCursorHotspot(16, 16);
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v72he::scummInit() {
- ScummEngine_v60he::scummInit();
-
- _stringLength = 1;
- memset(_stringBuffer, 0, sizeof(_stringBuffer));
-}
-
-void ScummEngine_v90he::scummInit() {
- ScummEngine_v72he::scummInit();
-
- _heObject = 0;
- _heObjectNum = 0;
- _hePaletteNum = 0;
-
- _sprite->resetTables(0);
- memset(&_wizParams, 0, sizeof(_wizParams));
-
- if (_features & GF_HE_CURSORLESS)
- setDefaultCursor();
-
- if (_heversion >= 98) {
- switch (_gameId) {
- case GID_PUTTRACE:
- _logicHE = new LogicHErace(this);
- break;
-
- case GID_FUNSHOP:
- _logicHE = new LogicHEfunshop(this);
- break;
-
- case GID_FOOTBALL:
- _logicHE = new LogicHEfootball(this);
- break;
-
- default:
- _logicHE = new LogicHE(this);
- break;
- }
- }
-}
-
-void ScummEngine_v99he::scummInit() {
- ScummEngine_v90he::scummInit();
-
- _hePalettes = (uint8 *)malloc((_numPalettes + 1) * 1024);
- memset(_hePalettes, 0, (_numPalettes + 1) * 1024);
-
- // Array 129 is set to base name
- int len = resStrLen((const byte *)_baseName.c_str()) + 1;
- ArrayHeader *ah = defineArray(129, kStringArray, 0, 0, 0, len);
- memcpy(ah->data, _baseName.c_str(), len);
-
-}
-#endif
-
-void ScummEngine::setupMusic(int midi) {
- int midiDriver = MidiDriver::detectMusicDriver(midi);
- _native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
-
- switch (midiDriver) {
- case MD_NULL:
- _musicType = MDT_NONE;
- break;
- case MD_PCSPK:
- case MD_PCJR:
- _musicType = MDT_PCSPK;
- break;
- case MD_TOWNS:
- _musicType = MDT_TOWNS;
- break;
- case MD_ADLIB:
- _musicType = MDT_ADLIB;
- break;
- default:
- _musicType = MDT_MIDI;
- break;
- }
-
- // FIXME: MD_TOWNS should not be _midi_native in the first place!! iMuse code needs to be restructured.
- if ((_gameId == GID_TENTACLE) || (_gameId == GID_SAMNMAX) || (midiDriver == MD_TOWNS))
- _enable_gs = false;
- else
- _enable_gs = ConfMan.getBool("enable_gs");
-
- /* Bind the mixer to the system => mixer will be invoked
- * automatically when samples need to be generated */
- if (!_mixer->isReady()) {
- warning("Sound mixer initialization failed\n");
- if (_musicType == MDT_ADLIB || _musicType == MDT_PCSPK) {
- midiDriver = MD_NULL;
- _musicType = MDT_NONE;
- warning("MIDI driver depends on sound mixer, switching to null MIDI driver\n");
- }
- }
-
- // Init iMuse
- if (_features & GF_DIGI_IMUSE) {
-#ifndef DISABLE_SCUMM_7_8
- _musicEngine = _imuseDigital = new IMuseDigital(this, 10);
-#endif
- } else if (_platform == Common::kPlatformC64) {
- // TODO
- _musicEngine = NULL;
- } else if (_platform == Common::kPlatformNES) {
- _musicEngine = new Player_NES(this);
- } else if ((_platform == Common::kPlatformAmiga) && (_version == 2)) {
- _musicEngine = new Player_V2A(this);
- } else if ((_platform == Common::kPlatformAmiga) && (_version == 3)) {
- _musicEngine = new Player_V3A(this);
- } else if ((_platform == Common::kPlatformAmiga) && (_version < 5)) {
- _musicEngine = NULL;
- } else if (_gameId == GID_MANIAC && (_version == 1)) {
- _musicEngine = new Player_V1(this, midiDriver != MD_PCSPK);
- } else if (_version <= 2) {
- _musicEngine = new Player_V2(this, midiDriver != MD_PCSPK);
- } else if ((_musicType == MDT_PCSPK) && ((_version > 2) && (_version < 5))) {
- _musicEngine = new Player_V2(this, midiDriver != MD_PCSPK);
- } else if (_version > 2 && _heversion <= 61) {
- MidiDriver *nativeMidiDriver = 0;
- MidiDriver *adlibMidiDriver = 0;
-
- if (_musicType != MDT_ADLIB)
- nativeMidiDriver = MidiDriver::createMidi(midiDriver);
- if (nativeMidiDriver != NULL && _native_mt32)
- nativeMidiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- bool multi_midi = ConfMan.getBool("multi_midi") && _musicType != MDT_NONE && (midi & MDT_ADLIB);
- if (_musicType == MDT_ADLIB || multi_midi) {
- adlibMidiDriver = MidiDriver_ADLIB_create(_mixer);
- adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_features & GF_SMALL_HEADER) ? 1 : 0);
- }
-
- _musicEngine = _imuse = IMuse::create(_system, nativeMidiDriver, adlibMidiDriver);
- if (_imuse) {
- if (ConfMan.hasKey("tempo"))
- _imuse->property(IMuse::PROP_TEMPO_BASE, ConfMan.getInt("tempo"));
- _imuse->property(IMuse::PROP_NATIVE_MT32, _native_mt32);
- _imuse->property(IMuse::PROP_GS, _enable_gs);
- if (_heversion >= 60 || midi == MDT_TOWNS) {
- _imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1);
- _imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1);
- }
- if (midi == MDT_TOWNS)
- _imuse->property(IMuse::PROP_DIRECT_PASSTHROUGH, 1);
- }
- }
-
- setupVolumes();
-}
-
-void ScummEngine::setupVolumes() {
-
- // Sync the engine with the config manager
- int soundVolumeMusic = ConfMan.getInt("music_volume");
- int soundVolumeSfx = ConfMan.getInt("sfx_volume");
- int soundVolumeSpeech = ConfMan.getInt("speech_volume");
-
- if (_musicEngine) {
- _musicEngine->setMusicVolume(soundVolumeMusic);
- }
-
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSfx);
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, soundVolumeSpeech);
-}
-
-
-
-#pragma mark -
-#pragma mark --- Main loop ---
-#pragma mark -
-
-int ScummEngine::go() {
- _engineStartTime = _system->getMillis() / 1000;
-
- // If requested, load a save game instead of running the boot script
- if (_saveLoadFlag != 2 || !loadState(_saveLoadSlot, _saveTemporaryState)) {
- int args[16];
- memset(args, 0, sizeof(args));
- args[0] = _bootParam;
-
- _saveLoadFlag = 0;
-#ifndef DISABLE_HE
- if (_heversion >= 98) {
- ((ScummEngine_v90he *)this)->_logicHE->initOnce();
- ((ScummEngine_v90he *)this)->_logicHE->beforeBootScript();
- }
-#endif
- if (_gameId == GID_MANIAC && _demoMode)
- runScript(9, 0, 0, args);
- else
- runScript(1, 0, 0, args);
- } else {
- _saveLoadFlag = 0;
- }
-
- int delta = 0;
- int diff = _system->getMillis();
-
- while (!_quit) {
-
- updatePalette();
- _system->updateScreen();
-
- diff -= _system->getMillis();
- waitForTimer(delta * 15 + diff);
- diff = _system->getMillis();
- delta = scummLoop(delta);
-
- if (delta < 1) // Ensure we don't get into a loop
- delta = 1; // by not decreasing sleepers.
-
- if (_quit) {
- // TODO: Maybe perform an autosave on exit?
- }
- }
-
- return 0;
-}
-
-void ScummEngine::waitForTimer(int msec_delay) {
- uint32 start_time;
-
- if (_fastMode & 2)
- msec_delay = 0;
- else if (_fastMode & 1)
- msec_delay = 10;
-
- start_time = _system->getMillis();
-
- while (!_quit) {
- _sound->updateCD(); // Loop CD Audio if needed
- parseEvents();
- if (_system->getMillis() >= start_time + msec_delay)
- break;
- _system->delayMillis(10);
- }
-}
-
-int ScummEngine::scummLoop(int delta) {
- if (_debugger->isAttached())
- _debugger->onFrame();
-
- // Randomize the PRNG by calling it at regular intervals. This ensures
- // that it will be in a different state each time you run the program.
- _rnd.getRandomNumber(2);
-
-#ifndef DISABLE_HE
- if (_heversion >= 98) {
- ((ScummEngine_v90he *)this)->_logicHE->startOfFrame();
- }
-#endif
- if (_version > 2) {
- VAR(VAR_TMR_1) += delta;
- VAR(VAR_TMR_2) += delta;
- VAR(VAR_TMR_3) += delta;
- if (_gameId == GID_ZAK || _gameId == GID_INDY3) {
- // All versions of Indy3 set three extra timers
- // FM-TOWNS version of Zak sets three extra timers
- VAR(39) += delta;
- VAR(40) += delta;
- VAR(41) += delta;
- }
- }
- if (VAR_TMR_4 != 0xFF)
- VAR(VAR_TMR_4) += delta;
-
- if (delta > 15)
- delta = 15;
-
- decreaseScriptDelay(delta);
-
- _talkDelay -= delta;
- if (_talkDelay < 0)
- _talkDelay = 0;
-
- // Record the current ego actor before any scripts (including input scripts)
- // get a chance to run.
- int oldEgo = 0;
- if (VAR_EGO != 0xFF)
- oldEgo = VAR(VAR_EGO);
-
- // In V1-V3 games, CHARSET_1 is called much earlier than in newer games.
- // See also bug #770042 for a case were this makes a difference.
- if (_version <= 3)
- CHARSET_1();
-
- processKbd(false);
-
- if (_features & GF_NEW_CAMERA) {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x;
- VAR(VAR_CAMERA_POS_Y) = camera._cur.y;
- } else if (_version <= 2) {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x / 8;
- } else {
- VAR(VAR_CAMERA_POS_X) = camera._cur.x;
- }
- if (_version <= 7)
- VAR(VAR_HAVE_MSG) = _haveMsg;
-
- if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
- // TODO
- } else if (_version <= 2) {
- VAR(VAR_VIRT_MOUSE_X) = _virtualMouse.x / 8;
- VAR(VAR_VIRT_MOUSE_Y) = _virtualMouse.y / 2;
-
- // Adjust mouse coordinates as narrow rooms in NES are centered
- if (_platform == Common::kPlatformNES && _NESStartStrip > 0) {
- VAR(VAR_VIRT_MOUSE_X) -= 2;
- if (VAR(VAR_VIRT_MOUSE_X) < 0)
- VAR(VAR_VIRT_MOUSE_X) = 0;
- }
- } else {
- VAR(VAR_VIRT_MOUSE_X) = _virtualMouse.x;
- VAR(VAR_VIRT_MOUSE_Y) = _virtualMouse.y;
- VAR(VAR_MOUSE_X) = _mouse.x;
- VAR(VAR_MOUSE_Y) = _mouse.y;
- if (VAR_DEBUGMODE != 0xFF) {
- // This is NOT for the Mac version of Indy3/Loom
- VAR(VAR_DEBUGMODE) = _debugMode;
- }
- }
-
- if (_features & GF_AUDIOTRACKS) {
- // Covered automatically by the Sound class
- } else if (VAR_MUSIC_TIMER != 0xFF) {
- if (_musicEngine) {
- // The music engine generates the timer data for us.
- VAR(VAR_MUSIC_TIMER) = _musicEngine->getMusicTimer();
- } else {
- // Used for Money Island 1 (Amiga)
- // TODO: The music delay (given in milliseconds) might have to be tuned a little
- // to get it correct for all games. Without the ability to watch/listen to the
- // original games, I can't do that myself.
- const int MUSIC_DELAY = 350;
- _tempMusic += delta * 15; // Convert delta to milliseconds
- if (_tempMusic >= MUSIC_DELAY) {
- _tempMusic -= MUSIC_DELAY;
- VAR(VAR_MUSIC_TIMER) += 1;
- }
- }
- }
-
- // Trigger autosave if necessary.
- if (!_saveLoadFlag && shouldPerformAutoSave(_lastSaveTime)) {
- _saveLoadSlot = 0;
- sprintf(_saveLoadName, "Autosave %d", _saveLoadSlot);
- _saveLoadFlag = 1;
- _saveTemporaryState = false;
- }
-
- if (VAR_GAME_LOADED != 0xFF)
- VAR(VAR_GAME_LOADED) = 0;
- if (_saveLoadFlag) {
-load_game:
- bool success;
- const char *errMsg = 0;
- char filename[256];
-
- if (_saveLoadFlag == 1) {
- success = saveState(_saveLoadSlot, _saveTemporaryState);
- if (!success)
- errMsg = "Failed to save game state to file:\n\n%s";
-
- // Ender: Disabled for small_header games, as can overwrite game
- // variables (eg, Zak256 cashcard values). Temp disabled for V8
- // because of odd timing issue with scripts and the variable reset
- if (success && _saveTemporaryState && !(_features & GF_SMALL_HEADER) && _version < 8)
- VAR(VAR_GAME_LOADED) = 201;
- } else {
- success = loadState(_saveLoadSlot, _saveTemporaryState);
- if (!success)
- errMsg = "Failed to load game state from file:\n\n%s";
-
- // Ender: Disabled for small_header games, as can overwrite game
- // variables (eg, Zak256 cashcard values).
- if (success && _saveTemporaryState && !(_features & GF_SMALL_HEADER))
- VAR(VAR_GAME_LOADED) = 203;
- }
-
- makeSavegameName(filename, _saveLoadSlot, _saveTemporaryState);
- if (!success) {
- displayMessage(0, errMsg, filename);
- } else if (_saveLoadFlag == 1 && _saveLoadSlot != 0 && !_saveTemporaryState) {
- // Display "Save successful" message, except for auto saves
- char buf[256];
- snprintf(buf, sizeof(buf), "Successfully saved game state in file:\n\n%s", filename);
-
- GUI::TimedMessageDialog dialog(buf, 1500);
- runDialog(dialog);
- }
- if (success && _saveLoadFlag != 1)
- clearClickedStatus();
-
- _saveLoadFlag = 0;
- _lastSaveTime = _system->getMillis();
- }
-
- if (_completeScreenRedraw) {
- _charset->clearCharsetMask();
- _charset->_hasMask = false;
-
- // HACK as in game save stuff isn't supported currently
- if (_gameId == GID_LOOM) {
- int args[16];
- uint value;
- memset(args, 0, sizeof(args));
- args[0] = 2;
-
- if (_platform == Common::kPlatformMacintosh)
- value = 105;
- else if (_version == 4) // 256 color CD version
- value = 150;
- else
- value = 100;
- byte restoreScript = (_platform == Common::kPlatformFMTowns) ? 17 : 18;
- // if verbs should be shown restore them
- if (VAR(value) == 2)
- runScript(restoreScript, 0, 0, args);
- } else if (_version > 3) {
- for (int i = 0; i < _numVerbs; i++)
- drawVerb(i, 0);
- } else {
- redrawVerbs();
- }
-
- handleMouseOver(false);
-
- _completeScreenRedraw = false;
- _fullRedraw = true;
- }
-
- if (_heversion >= 80) {
- _sound->processSoundCode();
- }
- runAllScripts();
- checkExecVerbs();
- checkAndRunSentenceScript();
-
- if (_quit)
- return 0;
-
- // HACK: If a load was requested, immediately perform it. This avoids
- // drawing the current room right after the load is request but before
- // it is performed. That was annoying esp. if you loaded while a SMUSH
- // cutscene was playing.
- if (_saveLoadFlag && _saveLoadFlag != 1) {
- goto load_game;
- }
-
- if (_currentRoom == 0) {
- if (_version > 3)
- CHARSET_1();
- drawDirtyScreenParts();
- } else {
- walkActors();
- moveCamera();
- updateObjectStates();
- if (_version > 3)
- CHARSET_1();
-
- if (camera._cur.x != camera._last.x || _bgNeedsRedraw || _fullRedraw
- || ((_features & GF_NEW_CAMERA) && camera._cur.y != camera._last.y)) {
- redrawBGAreas();
- }
-
- processDrawQue();
-
- if (_heversion >= 99)
- _fullRedraw = false;
-
- // Full Throttle always redraws verbs and draws verbs before actors
- if (_version >= 7)
- redrawVerbs();
-
-#ifndef DISABLE_HE
- if (_heversion >= 90) {
- ((ScummEngine_v90he *)this)->_sprite->resetBackground();
- ((ScummEngine_v90he *)this)->_sprite->sortActiveSprites();
- }
-#endif
-
- setActorRedrawFlags();
- resetActorBgs();
-
- if (VAR_CURRENT_LIGHTS != 0xFF &&
- !(VAR(VAR_CURRENT_LIGHTS) & LIGHTMODE_screen) &&
- VAR(VAR_CURRENT_LIGHTS) & LIGHTMODE_flashlight) {
- drawFlashlight();
- setActorRedrawFlags();
- }
-
- processActors();
-
- _fullRedraw = false;
-
- if (_version >= 4 && _heversion <= 61)
- cyclePalette();
- palManipulate();
- if (_doEffect) {
- _doEffect = false;
- fadeIn(_newEffect);
- clearClickedStatus();
- }
-
- if (VAR_MAIN_SCRIPT != 0xFF && VAR(VAR_MAIN_SCRIPT) != 0) {
- runScript(VAR(VAR_MAIN_SCRIPT), 0, 0, 0);
- }
-
- // Handle mouse over effects (for verbs).
- handleMouseOver(oldEgo != VAR(VAR_EGO));
-
- // Render everything to the screen.
- drawDirtyScreenParts();
-
- if (_version <= 5)
- playActorSounds();
- }
-
- _sound->processSound();
-
-#ifndef DISABLE_SCUMM_7_8
- if (_imuseDigital) {
- _imuseDigital->flushTracks();
- if ( ((_gameId == GID_DIG) && (!(_features & GF_DEMO))) || (_gameId == GID_CMI) )
- _imuseDigital->refreshScripts();
- }
-#endif
-
- camera._last = camera._cur;
-
- if (!(++res._expireCounter)) {
- res.increaseResourceCounter();
- }
-
- animateCursor();
-
- /* show or hide mouse */
- _system->showMouse(_cursor.state > 0);
-
-#ifndef DISABLE_HE
- if (_heversion >= 90) {
- ((ScummEngine_v90he *)this)->_sprite->updateImages();
- }
- if (_heversion >= 98) {
- ((ScummEngine_v90he *)this)->_logicHE->endOfFrame();
- }
-#endif
-
- if (VAR_TIMER != 0xFF)
- VAR(VAR_TIMER) = 0;
- return VAR(VAR_TIMER_NEXT);
-
-}
-
-#pragma mark -
-#pragma mark --- SCUMM ---
-#pragma mark -
-
-int ScummEngine::getHETimer(int timer) {
- checkRange(15, 1, timer, "getHETimer: Timer out of range(%d)");
- int time = _system->getMillis() - _heTimers[timer];
- return time;
-}
-
-void ScummEngine::setHETimer(int timer) {
- checkRange(15, 1, timer, "setHETimer: Timer out of range(%d)");
- _heTimers[timer] = _system->getMillis();
-}
-
-void ScummEngine::pauseGame() {
- pauseDialog();
-}
-
-void ScummEngine::shutDown() {
- _quit = true;
-}
-
-void ScummEngine::restart() {
-// TODO: Check this function - we should probably be reinitting a lot more stuff, and I suspect
-// this leaks memory like a sieve
-
-// Fingolfing seez: An alternate way to implement restarting would be to create
-// a save state right after startup ... to this end we could introduce a SaveFile
-// subclass which is implemented using a memory buffer (i.e. no actual file is
-// created). Then to restart we just have to load that pseudo save state.
-
-
- int i;
-
- // Reset some stuff
- _currentRoom = 0;
- _currentScript = 0xFF;
- killAllScriptsExceptCurrent();
- setShake(0);
- _sound->stopAllSounds();
-
- // Clear the script variables
- for (i = 0; i < _numVariables; i++)
- _scummVars[i] = 0;
-
- // Empty inventory
- for (i = 0; i < _numGlobalObjects; i++)
- clearOwnerOf(i);
-
- // Reallocate arrays
- allocateArrays();
-
- // Reread index (reset objectstate etc)
- readIndexFile();
-
- // Reinit scumm variables
- scummInit();
- initScummVars();
-
- if (_imuse) {
- _imuse->setBase(res.address[rtSound]);
- }
-
- // Reinit sound engine
- if (_version >= 5)
- _sound->setupSound();
-
- // Re-run bootscript
- int args[16];
- memset(args, 0, sizeof(args));
- args[0] = _bootParam;
- if (_gameId == GID_MANIAC && _demoMode)
- runScript(9, 0, 0, args);
- else
- runScript(1, 0, 0, args);
-}
-
-void ScummEngine::startManiac() {
- debug(0, "stub startManiac()");
- displayMessage(0, "Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory.");
-}
-
-#pragma mark -
-#pragma mark --- GUI ---
-#pragma mark -
-
-int ScummEngine::runDialog(Dialog &dialog) {
- _dialogStartTime = _system->getMillis() / 1000;
-
- // Pause sound & video
- bool old_soundsPaused = _sound->_soundsPaused;
- _sound->pauseSounds(true);
- bool oldSmushPaused = _smushPaused;
- _smushPaused = true;
-
- // Open & run the dialog
- int result = dialog.runModal();
-
- // Restore old cursor
- updateCursor();
-
- // Resume sound & video
- _sound->pauseSounds(old_soundsPaused);
- _smushPaused = oldSmushPaused;
-
- _engineStartTime += (_system->getMillis() / 1000) - _dialogStartTime;
- _dialogStartTime = 0;
-
- // Return the result
- return result;
-}
-
-void ScummEngine::pauseDialog() {
- if (!_pauseDialog)
- _pauseDialog = new PauseDialog(this, 10);
- runDialog(*_pauseDialog);
-}
-
-void ScummEngine::versionDialog() {
- if (!_versionDialog)
- _versionDialog = new PauseDialog(this, 11);
- runDialog(*_versionDialog);
-}
-
-void ScummEngine::mainMenuDialog() {
- if (!_mainMenuDialog)
- _mainMenuDialog = new MainMenuDialog(this);
- runDialog(*_mainMenuDialog);
-}
-
-void ScummEngine::confirmExitDialog() {
- ConfirmDialog d(this, "Do you really want to quit (y/n)?");
-
- if (runDialog(d)) {
- _quit = true;
- }
-}
-
-void ScummEngine::confirmRestartDialog() {
- ConfirmDialog d(this, "Do you really want to restart (y/n)?");
-
- if (runDialog(d)) {
- restart();
- }
-}
-
-char ScummEngine::displayMessage(const char *altButton, const char *message, ...) {
- char buf[STRINGBUFLEN];
- va_list va;
-
- va_start(va, message);
- vsnprintf(buf, STRINGBUFLEN, message, va);
- va_end(va);
-
- GUI::MessageDialog dialog(buf, "OK", altButton);
- return runDialog(dialog);
-}
-
-#pragma mark -
-#pragma mark --- Miscellaneous ---
-#pragma mark -
-
-
-uint32 ScummEngine::fileReadDword() {
-#if defined(SCUMM_LITTLE_ENDIAN)
- return _fileHandle->readUint32LE();
-#elif defined(SCUMM_BIG_ENDIAN)
- return _fileHandle->readUint32BE();
-#endif
-}
-
-void ScummEngine::errorString(const char *buf1, char *buf2) {
- if (_currentScript != 0xFF) {
- ScriptSlot *ss = &vm.slot[_currentScript];
- sprintf(buf2, "(%d:%d:0x%X): %s", _roomResource,
- ss->number, _scriptPointer - _scriptOrgPointer, buf1);
- } else {
- strcpy(buf2, buf1);
- }
-
-#ifdef _WIN32_WCE
- if (isSmartphone())
- return;
-#endif
-
- // Unless an error -originated- within the debugger, spawn the debugger. Otherwise
- // exit out normally.
- if (_debugger && !_debugger->isAttached()) {
- printf("%s\n", buf2); // (Print it again in case debugger segfaults)
- _debugger->attach(buf2);
- _debugger->onFrame();
- }
-}
-
-int ScummEngine::generateSubstResFileName(const char *filename, char *buf, int bufsize, int index) {
- if (index == -3)
- index = _substResFileNameIndex;
-
- return generateSubstResFileName_(filename, buf, bufsize, index);
-}
-
-
-} // End of namespace Scumm
-
-using namespace Scumm;
-
-GameList Engine_SCUMM_gameList() {
- const ScummGameSettings *g = scumm_settings;
- const ObsoleteGameIDs *o = obsoleteGameIDsTable;
- GameList games;
- while (g->gameid) {
- games.push_back(g->toGameSettings());
- g++;
- }
-
- while (o->from) {
- games.push_back(o->toGameSettings());
- o++;
- }
- return games;
-}
-
-enum {
- kDetectNameMethodsCount = 8
-};
-
-static bool generateDetectName(const ScummGameSettings *g, int method, char *detectName) {
- detectName[0] = '\0';
-
- switch (method) {
- case 0:
- if (g->version > 3)
- return false;
- strcpy(detectName, "00.LFL");
- break;
- case 1:
- if (g->version < 3 || g->version > 5)
- return false;
- strcpy(detectName, "000.LFL");
- break;
- case 2:
- if (g->version < 4 || g->version > 7)
- return false;
- strcpy(detectName, g->gameid);
- strcat(detectName, ".000");
- break;
- case 3:
- if (g->version < 7)
- return false;
- strcpy(detectName, g->gameid);
- strcat(detectName, ".la0");
- break;
- case 4:
- if (g->heversion == 0)
- return false;
- strcpy(detectName, g->gameid);
- strcat(detectName, ".he0");
- break;
- case 5:
- // FIXME: Fingolfin asks: For which games is this case used?
- // Please document this. Also: Why was this case missing in
- // Engine_SCUMM_create ?
- strcpy(detectName, g->gameid);
- break;
- case 6:
- if (g->id != GID_SAMNMAX)
- return false;
- strcpy(detectName, g->gameid);
- strcat(detectName, ".sm0");
- break;
- case 7:
- if (g->id != GID_MANIAC)
- return false;
- strcpy(detectName, "00.MAN");
- break;
- }
-
- return true;
-}
-
-
-DetectedGameList Engine_SCUMM_detectGames(const FSList &fslist) {
- DetectedGameList detectedGames;
- const ScummGameSettings *g;
- char detectName[128];
- char tempName[128];
- int substLastIndex = 0;
-
- typedef Common::Map<Common::String, bool> StringSet;
- StringSet fileSet;
-
- for (g = scumm_settings; g->gameid; ++g) {
- // Determine the 'detectname' for this game, that is, the name of a
- // file that *must* be presented if the directory contains the data
- // for this game. For example, FOA requires atlantis.000
-
- // TODO: we need to add cache here
- for (int method = 0; method < kDetectNameMethodsCount; method++) {
- if (!generateDetectName(g, method, detectName))
- continue;
-
- strcpy(tempName, detectName);
-
- substLastIndex = 0;
-
- while (substLastIndex != -1) {
- // Iterate over all files in the given directory
- for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
- if (!file->isDirectory()) {
- const char *name = file->displayName().c_str();
-
- if (0 == scumm_stricmp(detectName, name)) {
- byte buf[6];
-
- if (g->version < 4) {
- // We take a look at the file now, to narrow
- // down the list of possible candidates a bit further.
- // E.g. it's trivial to distinguish V1 from V3 games.
- File tmp;
- if (!tmp.open(file->path().c_str()))
- break;
- tmp.read(buf, 6);
-
- if (buf[0] == 0xCE && buf[1] == 0xF5) {
- // Looks like V1. However, we currently do not distinguish between V1 and V2
- // in the scumm_settings list.
- if (g->version != 1 && g->version != 2)
- break;
-
- // Candidates: maniac clasic, zak classic
-
- // TODO: Maybe we can use the filesize to distinguish these two?
- // English V1 Zak: 1896 bytes
- // English V1 MM: 1972 bytes
- // It would be interesting if those sizes are the same for other language
- // variants of these games, or for demos?
- } else if (buf[0] == 0xFF && buf[1] == 0xFE) {
- // GF_OLD_BUNDLE: could be V2 or old V3.
- if (!(g->features & GF_OLD_BUNDLE) || (g->version != 2 && g->version != 3))
- break;
- // Candidates: maniac enhanced, zak enhanced, indy3ega, loom
- /*
- TODO: MIght be possible to distinguish those by the script count.
- Specifically, my versions of these games have this in their headers:
-
- Loom (en; de; en demo; en MAC):
- _numGlobalObjects 1000
- _numRooms 100
- _numCostumes 200
- _numScripts 200
- _numSounds 80
-
- Indy3EGA (en PC; en Mac; en demo):
- _numGlobalObjects 1000
- _numRooms 99
- _numCostumes 129
- _numScripts 139
- _numSounds 84
-
- MM (en; de):
- _numGlobalObjects 780
- _numRooms 61
- _numCostumes 40
- _numScripts 179
- _numSounds 120
-
- Zak (de; en demo):
- _numGlobalObjects 780
- _numRooms 61
- _numCostumes 40
- _numScripts 155
- _numSounds 120
-
- So, they all have a different number of scripts.
- */
- } else if (buf[4] == '0' && buf[5] == 'R') {
- // newer V3 game
- if (g->version != 3)
- break;
- // Candidates: indy3, indy3Towns, zakTowns, loomTowns
- /*
- Considering that we know about *all* TOWNS versions,
- and know their MD5s, we could simply rely on this and
- if we find something which has an unknown MD5, assume
- that it is an (so far unknown) version of Indy3.
-
- We can combin this with a look at the resource headers:
-
- Indy3:
- _numGlobalObjects 1000
- _numRooms 99
- _numCostumes 129
- _numScripts 139
- _numSounds 84
-
- Indy3Towns, ZakTowns, ZakLoom demo:
- _numGlobalObjects 1000
- _numRooms 99
- _numCostumes 199
- _numScripts 199
- _numSounds 199
-
- Assuming that all the town variants look like the latter, we can
- do the chceck like this:
- if (numScripts == 139)
- assume Indy3
- else if (numScripts == 199)
- assume towns game
- else
- unknown, do not accept it
- */
- } else if (buf[4] == 'R' && buf[5] == 'N') {
- // V4 game
- if (g->version != 4)
- break;
- // Candidates: monkeyEGA, pass, monkeyVGA, loomcd
- /*
- For all of them, we have:
- _numGlobalObjects 1000
- _numRooms 99
- _numCostumes 199
- _numScripts 199
- _numSounds 199
- */
- } else if (buf[0] == 0xa0 && buf[1] == 0x07 && buf[2] == 0xa5 &&
- buf[3] == 0xbc) {
- // MM NES .prg
- if (g->id != GID_MANIAC)
- break;
- } else if (buf[0] == 0xbc && buf[1] == 0xb9) {
- // MM NES 00.LFL
- if (g->id != GID_MANIAC)
- break;
- } else if (buf[0] == 0x31 && buf[1] == 0x0a) {
- // C64 MM & Zak disk1
- if (g->version != 2)
- break;
- } else if (buf[0] == 0xcd && buf[1] == 0xfe) {
- // C64 MM & Zak 00.LFL
- if (g->version != 2)
- break;
- } else {
- // This is not a V1-V4 game
- break;
- }
- }
-
- // Match found, add to list of candidates, then abort inner loop.
- if (substLastIndex > 0 && // HE Mac versions.
- (substResFileNameTable[substLastIndex].genMethod == kGenMac ||
- substResFileNameTable[substLastIndex].genMethod == kGenMacNoParens)) {
- detectedGames.push_back(DetectedGame(g->toGameSettings(),
- Common::UNK_LANG,
- Common::kPlatformMacintosh));
- fileSet[file->path()] = true;
- } else if (substLastIndex == 0 && g->id == GID_MANIAC &&
- (buf[0] == 0xbc || buf[0] == 0xa0)) {
- detectedGames.push_back(DetectedGame(g->toGameSettings(),
- Common::UNK_LANG,
- Common::kPlatformNES));
- } else if ((g->id == GID_MANIAC || g->id == GID_ZAK) &&
- ((buf[0] == 0x31 && buf[1] == 0x0a) ||
- (buf[0] == 0xcd && buf[1] == 0xfe))) {
- detectedGames.push_back(DetectedGame(g->toGameSettings(),
- Common::UNK_LANG,
- Common::kPlatformC64));
- } else {
- detectedGames.push_back(g->toGameSettings());
- fileSet[file->path()] = false;
- }
- break;
- }
- }
- }
-
- substLastIndex = generateSubstResFileName_(tempName, detectName, sizeof(detectName), substLastIndex+1);
- }
- }
- }
-
- // Now, we check the MD5 sums of the 'candidate' files. If we have an exact match,
- // only return that.
- bool exactMatch = false;
- for (StringSet::const_iterator iter = fileSet.begin(); iter != fileSet.end(); ++iter) {
- uint8 md5sum[16];
- const char *name = iter->_key.c_str();
-
- if (Common::md5_file(name, md5sum, 0, kMD5FileSizeLimit)) {
- char md5str[32+1];
- for (int j = 0; j < 16; j++) {
- sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
- }
-
- const MD5Table *elem;
- elem = (const MD5Table *)bsearch(md5str, md5table, ARRAYSIZE(md5table)-1, sizeof(MD5Table), compareMD5Table);
- if (elem) {
- if (!exactMatch)
- detectedGames.clear(); // Clear all the non-exact candidates
-
- const char *gameid = elem->gameid;
-
- // Find the GameSettings for that gameid
- for (g = scumm_settings; g->gameid; ++g) {
- if (0 == scumm_stricmp(g->gameid, gameid))
- break;
- }
- assert(g->gameid);
- // Insert the 'enhanced' game data into the candidate list
- if (iter->_value == true) // This was HE Mac game
- detectedGames.push_back(DetectedGame(g->toGameSettings(), elem->language, Common::kPlatformMacintosh));
- else
- detectedGames.push_back(DetectedGame(g->toGameSettings(), elem->language, elem->platform));
- exactMatch = true;
- }
- }
- }
-
- return detectedGames;
-}
-
-static int generateSubstResFileName_(const char *filename, char *buf, int bufsize, int index) {
- if (index <= 0)
- return -1;
-
- size_t len = strlen(filename);
- assert(len > 0);
-
- char num = filename[len - 1];
-
- // In some cases we have .(a) and .(b) extensions
- if (num == ')')
- num = filename[len - 2];
-
- const char *ext = strrchr(filename, '.');
- if (ext)
- len = ext - filename;
-
- for (int i = index; substResFileNameTable[i].winName; i++) {
- if (!scumm_strnicmp(filename, substResFileNameTable[i].winName, len)) {
- switch (substResFileNameTable[i].genMethod) {
- case kGenMac:
- case kGenMacNoParens:
- if (num == '3') { // special case for cursors
- // For mac they're stored in game binary
- strncpy(buf, substResFileNameTable[i].macName, bufsize);
- } else {
- if (substResFileNameTable[i].genMethod == kGenMac)
- snprintf(buf, bufsize, "%s (%c)", substResFileNameTable[i].macName, num);
- else
- snprintf(buf, bufsize, "%s %c", substResFileNameTable[i].macName, num);
- }
- break;
-
- case kGenPC:
- if (ext)
- snprintf(buf, bufsize, "%s%s", substResFileNameTable[i].macName, ext);
- else
- strncpy(buf, substResFileNameTable[i].macName, bufsize);
- break;
-
- case kGenAsIs:
- strncpy(buf, substResFileNameTable[i].macName, bufsize);
- break;
-
- default:
- *buf = 0;
- break;
- }
-
- return i;
- }
- }
- return -1;
-}
-
-/**
- * Create a ScummEngine instance, based on the given detector data.
- *
- * This is heavily based on our MD5 detection scheme.
- */
-Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) {
- Engine *engine;
-
- // We start by checking whether the specified game ID is obsolete.
- // If that is the case, we automaticlaly upgrade the target to use
- // the correct new game ID (and platform, if specified).
- const ObsoleteGameIDs *o = obsoleteGameIDsTable;
- while (o->from) {
- if (!scumm_stricmp(detector->_game.gameid, o->from)) {
- // Match found, perform upgrade
- detector->_game.gameid = o->to;
- ConfMan.set("gameid", o->to);
-
- if (o->platform != Common::kPlatformUnknown)
- ConfMan.set("platform", Common::getPlatformCode(o->platform));
-
- warning("Target upgraded from game ID %s to %s", o->from, o->to);
- ConfMan.flushToDisk();
- break;
- }
- o++;
- }
-
- // Lookup the game ID in our database. If this lookup fails, then
- // the game ID is unknown, and we have to abort.
- const ScummGameSettings *g = scumm_settings;
- while (g->gameid) {
- if (!scumm_stricmp(detector->_game.gameid, g->gameid))
- break;
- g++;
- }
- if (!g->gameid) {
- return 0;
- }
-
- // We now want to alculate the MD5 of the games detection file, so that we
- // can store it in savegames etc..
- const char *gameid = g->gameid;
- char detectName[256], tempName[256], gameMD5[32+1];
- uint8 md5sum[16];
- int substLastIndex = 0;
- bool found = false;
-
- ScummGameSettings game = *g;
-
- // To this end, we first have to figure out what the proper detection file
- // is (00.LFL, 000.LFL, ...). So we iterate over all possible names,
- // and once we find a matching file, we assume that's it.
- for (int method = 0; method < kDetectNameMethodsCount && !found; method++) {
- if (!generateDetectName(g, method, detectName))
- continue;
-
- strcpy(tempName, detectName);
-
- substLastIndex = 0;
- while (substLastIndex != -1) {
- // FIXME: Repeatedly calling File::exists like this is a bad idea.
- // Instead, use the fs.h code to get a list of all files in that
- // directory and simply check whether that filename is contained
- // in it.
- if (File::exists(detectName, ConfMan.get("path").c_str())) {
- found = true;
- break;
- }
-
- substLastIndex = generateSubstResFileName_(tempName, detectName, sizeof(detectName), substLastIndex + 1);
- }
- if (found) {
- if (substLastIndex != 0)
- debug(5, "Generated filename substitute: %s -> %s", tempName, detectName);
- break;
- }
- }
-
- // Unable to locate game data
- if (!found) {
- return 0;
- }
-
- // Force game to have Mac platform if needed
- if (substLastIndex > 0) {
- if (substResFileNameTable[substLastIndex].genMethod == kGenMac ||
- substResFileNameTable[substLastIndex].genMethod == kGenMacNoParens)
- game.platform = Common::kPlatformMacintosh;
- }
-
- // Compute the MD5 of the file, and (if we succeeded) store a hex version
- // of it in gameMD5 (useful to print it to the user in messages).
- if (Common::md5_file(detectName, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) {
- for (int j = 0; j < 16; j++) {
- sprintf(gameMD5 + j*2, "%02x", (int)md5sum[j]);
- }
- }
-
- // Check if the MD5 was overwritten, if so, use that in the subsequent search
- const char *md5;
- if (ConfMan.hasKey("target_md5")) {
- md5 = ConfMan.get("target_md5").c_str();
- } else {
- md5 = gameMD5;
- }
-
- // Now search our 'database' for the MD5; if a match is found, we use
- // the information in the 'database' to correct the GameSettings.
- g = multiple_versions_md5_settings;
- while (g->gameid) {
- if (!scumm_stricmp(md5, g->gameid)) {
- // Match found
- game = *g;
- game.gameid = gameid; // FIXME: Fingolfin wonders what this line is good for?
- if (game.description)
- g_system->setWindowCaption(game.description);
- break;
- }
- g++;
- }
-
- // Starting from version 7.1, HE games use 640x480. We check this here since multiple
- // versions _could_ use different resolutions (I haven't verified this, though).
- if (game.heversion >= 71) {
- game.features |= GF_DEFAULT_TO_1X_SCALER;
- }
-
-
- // Check for a user override of the platform. We allow the user to override
- // the platform, to make it possible to add games which are not yet in
- // our MD5 database but require a specific platform setting.
- if (ConfMan.hasKey("platform"))
- game.platform = Common::parsePlatform(ConfMan.get("platform"));
-
-
- // V3 FM-TOWNS games *always* should use the corresponding music driver,
- // anything else makes no sense for them.
- if (game.platform == Common::kPlatformFMTowns && game.version == 3) {
- game.midi = MDT_TOWNS;
- }
-
- // Finally, we have massaged the GameSettings to our satisfaction, and can
- // instantiate the appropriate game engine. Hooray!
- switch (game.version) {
- case 1:
- case 2:
- if (game.id == GID_MANIAC && game.platform == Common::kPlatformC64)
- engine = new ScummEngine_c64(detector, syst, game, md5sum, substLastIndex);
- else
- engine = new ScummEngine_v2(detector, syst, game, md5sum, substLastIndex);
- break;
- case 3:
- if (game.features & GF_OLD_BUNDLE)
- engine = new ScummEngine_v3old(detector, syst, game, md5sum, substLastIndex);
- else
- engine = new ScummEngine_v3(detector, syst, game, md5sum, substLastIndex);
- break;
- case 4:
- engine = new ScummEngine_v4(detector, syst, game, md5sum, substLastIndex);
- break;
- case 5:
- engine = new ScummEngine_v5(detector, syst, game, md5sum, substLastIndex);
- break;
- case 6:
- switch (game.heversion) {
-#ifndef DISABLE_HE
- case 100:
- engine = new ScummEngine_v100he(detector, syst, game, md5sum, substLastIndex);
- break;
- case 99:
- engine = new ScummEngine_v99he(detector, syst, game, md5sum, substLastIndex);
- break;
- case 98:
- case 95:
- case 90:
- engine = new ScummEngine_v90he(detector, syst, game, md5sum, substLastIndex);
- break;
- case 80:
- engine = new ScummEngine_v80he(detector, syst, game, md5sum, substLastIndex);
- break;
- case 73:
- case 72:
- engine = new ScummEngine_v72he(detector, syst, game, md5sum, substLastIndex);
- break;
- case 71:
- engine = new ScummEngine_v71he(detector, syst, game, md5sum, substLastIndex);
- break;
- case 70:
- engine = new ScummEngine_v70he(detector, syst, game, md5sum, substLastIndex);
- break;
-#endif
-#ifndef PALMOS_68K
- case 61:
- engine = new ScummEngine_v60he(detector, syst, game, md5sum, substLastIndex);
- break;
-#endif
- default:
- engine = new ScummEngine_v6(detector, syst, game, md5sum, substLastIndex);
- }
- break;
-#ifndef DISABLE_SCUMM_7_8
- case 7:
- engine = new ScummEngine_v7(detector, syst, game, md5sum, substLastIndex);
- break;
- case 8:
- engine = new ScummEngine_v8(detector, syst, game, md5sum, substLastIndex);
- break;
-#endif
- default:
- error("Engine_SCUMM_create(): Unknown version of game engine");
- }
-
- return engine;
-}
-
-REGISTER_PLUGIN(SCUMM, "Scumm Engine")
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Scumm_md5table)
-_GSETPTR(md5table, GBVARS_MD5TABLE_INDEX, MD5Table, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Scumm_md5table)
-_GRELEASEPTR(GBVARS_MD5TABLE_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/scumm.h b/scumm/scumm.h
deleted file mode 100644
index 5509378371..0000000000
--- a/scumm/scumm.h
+++ /dev/null
@@ -1,1369 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCUMM_H
-#define SCUMM_H
-
-#include "base/engine.h"
-#include "common/file.h"
-#include "common/rect.h"
-#include "common/str.h"
-#include "graphics/surface.h"
-
-#include "scumm/gfx.h"
-#include "scumm/script.h"
-
-#include "sound/mididrv.h"
-
-namespace GUI {
- class Dialog;
-}
-using GUI::Dialog;
-class GameDetector;
-namespace Common {
- class InSaveFile;
- class OutSaveFile;
-}
-
-namespace Scumm {
-
-class Actor;
-class BaseCostumeLoader;
-class BaseCostumeRenderer;
-class BaseScummFile;
-class CharsetRenderer;
-class IMuse;
-class IMuseDigital;
-class Insane;
-class MusicEngine;
-class ScummEngine;
-class ScummDebugger;
-class Serializer;
-class Sound;
-
-struct Box;
-struct BoxCoords;
-struct FindObjectInRoom;
-struct ScummGameSettings;
-
-// Use g_scumm from error() ONLY
-extern ScummEngine *g_scumm;
-
-/* System Wide Constants */
-enum {
- NUM_SENTENCE = 6,
- NUM_SHADOW_PALETTE = 8
-};
-
-/**
- * SCUMM feature flags define for every game which specific set of engine
- * features are used by that game.
- * Note that some of them could be replaced by checks for the SCUMM version.
- */
-enum GameFeatures {
- /** Games with the new camera system (ScummEngine_v7 and subclasses). */
- GF_NEW_CAMERA = 1 << 1,
-
- /** Games with the AKOS costume system (ScummEngine_v7 and subclasses, HE games). */
- GF_NEW_COSTUMES = 1 << 2,
-
- /** Games with digital iMUSE (ScummEngine_v7 and subclasses). */
- GF_DIGI_IMUSE = 1 << 3,
-
- /** Games using XOR encrypted data files. */
- GF_USE_KEY = 1 << 4,
-
- /** Small header games (ScummEngine_v4 and subclasses). */
- GF_SMALL_HEADER = 1 << 5,
-
- /** Old bundle games (ScummEngine_v3old and subclasses). */
- GF_OLD_BUNDLE = 1 << 6,
-
- /** EGA games. */
- GF_16COLOR = 1 << 7,
-
- /** VGA versions of V3 games. Equivalent to (version == 3 && not GF_16COLOR) */
- GF_OLD256 = 1 << 8,
-
- /** Games which have Audio CD tracks. */
- GF_AUDIOTRACKS = 1 << 9,
-
- /** Games without actor scaling (ScummEngine_v3 and subclasses). */
- GF_NO_SCALING = 1 << 10,
-
- /**
- * Games using only very few local variables in scripts.
- * Apparently that is only the case for 256 color version of Indy3.
- */
- GF_FEW_LOCALS = 1 << 11,
-
- /** HE games without cursor resources */
- GF_HE_CURSORLESS = 1 << 12,
-
- /** HE games for which localized versions exist */
- GF_HE_LOCALIZED = 1 << 13,
-
- /**
- * HE Games with more global scripts and different sprite handling
- * i.e. read it as HE version 9.85. Used for HE98 only.
- */
- GF_HE_985 = 1 << 14,
-
- /** HE games with 16 bit color */
- GF_16BIT_COLOR = 1 << 15,
-
- /** HE games which use sprites for subtitles */
- GF_HE_NOSUBTITLES = 1 << 16,
-
- /** A demo, not a full blown game. */
- GF_DEMO = 1 << 17
-};
-
-/* SCUMM Debug Channels */
-void CDECL debugC(int level, const char *s, ...);
-
-struct dbgChannelDesc {
- const char *channel, *desc;
- uint32 flag;
-};
-
-enum {
- DEBUG_GENERAL = 1 << 0, // General debug
- DEBUG_SCRIPTS = 1 << 2, // Track script execution (start/stop/pause)
- DEBUG_OPCODES = 1 << 3, // Track opcode invocations
- DEBUG_VARS = 1 << 4, // Track variable changes
- DEBUG_RESOURCE = 1 << 5, // Track resource loading / allocation
- DEBUG_IMUSE = 1 << 6, // Track iMUSE events
- DEBUG_SOUND = 1 << 7, // General Sound Debug
- DEBUG_ACTORS = 1 << 8, // General Actor Debug
- DEBUG_INSANE = 1 << 9, // Track INSANE
- DEBUG_SMUSH = 1 << 10 // Track SMUSH
-};
-
-/**
- * Internal header for any memory block allocated by the resource manager.
- *
- * @todo Hide MemBlkHeader; no code outside the resource manager should
- * have to use it, ever. Currently script code needs it to detect whether
- * some scripts have moved (in fetchScriptByte()).
- */
-struct MemBlkHeader {
- uint32 size;
-};
-
-struct VerbSlot;
-struct ObjectData;
-
-enum {
- LIGHTMODE_dark = 0,
- LIGHTMODE_actor_base = 1,
- LIGHTMODE_screen = 2,
- LIGHTMODE_flashlight = 4,
- LIGHTMODE_actor_color = 8
-};
-
-enum {
- MBS_LEFT_CLICK = 0x8000,
- MBS_RIGHT_CLICK = 0x4000,
- MBS_MOUSE_MASK = (MBS_LEFT_CLICK | MBS_RIGHT_CLICK),
- MBS_MAX_KEY = 0x0200
-};
-
-enum ScummGameId {
- GID_CMI,
- GID_DIG,
- GID_FT,
- GID_INDY3,
- GID_INDY4,
- GID_LOOM,
- GID_MANIAC,
- GID_MONKEY_EGA,
- GID_MONKEY_VGA,
- GID_MONKEY,
- GID_MONKEY2,
- GID_PASS,
- GID_SAMNMAX,
- GID_TENTACLE,
- GID_ZAK,
-
- GID_HEGAME, // Generic name for all HE games with default behaviour
- GID_PUTTDEMO,
- GID_FBEAR,
- GID_FUNPACK,
- GID_WATER,
- GID_PUTTRACE,
- GID_FUNSHOP, // Used for all three funshops
- GID_FOOTBALL
-};
-
-struct SentenceTab {
- byte verb;
- byte preposition;
- uint16 objectA;
- uint16 objectB;
- uint8 freezeCount;
-};
-
-struct StringSlot {
- int16 xpos;
- int16 ypos;
- int16 right;
- int16 height;
- byte color;
- byte charset;
- bool center;
- bool overhead;
- bool no_talk_anim;
-};
-
-struct StringTab : StringSlot {
- // The 'default' values for this string slot. This is used so that the
- // string slot can temporarily be set to different values, and then be
- // easily reset to a previously set default.
- StringSlot _default;
-
- void saveDefault() {
- StringSlot &s = *this;
- _default = s;
- }
-
- void loadDefault() {
- StringSlot &s = *this;
- s = _default;
- }
-};
-
-
-
-enum WhereIsObject {
- WIO_NOT_FOUND = -1,
- WIO_INVENTORY = 0,
- WIO_ROOM = 1,
- WIO_GLOBAL = 2,
- WIO_LOCAL = 3,
- WIO_FLOBJECT = 4
-};
-
-struct AuxBlock {
- bool visible;
- Common::Rect r;
-
- void reset() {
- visible = false;
- r.left = r.top = 0;
- r.right = r.bottom = -1;
- }
-};
-
-struct AuxEntry {
- int actorNum;
- int subIndex;
-};
-
-// TODO: Rename InfoStuff to something more descriptive
-struct InfoStuff {
- uint32 date;
- uint16 time;
- uint32 playtime;
-};
-
-/**
- * A list of resource types.
- * WARNING: Do not change the order of these, as the savegame format relies
- * on it; any change made here will break savegame compatibility!
- */
-enum ResTypes {
- rtFirst = 1,
- rtRoom = 1,
- rtScript = 2,
- rtCostume = 3,
- rtSound = 4,
- rtInventory = 5,
- rtCharset = 6,
- rtString = 7,
- rtVerb = 8,
- rtActorName = 9,
- rtBuffer = 10,
- rtScaleTable = 11,
- rtTemp = 12,
- rtFlObject = 13,
- rtMatrix = 14,
- rtBox = 15,
- rtObjectName = 16,
- rtRoomScripts = 17,
- rtRoomImage = 18,
- rtImage = 19,
- rtTalkie = 20,
- rtSpoolBuffer = 21,
- rtLast = 21,
- rtNumTypes = 22
-};
-
-class ResourceManager {
- friend class ScummDebugger;
- friend class ScummEngine;
-protected:
- ScummEngine *_vm;
-
-public:
- byte mode[rtNumTypes];
- uint16 num[rtNumTypes];
- uint32 tags[rtNumTypes];
- const char *name[rtNumTypes];
- byte **address[rtNumTypes];
-protected:
- byte *flags[rtNumTypes];
- byte *status[rtNumTypes];
-public:
- byte *roomno[rtNumTypes];
- uint32 *roomoffs[rtNumTypes];
- uint32 *globsize[rtNumTypes];
-
- uint32 _allocatedSize;
- uint32 _maxHeapThreshold, _minHeapThreshold;
- byte _expireCounter;
-
-public:
- ResourceManager(ScummEngine *vm);
-
- byte *createResource(int type, int index, uint32 size);
- void nukeResource(int type, int i);
-
- void freeResources();
-
- bool isResourceLoaded(int type, int index) const;
-
- void lock(int type, int i);
- void unlock(int type, int i);
- bool isLocked(int type, int i) const;
-
- void setModified(int type, int i);
- bool isModified(int type, int i) const;
-
- void setResourceCounter(int type, int index, byte flag);
- void increaseResourceCounter();
-
- void resourceStats();
- void expireResources(uint32 size);
-
-protected:
- bool validateResource(const char *str, int type, int index) const;
-};
-
-class ScummEngine : public Engine {
- friend class ScummDebugger;
- friend class SmushPlayer;
- friend class Insane;
- friend class CharsetRenderer;
- friend class ResourceManager;
-
- void errorString(const char *buf_input, char *buf_output);
-public:
- /* Put often used variables at the top.
- * That results in a shorter form of the opcode
- * on some architectures. */
- IMuse *_imuse;
- IMuseDigital *_imuseDigital;
- MusicEngine *_musicEngine;
- Sound *_sound;
-
- VerbSlot *_verbs;
- ObjectData *_objs;
- ObjectData *_storedFlObjects;
- ScummDebugger *_debugger;
-
- // Core variables
- byte _gameId;
- byte _version;
- uint8 _heversion;
- uint32 _features; // Should only be accessed for reading (TODO enforce it compiler-wise with making it private and creating an accessor)
- Common::Platform _platform;
- uint8 _gameMD5[16];
-
- /** Random number generator */
- Common::RandomSource _rnd;
-
- /** Graphics manager */
- Gdi gdi;
-
- /** Central resource data. */
- ResourceManager res;
-
-protected:
- VirtualMachineState vm;
-
-public:
- // Constructor / Destructor
- ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex);
- virtual ~ScummEngine();
-
- /** Startup function, main loop. */
- int go();
-
- // Init functions
- int init(GameDetector &detector);
-
- virtual void setupScummVars();
- virtual void initScummVars();
-
- virtual void scummInit();
-
- void loadCJKFont();
- void setupMusic(int midi);
- void setupVolumes();
-
- // Scumm main loop
- int scummLoop(int delta);
-
- // Event handling
- void parseEvents();
- void waitForTimer(int msec_delay);
- void processKbd(bool smushMode);
- void clearClickedStatus();
-
- // Misc utility functions
- uint32 _debugFlags;
- const char *getBaseName() const { return _baseName.c_str(); }
-
- // Cursor/palette
- void updateCursor();
- virtual void animateCursor() {}
- virtual void updatePalette();
-
- /**
- * Flag which signals that the SMUSH video playback should end now
- * (e.g. because it was aborted by the user or it's simply finished).
- */
- bool _smushVideoShouldFinish;
- /** This flag is a hack to allow the pause dialog to pause SMUSH playback, too. */
- bool _smushPaused;
- /** This flag tells IMuseDigital that INSANE is running. */
- bool _insaneRunning;
-
-protected:
- Insane *_insane;
-
-public:
- void pauseGame();
- void restart();
- void shutDown();
-
- /** We keep running until this is set to true. */
- bool _quit;
-
-protected:
- Dialog *_pauseDialog;
- Dialog *_versionDialog;
- Dialog *_mainMenuDialog;
-
- int runDialog(Dialog &dialog);
- void confirmExitDialog();
- void confirmRestartDialog();
- void pauseDialog();
- void versionDialog();
- void mainMenuDialog();
-
- char displayMessage(const char *altButton, const char *message, ...);
-
- byte _fastMode;
-
- byte _numActors;
- Actor *_actors; // Has _numActors elements
- Actor **_sortedActors;
-
- byte *_arraySlot;
- uint16 *_inventory;
- uint16 *_newNames;
-public:
- // VAR is a wrapper around scummVar, which attempts to include additional
- // useful information should an illegal var access be detected.
- #define VAR(x) scummVar(x, #x, __FILE__, __LINE__)
- int32& scummVar(byte var, const char *varName, const char *file, int line)
- {
- if (var == 0xFF) {
- error("Illegal access to variable %s in file %s, line %d", varName, file, line);
- }
- return _scummVars[var];
- }
- int32 scummVar(byte var, const char *varName, const char *file, int line) const
- {
- if (var == 0xFF) {
- error("Illegal access to variable %s in file %s, line %d", varName, file, line);
- }
- return _scummVars[var];
- }
-
-protected:
- int16 _varwatch;
- int32 *_roomVars;
- int32 *_scummVars;
- byte *_bitVars;
-
- /* Global resource tables */
- int _numVariables, _numBitVariables, _numLocalObjects;
- int _numGlobalObjects, _numArray, _numVerbs, _numFlObject;
- int _numInventory;
- int _numNewNames, _numGlobalScripts;
- int _numRoomVariables;
- int _numPalettes, _numSprites, _numTalkies, _numUnk;
- int _numStoredFlObjects;
- int _HEHeapSize;
-public:
- int _numLocalScripts, _numImages, _numRooms, _numScripts, _numSounds; // Used by HE games
- int _numCostumes; // FIXME - should be protected, used by Actor::remapActorPalette
- int _numCharsets; // FIXME - should be protected, used by CharsetRenderer
-
- BaseCostumeLoader *_costumeLoader;
- BaseCostumeRenderer *_costumeRenderer;
-
- int _NESCostumeSet;
- void NES_loadCostumeSet(int n);
- byte *_NEScostdesc, *_NEScostlens, *_NEScostoffs, *_NEScostdata;
- byte _NESPatTable[2][4096];
- byte _NESPalette[2][16];
- byte _NESBaseTiles;
-
- int _NESStartStrip;
-
-protected:
- /* Current objects - can go in their respective classes */
- byte _curActor;
- int _curVerb;
- int _curVerbSlot;
- int _curPalIndex;
-
-public:
- byte _currentRoom; // FIXME - should be protected but Actor::isInCurrentRoom uses it
- int _roomResource; // FIXME - should be protected but Sound::pauseSounds uses it
- bool _egoPositioned; // Used by Actor::putActor, hence public
-
- int generateSubstResFileName(const char *filename, char *buf, int bufsize, int index = -3);
- int _substResFileNameIndex;
- int _substResFileNameIndexBundle; // Used with Mac bundles
-
-protected:
- int _keyPressed;
- uint16 _lastKeyHit;
- bool _keyDownMap[512]; // FIXME - 512 is a guess. it's max(kbd.ascii)
-
- Common::Point _mouse;
- Common::Point _virtualMouse;
-
- uint16 _mouseAndKeyboardStat;
- byte _leftBtnPressed, _rightBtnPressed;
-
- /** The bootparam, to be passed to the script 1, the bootscript. */
- int _bootParam;
-
- // Various options useful for debugging
- bool _dumpScripts;
- bool _hexdumpScripts;
- bool _showStack;
- uint16 _debugMode;
-
- // Save/Load class - some of this may be GUI
- byte _saveLoadFlag, _saveLoadSlot;
- uint32 _lastSaveTime;
- bool _saveTemporaryState;
- char _saveLoadName[32];
-
- bool saveState(int slot, bool compat);
- bool loadState(int slot, bool compat);
- virtual void saveOrLoad(Serializer *s);
- void saveLoadResource(Serializer *ser, int type, int index); // "Obsolete"
- void saveResource(Serializer *ser, int type, int index);
- void loadResource(Serializer *ser, int type, int index);
- void makeSavegameName(char *out, int slot, bool temporary);
-
- int getKeyState(int key);
-
-public:
- bool getSavegameName(int slot, char *desc);
- void listSavegames(bool *marks, int num);
-
- void requestSave(int slot, const char *name, bool temporary = false);
- void requestLoad(int slot);
-
-// thumbnail + info stuff
-public:
- Graphics::Surface *loadThumbnailFromSlot(int slot);
- bool loadInfosFromSlot(int slot, InfoStuff *stuff);
-
-protected:
- Graphics::Surface *loadThumbnail(Common::InSaveFile *file);
- bool loadInfos(Common::InSaveFile *file, InfoStuff *stuff);
- void saveThumbnail(Common::OutSaveFile *file);
- void saveInfos(Common::OutSaveFile* file);
-
- int32 _engineStartTime;
- int32 _dialogStartTime;
-
-protected:
- /* Script VM - should be in Script class */
- uint32 _localScriptOffsets[1024];
- const byte *_scriptPointer, *_scriptOrgPointer;
- byte _opcode, _currentScript;
- const byte * const *_lastCodePtr;
- int _resultVarNumber, _scummStackPos;
- int _vmStack[150];
- int _keyScriptKey, _keyScriptNo;
-
- // See the ScummEngine constructor and checkAndRunSentenceScript()
- int _defaultFTSentenceScript, _buggyFTSentenceScript;
-
- virtual void setupOpcodes() = 0;
- virtual void executeOpcode(byte i) = 0;
- virtual const char *getOpcodeDesc(byte i) = 0;
-
- void initializeLocals(int slot, int *vars);
- int getScriptSlot();
-
- void startScene(int room, Actor *a, int b);
- void startManiac();
-
-public:
- void runScript(int script, bool freezeResistant, bool recursive, int *lvarptr, int cycle = 0);
- void stopScript(int script);
- void nukeArrays(byte scriptSlot);
-
-protected:
- void runObjectScript(int script, int entry, bool freezeResistant, bool recursive, int *vars, int slot = -1, int cycle = 0);
- void runScriptNested(int script);
- void executeScript();
- void updateScriptPtr();
- virtual void runInventoryScript(int i);
- void inventoryScript();
- void checkAndRunSentenceScript();
- void runExitScript();
- void runEntryScript();
- void runAllScripts();
- void freezeScripts(int scr);
- void unfreezeScripts();
-
- bool isScriptInUse(int script) const;
- bool isRoomScriptRunning(int script) const;
- bool isScriptRunning(int script) const;
-
- void killAllScriptsExceptCurrent();
- void killScriptsAndResources();
- void decreaseScriptDelay(int amount);
-
- void stopObjectCode();
- void stopObjectScript(int script);
-
- void getScriptBaseAddress();
- void getScriptEntryPoint();
- int getVerbEntrypoint(int obj, int entry);
-
- byte fetchScriptByte();
- virtual uint fetchScriptWord();
- virtual int fetchScriptWordSigned();
- uint fetchScriptDWord();
- int fetchScriptDWordSigned();
- void ignoreScriptWord() { fetchScriptWord(); }
- void ignoreScriptByte() { fetchScriptByte(); }
- virtual void getResultPos();
- void setResult(int result);
- void push(int a);
- int pop();
- virtual int readVar(uint var);
- virtual void writeVar(uint var, int value);
-
- void beginCutscene(int *args);
- void endCutscene();
- void abortCutscene();
- void beginOverride();
- void endOverride();
-
- void copyScriptString(byte *dst);
- int resStrLen(const byte *src) const;
- void doSentence(int c, int b, int a);
-
- /* Should be in Resource class */
- BaseScummFile *_fileHandle;
- uint32 _fileOffset;
-public:
- /** The name of the (macintosh/rescumm style) container file, if any. */
- Common::String _containerFile;
-
- bool openFile(BaseScummFile &file, const char *filename, bool resourceFile = false);
-
-protected:
- int _resourceHeaderSize;
- Common::String _baseName; // This is the name we use for opening resource files
- Common::String _targetName; // This is the game the user calls it, so use for saving
- byte _resourceMapper[128];
- byte *_heV7DiskOffsets;
- uint32 *_heV7RoomIntOffsets;
- const byte *_resourceLastSearchBuf; // FIXME: need to put it to savefile?
- uint32 _resourceLastSearchSize; // FIXME: need to put it to savefile?
-
- virtual void allocateArrays();
- void openRoom(int room);
- void closeRoom();
- void deleteRoomOffsets();
- virtual void readRoomsOffsets();
- void askForDisk(const char *filename, int disknum);
- bool openResourceFile(const char *filename, byte encByte);
-
- void loadPtrToResource(int type, int i, const byte *ptr);
- virtual void readResTypeList(int id, uint32 tag, const char *name);
- void allocResTypeData(int id, uint32 tag, int num, const char *name, int mode);
-// byte *createResource(int type, int index, uint32 size);
- int loadResource(int type, int i);
-// void nukeResource(int type, int i);
- int getResourceSize(int type, int idx);
-
-public:
- byte *getResourceAddress(int type, int i);
- virtual byte *getStringAddress(int i);
- byte *getStringAddressVar(int i);
- void ensureResourceLoaded(int type, int i);
- int getResourceRoomNr(int type, int index);
-
-protected:
- int readSoundResource(int type, int index);
- int convert_extraflags(byte *ptr, byte * src_ptr);
- void convertMac0Resource(int type, int index, byte *ptr, int size);
- void convertADResource(int type, int index, byte *ptr, int size);
- int readSoundResourceSmallHeader(int type, int index);
- bool isResourceInUse(int type, int i) const;
- virtual void loadRoomSubBlocks();
- virtual void initRoomSubBlocks();
- void clearRoomObjects();
- void storeFlObject(int slot);
- void restoreFlObjects();
- virtual void loadRoomObjects();
-
- virtual void readArrayFromIndexFile();
- virtual void readMAXS(int blockSize) = 0;
- virtual void readGlobalObjects();
- virtual void readIndexFile();
- virtual void readIndexBlock(uint32 block, uint32 itemsize);
- virtual void loadCharset(int i);
- void nukeCharset(int i);
-
- int _lastLoadedRoom;
-public:
- const byte *findResourceData(uint32 tag, const byte *ptr);
- const byte *findResource(uint32 tag, const byte *ptr);
- int getResourceDataSize(const byte *ptr) const;
- void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
-
-public:
- /* Should be in Object class */
- byte OF_OWNER_ROOM;
- int getInventorySlot();
- int findInventory(int owner, int index);
- int getInventoryCount(int owner);
-
-protected:
- byte *_objectOwnerTable, *_objectRoomTable, *_objectStateTable;
- int _numObjectsInRoom;
-
-public:
- uint32 *_classData;
-
-protected:
- virtual void setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
- void markObjectRectAsDirty(int obj);
- void loadFlObject(uint object, uint room);
- void nukeFlObjects(int min, int max);
- int findFlObjectSlot();
- int findLocalObjectSlot();
- void addObjectToInventory(uint obj, uint room);
- void updateObjectStates();
-public:
- bool getClass(int obj, int cls) const; // Used in actor.cpp, hence public
-protected:
- void putClass(int obj, int cls, bool set);
- int getState(int obj);
- void putState(int obj, int state);
- void setObjectState(int obj, int state, int x, int y);
- int getOwner(int obj) const;
- void putOwner(int obj, int owner);
- void setOwnerOf(int obj, int owner);
- void clearOwnerOf(int obj);
- int getObjectRoom(int obj) const;
- int getObjX(int obj);
- int getObjY(int obj);
- void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); }
- void getObjectXYPos(int object, int &x, int &y, int &dir);
- int getObjOldDir(int obj);
- int getObjNewDir(int obj);
- int getObjectIndex(int object) const;
- int getObjectImageCount(int object);
- int whereIsObject(int object) const;
- int findObject(int x, int y);
- void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
-public:
- int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
-protected:
- int getObjActToObjActDist(int a, int b); // Not sure how to handle
- const byte *getObjOrActorName(int obj); // these three..
- void setObjectName(int obj);
-
- void addObjectToDrawQue(int object);
- void removeObjectFromDrawQue(int object);
- void clearDrawObjectQueue();
- void processDrawQue();
-
- virtual void clearDrawQueues();
-
- uint32 getOBCDOffs(int object) const;
- byte *getOBCDFromObject(int obj);
- const byte *getOBIMFromObjectData(const ObjectData &od);
- const byte *getObjectImage(const byte *ptr, int state);
- virtual int getObjectIdFromOBIM(const byte *obim);
-
- int getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f);
-
-protected:
- /* Should be in Verb class */
- uint16 _verbMouseOver;
- int _inventoryOffset;
- int8 _userPut;
- uint16 _userState;
-
- int _activeObject;
-
- virtual void handleMouseOver(bool updateInventory);
- virtual void redrawVerbs();
- virtual void checkExecVerbs();
-
- void verbMouseOver(int verb);
- int findVerbAtPos(int x, int y) const;
- virtual void drawVerb(int verb, int mode);
- void runInputScript(int a, int cmd, int mode);
- void restoreVerbBG(int verb);
- void drawVerbBitmap(int verb, int x, int y);
- int getVerbSlot(int id, int mode) const;
- void killVerb(int slot);
- void setVerbObject(uint room, uint object, uint verb);
-
-public:
- bool isValidActor(int id) const;
-
- /* Should be in Actor class */
- Actor *derefActor(int id, const char *errmsg = 0) const;
- Actor *derefActorSafe(int id, const char *errmsg) const;
-
- int getAngleFromPos(int x, int y) const;
-
-protected:
- void walkActors();
- void playActorSounds();
- void redrawAllActors();
- void setActorRedrawFlags();
- void putActors();
- void showActors();
- void setupV1ActorTalkColor();
- void resetActorBgs();
- virtual void processActors();
- void processUpperActors();
- virtual int getActorFromPos(int x, int y);
-
-public:
- /* Actor talking stuff */
- byte _actorToPrintStrFor, _V1TalkingActor;
- int _sentenceNum;
- SentenceTab _sentence[NUM_SENTENCE];
- StringTab _string[6];
- int16 _talkDelay;
- int _NES_lastTalkingActor;
- int _NES_talkColor;
-
- virtual void actorTalk(const byte *msg);
- void stopTalk();
- int getTalkingActor(); // Wrapper around VAR_TALK_ACTOR for V1 Maniac
- void setTalkingActor(int variable);
-
- // Generic costume code
- bool isCostumeInUse(int i) const;
-
- // Akos Class
- struct {
- int16 cmd;
- int16 actor;
- int16 param1;
- int16 param2;
- } _akosQueue[32];
- int16 _akosQueuePos;
-
- Common::Rect _actorClipOverride;
-
- bool akos_increaseAnims(const byte *akos, Actor *a);
- bool akos_increaseAnim(Actor *a, int i, const byte *aksq, const uint16 *akfo, int numakfo);
- void akos_queCommand(byte cmd, Actor *a, int param_1, int param_2);
- virtual void akos_processQueue();
-
-protected:
- /* Should be in Graphics class? */
- uint16 _screenB, _screenH;
-public:
- int _roomHeight, _roomWidth;
- int _screenHeight, _screenWidth;
- VirtScreen virtscr[4]; // Virtual screen areas
- CameraData camera; // 'Camera' - viewport
-
- int _screenStartStrip, _screenEndStrip;
- int _screenTop;
-
- Common::RenderMode _renderMode;
-
-protected:
- ColorCycle _colorCycle[16]; // Palette cycles
- uint8 _colorUsedByCycle[256];
-
- uint32 _ENCD_offs, _EXCD_offs;
- uint32 _CLUT_offs, _EPAL_offs;
- uint32 _IM00_offs, _PALS_offs;
-
- //ender: fullscreen
- bool _fullRedraw, _bgNeedsRedraw;
- bool _screenEffectFlag, _completeScreenRedraw;
-
- struct {
- int hotspotX, hotspotY, width, height;
- byte animate, animateIndex;
- int8 state;
- } _cursor;
- byte _grabbedCursor[8192];
- byte _currentCursor;
-
- byte _newEffect, _switchRoomEffect2, _switchRoomEffect;
- bool _doEffect;
-
- byte *_scrollBuffer;
-
- struct {
- int x, y, w, h;
- byte *buffer;
- uint16 xStrips, yStrips;
- bool isDrawn;
- } _flashlight;
-
-public:
- bool isLightOn() const;
-
-protected:
- void initScreens(int b, int h);
- void initVirtScreen(VirtScreenNumber slot, int top, int width, int height, bool twobufs, bool scrollable);
- void initBGBuffers(int height);
- void initCycl(const byte *ptr); // Color cycle
-
- void decodeNESBaseTiles();
-
- void drawObject(int obj, int arg);
- void drawRoomObjects(int arg);
- void drawRoomObject(int i, int arg);
- void drawBox(int x, int y, int x2, int y2, int color);
-
- void restoreBG(Common::Rect rect, byte backcolor = 0);
- void redrawBGStrip(int start, int num);
- virtual void redrawBGAreas();
-
- void cameraMoved();
- void setCameraAtEx(int at);
- virtual void setCameraAt(int pos_x, int pos_y);
- virtual void setCameraFollows(Actor *a);
- virtual void moveCamera();
- virtual void panCameraTo(int x, int y);
- void clampCameraPos(Common::Point *pt);
- void actorFollowCamera(int act);
-
- const byte *getPalettePtr(int palindex, int room);
- void setupC64Palette();
- void setupNESPalette();
- void setupAmigaPalette();
- void setupHercPalette();
- void setupCGAPalette();
- void setupEGAPalette();
- void setupV1Palette();
- void setPalette(int pal);
- void setRoomPalette(int pal, int room);
- virtual void setPaletteFromPtr(const byte *ptr, int numcolor = -1);
- virtual void setPalColor(int index, int r, int g, int b);
- void setDirtyColors(int min, int max);
- const byte *findPalInPals(const byte *pal, int index);
- void swapPalColors(int a, int b);
- virtual void copyPalColor(int dst, int src);
- void cyclePalette();
- void stopCycle(int i);
- virtual void palManipulateInit(int resID, int start, int end, int time);
- void palManipulate();
-public:
- int remapPaletteColor(int r, int g, int b, int threshold); // Used by Actor::remapActorPalette
-protected:
- void moveMemInPalRes(int start, int end, byte direction);
- void setupShadowPalette(int slot, int redScale, int greenScale, int blueScale, int startColor, int endColor);
- void setupShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor, int start, int end);
- virtual void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
-
- void setupCursor();
-
- void setCursorFromBuffer(const byte *ptr, int width, int height, int pitch);
-
-public:
- void markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit = 0);
- void markRectAsDirty(VirtScreenNumber virt, const Common::Rect& rect, int dirtybit = 0) {
- markRectAsDirty(virt, rect.left, rect.right, rect.top, rect.bottom, dirtybit);
- }
-protected:
- // Screen rendering
- byte *_compositeBuf;
- byte *_herculesBuf;
- virtual void drawDirtyScreenParts();
- void updateDirtyScreen(VirtScreenNumber slot);
- void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
- void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
- void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const;
-
-public:
- VirtScreen *findVirtScreen(int y);
- byte *getMaskBuffer(int x, int y, int z);
-
-protected:
- void drawFlashlight();
-
- void fadeIn(int effect);
- void fadeOut(int effect);
-
- void unkScreenEffect6();
- void transitionEffect(int a);
- void dissolveEffect(int width, int height);
- void scrollEffect(int dir);
-
- // bomp
-public:
- byte *_bompActorPalettePtr;
- void drawBomp(const BompDrawData &bd, bool mirror);
-
-protected:
- bool _shakeEnabled;
- uint _shakeFrame;
- void setShake(int mode);
-
- int _drawObjectQueNr;
- byte _drawObjectQue[200];
-
- /* For each of the 410 screen strips, gfxUsageBits contains a
- * bitmask. The lower 80 bits each correspond to one actor and
- * signify if any part of that actor is currently contained in
- * that strip.
- *
- * If the leftmost bit is set, the strip (background) is dirty
- * needs to be redrawn.
- *
- * The second leftmost bit is set by removeBlastObject() and
- * restoreBG(), but I'm not yet sure why.
- */
- uint32 gfxUsageBits[410 * 3];
-
- void upgradeGfxUsageBits();
- void setGfxUsageBit(int strip, int bit);
- void clearGfxUsageBit(int strip, int bit);
- bool testGfxUsageBit(int strip, int bit);
- bool testGfxAnyUsageBits(int strip);
- bool testGfxOtherUsageBits(int strip, int bit);
-
-public:
- byte _roomPalette[256];
- byte *_shadowPalette;
- bool _skipDrawObject;
- int _voiceMode;
-
- // HE specific
- byte _HEV7ActorPalette[256];
- uint8 *_hePalettes;
-
- int _heTimers[16];
- int getHETimer(int timer);
- void setHETimer(int timer);
-
-protected:
- int _shadowPaletteSize;
- byte _currentPalette[3 * 256];
- byte _darkenPalette[3 * 256];
-
- int _palDirtyMin, _palDirtyMax;
-
- byte _palManipStart, _palManipEnd;
- uint16 _palManipCounter;
- byte *_palManipPalette;
- byte *_palManipIntermediatePal;
-
- byte _haveMsg;
- bool _haveActorSpeechMsg;
- bool _useTalkAnims;
- uint16 _defaultTalkDelay;
- int _tempMusic;
- int _saveSound;
- bool _native_mt32;
- bool _enable_gs;
- int _midi;
- MidiDriverFlags _musicType;
- bool _copyProtection;
- bool _demoMode;
- bool _confirmExit;
-
-public:
- uint16 _extraBoxFlags[65];
-
- byte getNumBoxes();
- byte *getBoxMatrixBaseAddr();
- int getPathToDestBox(byte from, byte to);
- void getGates(int trap1, int trap2, Common::Point gateA[2], Common::Point gateB[2]);
- bool inBoxQuickReject(int box, int x, int y, int threshold);
- int getClosestPtOnBox(int box, int x, int y, int16& outX, int16& outY);
- int getSpecialBox(int param1, int param2);
-
- void setBoxFlags(int box, int val);
- void setBoxScale(int box, int b);
-
- bool checkXYInBoxBounds(int box, int x, int y);
- uint distanceFromPt(int x, int y, int ptx, int pty);
- void getBoxCoordinates(int boxnum, BoxCoords *bc);
- byte getMaskFromBox(int box);
- Box *getBoxBaseAddr(int box);
- byte getBoxFlags(int box);
- int getBoxScale(int box);
-
- int getScale(int box, int x, int y);
- int getScaleFromSlot(int slot, int x, int y);
-
-protected:
- // Scaling slots/items
- struct ScaleSlot {
- int x1, y1, scale1;
- int x2, y2, scale2;
- };
- ScaleSlot _scaleSlots[20];
- void setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2);
- void setBoxScaleSlot(int box, int slot);
- void convertScaleTableToScaleSlot(int slot);
-
- void createBoxMatrix();
- bool areBoxesNeighbours(int i, int j);
-
- /* String class */
-public:
- CharsetRenderer *_charset;
- byte _charsetColorMap[16];
-protected:
- byte _charsetColor;
- byte _charsetData[15][16];
-
- int _charsetBufPos;
- byte _charsetBuffer[512];
-
- bool _keepText;
-
- virtual void initCharset(int charset);
-
- void printString(int m, const byte *msg);
-
- virtual bool handleNextCharsetCode(Actor *a, int *c);
- void CHARSET_1();
- void drawString(int a, const byte *msg);
- void debugMessage(const byte *msg);
- void showMessageDialog(const byte *msg);
-
- int convertMessageToString(const byte *msg, byte *dst, int dstSize);
- int convertIntMessage(byte *dst, int dstSize, int var);
- int convertVerbMessage(byte *dst, int dstSize, int var);
- int convertNameMessage(byte *dst, int dstSize, int var);
- int convertStringMessage(byte *dst, int dstSize, int var);
-
- virtual void loadLanguageBundle() {}
-
-public:
- Common::Language _language; // Accessed by a hack in NutRenderer::loadFont
-
- // Used by class ScummDialog:
- virtual void translateText(const byte *text, byte *trans_buff);
-
- // Somewhat hackish stuff for 2 byte support (Chinese/Japanese/Korean)
- bool _useCJKMode;
- int _2byteHeight;
- int _2byteWidth;
- byte *get2byteCharPtr(int idx);
-
-protected:
- byte *_2byteFontPtr;
-
- uint32 fileReadDword();
-
-public:
-
- /* Scumm Vars */
- byte VAR_LANGUAGE;
- byte VAR_KEYPRESS;
- byte VAR_SYNC;
- byte VAR_EGO;
- byte VAR_CAMERA_POS_X;
- byte VAR_HAVE_MSG;
- byte VAR_ROOM;
- byte VAR_OVERRIDE;
- byte VAR_MACHINE_SPEED;
- byte VAR_ME;
- byte VAR_NUM_ACTOR;
- byte VAR_CURRENT_LIGHTS;
- byte VAR_CURRENTDRIVE;
- byte VAR_CURRENTDISK;
- byte VAR_TMR_1;
- byte VAR_TMR_2;
- byte VAR_TMR_3;
- byte VAR_MUSIC_TIMER;
- byte VAR_ACTOR_RANGE_MIN;
- byte VAR_ACTOR_RANGE_MAX;
- byte VAR_CAMERA_MIN_X;
- byte VAR_CAMERA_MAX_X;
- byte VAR_TIMER_NEXT;
- byte VAR_VIRT_MOUSE_X;
- byte VAR_VIRT_MOUSE_Y;
- byte VAR_ROOM_RESOURCE;
- byte VAR_LAST_SOUND;
- byte VAR_CUTSCENEEXIT_KEY;
- byte VAR_OPTIONS_KEY;
- byte VAR_TALK_ACTOR;
- byte VAR_CAMERA_FAST_X;
- byte VAR_SCROLL_SCRIPT;
- byte VAR_ENTRY_SCRIPT;
- byte VAR_ENTRY_SCRIPT2;
- byte VAR_EXIT_SCRIPT;
- byte VAR_EXIT_SCRIPT2;
- byte VAR_VERB_SCRIPT;
- byte VAR_SENTENCE_SCRIPT;
- byte VAR_INVENTORY_SCRIPT;
- byte VAR_CUTSCENE_START_SCRIPT;
- byte VAR_CUTSCENE_END_SCRIPT;
- byte VAR_CHARINC;
- byte VAR_WALKTO_OBJ;
- byte VAR_DEBUGMODE;
- byte VAR_HEAPSPACE;
- byte VAR_RESTART_KEY;
- byte VAR_PAUSE_KEY;
- byte VAR_MOUSE_X;
- byte VAR_MOUSE_Y;
- byte VAR_TIMER;
- byte VAR_TMR_4;
- byte VAR_SOUNDCARD;
- byte VAR_VIDEOMODE;
- byte VAR_MAINMENU_KEY;
- byte VAR_FIXEDDISK;
- byte VAR_CURSORSTATE;
- byte VAR_USERPUT;
- byte VAR_SOUNDRESULT;
- byte VAR_TALKSTOP_KEY;
- byte VAR_FADE_DELAY;
- byte VAR_NOSUBTITLES;
-
- // V5+
- byte VAR_SOUNDPARAM;
- byte VAR_SOUNDPARAM2;
- byte VAR_SOUNDPARAM3;
- byte VAR_MOUSEPRESENT;
- byte VAR_MEMORY_PERFORMANCE;
- byte VAR_VIDEO_PERFORMANCE;
- byte VAR_ROOM_FLAG;
- byte VAR_GAME_LOADED;
- byte VAR_NEW_ROOM;
-
- // V4/V5
- byte VAR_V5_TALK_STRING_Y;
-
- // V6+
- byte VAR_ROOM_WIDTH;
- byte VAR_ROOM_HEIGHT;
- byte VAR_SUBTITLES;
- byte VAR_V6_EMSSPACE;
-
- // V7/V8 (=GF_NEW_CAMERA) specific variables
- byte VAR_CAMERA_POS_Y;
- byte VAR_CAMERA_MIN_Y;
- byte VAR_CAMERA_MAX_Y;
- byte VAR_CAMERA_THRESHOLD_X;
- byte VAR_CAMERA_THRESHOLD_Y;
- byte VAR_CAMERA_SPEED_X;
- byte VAR_CAMERA_SPEED_Y;
- byte VAR_CAMERA_ACCEL_X;
- byte VAR_CAMERA_ACCEL_Y;
- byte VAR_CAMERA_DEST_X;
- byte VAR_CAMERA_DEST_Y;
- byte VAR_CAMERA_FOLLOWED_ACTOR;
-
- // V7/V8 specific variables
- byte VAR_VERSION_KEY;
- byte VAR_DEFAULT_TALK_DELAY;
- byte VAR_CUSTOMSCALETABLE;
- byte VAR_BLAST_ABOVE_TEXT;
- byte VAR_VOICE_MODE;
- byte VAR_MUSIC_BUNDLE_LOADED;
- byte VAR_VOICE_BUNDLE_LOADED;
-
- byte VAR_LEFTBTN_DOWN; // V7/V8
- byte VAR_RIGHTBTN_DOWN; // V7/V8
- byte VAR_LEFTBTN_HOLD; // V6/V72HE/V7/V8
- byte VAR_RIGHTBTN_HOLD; // V6/V72HE/V7/V8
- byte VAR_SAVELOAD_SCRIPT; // V6/V7 (not HE)
- byte VAR_SAVELOAD_SCRIPT2; // V6/V7 (not HE)
-
- // V6/V7 specific variables (FT & Sam & Max specific)
- byte VAR_CHARSET_MASK;
-
- // V6 specific variables
- byte VAR_V6_SOUNDMODE;
-
- // V1/V2 specific variables
- byte VAR_CHARCOUNT;
- byte VAR_VERB_ALLOWED;
- byte VAR_ACTIVE_VERB;
- byte VAR_ACTIVE_OBJECT1;
- byte VAR_ACTIVE_OBJECT2;
- byte VAR_CLICK_AREA;
-
- // HE specific variables
- byte VAR_REDRAW_ALL_ACTORS; // Used in setActorRedrawFlags()
- byte VAR_SKIP_RESET_TALK_ACTOR; // Used in setActorCostume()
-
- byte VAR_SOUND_CHANNEL; // Used in o_startSound()
- byte VAR_TALK_CHANNEL; // Used in startHETalkSound()
- byte VAR_SOUNDCODE_TMR; // Used in processSoundCode()
- byte VAR_RESERVED_SOUND_CHANNELS; // Used in findFreeSoundChannel()
-
- byte VAR_MAIN_SCRIPT; // Used in scummLoop()
-
- byte VAR_SCRIPT_CYCLE; // Used in runScript()/runObjectScript()
- byte VAR_NUM_SCRIPT_CYCLES; // Used in runAllScripts()
-
- byte VAR_KEY_STATE; // Used in parseEvents()
- byte VAR_MOUSE_STATE; // Used in checkExecVerbs();
-
- // Exists both in V7 and in V72HE:
- byte VAR_NUM_GLOBAL_OBJS;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/channel.h b/scumm/smush/channel.h
deleted file mode 100644
index 52e64c8b2d..0000000000
--- a/scumm/smush/channel.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SMUSH_CHANNEL_H
-#define SMUSH_CHANNEL_H
-
-#include "common/util.h"
-
-namespace Scumm {
-
-class Chunk;
-class ContChunk;
-
-class SmushChannel {
-public:
-
- virtual ~SmushChannel() {};
- virtual bool appendData(Chunk &b, int32 size) = 0;
- virtual bool setParameters(int32, int32, int32, int32, int32) = 0;
- virtual bool checkParameters(int32, int32, int32, int32, int32) = 0;
- virtual bool isTerminated() const = 0;
- virtual int32 availableSoundData() const = 0;
- virtual void getSoundData(int16 *sound_buffer, int32 size) = 0;
- virtual void getSoundData(int8 *sound_buffer, int32 size) = 0;
- virtual int32 getRate() = 0;
- virtual bool getParameters(int32 &rate, bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) = 0;
- virtual int32 getTrackIdentifier() const = 0;
-};
-
-class SaudChannel : public SmushChannel {
-private:
- int32 _track;
- int32 _nbframes;
- int32 _dataSize;
- int32 _frequency;
- bool _inData;
- bool _markReached;
- int32 _flags;
- int32 _volume;
- int32 _pan;
- int32 _index;
- byte *_tbuffer;
- int32 _tbufferSize;
- byte *_sbuffer;
- int32 _sbufferSize;
- bool _keepSize;
-
-protected:
- void handleStrk(Chunk &c);
- void handleSmrk(Chunk &c);
- void handleShdr(Chunk &c);
- bool handleSubTags(int32 &offset);
- bool processBuffer();
-
-public:
- SaudChannel(int32 track, int32 freq);
- virtual ~SaudChannel();
- bool isTerminated() const;
- bool setParameters(int32 duration, int32 flags, int32 vol1, int32 vol2, int32 index);
- bool checkParameters(int32 index, int32 duration, int32 flags, int32 vol1, int32 vol2);
- bool appendData(Chunk &b, int32 size);
- int32 availableSoundData() const;
- void getSoundData(int16 *sound_buffer, int32 size);
- void getSoundData(int8 *sound_buffer, int32 size) { error("8bit request for SAUD channel should never happen"); };
- int32 getRate() { return _frequency; }
- bool getParameters(int32 &rate, bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) {
- rate = _frequency;
- stereo = true;
- is_16bit = true;
- vol = _volume;
- pan = _pan;
- return true;
- };
- virtual int32 getTrackIdentifier() const { return _track; };
-};
-
-class ImuseChannel : public SmushChannel {
-private:
- int32 _track; //!< the track number
- byte *_tbuffer; //!< data temporary buffer
- int32 _tbufferSize; //!< temporary buffer size
- byte *_sbuffer; //!< sound buffer
- int32 _sbufferSize; //!< sound buffer size
- int32 _srbufferSize;
- int32 _frequency; //!< the target frequency of the ::mixer
- int32 _dataSize; //!< remaining size of sound data in the iMUS buffer
- bool _inData;
- int32 _volume;
- int32 _pan;
-
- int32 _bitsize; //!< the bitsize of the original data
- int32 _rate; //!< the sampling rate of the original data
- int32 _channels; //!< the number of channels of the original data
-
-protected:
- int32 decode(int32 size, int32 &ret);
- void decode();
- bool processBuffer();
- bool handleMap(Chunk &);
- bool handleFormat(Chunk &);
- bool handleRegion(Chunk &);
- bool handleStop(Chunk &);
- bool handleSubTags(int32 & offset);
-
-public:
- ImuseChannel(int32 track, int32 freq);
- virtual ~ImuseChannel();
- bool isTerminated() const;
- bool setParameters(int32 nbframes, int32 size, int32 track_flags, int32 unk1, int32);
- bool checkParameters(int32 index, int32 nbframes, int32 size, int32 track_flags, int32 unk1);
- bool appendData(Chunk &b, int32 size);
- int32 availableSoundData() const;
- void getSoundData(int16 *sound_buffer, int32 size);
- void getSoundData(int8 *sound_buffer, int32 size);
- int32 getRate() { return _rate; }
- bool getParameters(int32 &rate, bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) {
- rate = _rate;
- stereo = (_channels == 2);
- is_16bit = (_bitsize > 8);
- vol = _volume;
- pan = _pan;
- return true;
- };
- virtual int32 getTrackIdentifier() const { return _track; };
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/chunk.cpp b/scumm/smush/chunk.cpp
deleted file mode 100644
index 60512cdf2f..0000000000
--- a/scumm/smush/chunk.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/smush/chunk.h"
-#include "scumm/scumm.h"
-
-#include "common/file.h"
-#include "common/str.h"
-#include "common/util.h"
-
-namespace Scumm {
-
-const char *Chunk::ChunkString(Chunk::type t) {
- static char data[5];
- data[0] = (char)((t >> 24) & 0xFF);
- data[1] = (char)((t >> 16) & 0xFF);
- data[2] = (char)((t >> 8) & 0xFF);
- data[3] = (char)((t >> 0) & 0xFF);
- data[4] = 0;
- return data;
-}
-
-BaseChunk::BaseChunk() :
- _type(0),
- _size(0),
- _curPos(0) {
-}
-
-bool BaseChunk::eof() const {
- return _curPos >= _size;
-}
-
-uint32 BaseChunk::tell() const {
- return _curPos;
-}
-
-Chunk::type BaseChunk::getType() const {
- return _type;
-}
-
-uint32 BaseChunk::getSize() const {
- return _size;
-}
-
-bool BaseChunk::seek(int32 delta, seek_type dir) {
- switch(dir) {
- case seek_cur:
- _curPos += delta;
- break;
- case seek_start:
- if (delta < 0)
- error("invalid seek request");
-
- _curPos = (uint32)delta;
- break;
- case seek_end:
- if (delta > 0 || _size < (uint32)-delta)
- error("invalid seek request");
-
- _curPos = (uint32)(_size + delta);
- break;
- }
- if (_curPos > _size) {
- error("invalid seek request : %d > %d (delta == %d)", _curPos, _size, delta);
- }
- return true;
-}
-
-FileChunk::FileChunk(ScummFile *data, int offset) {
- _data = data;
- _deleteData = false;
-
- _data->seek(offset, seek_start);
- _type = _data->readUint32BE();
- _size = _data->readUint32BE();
- _offset = _data->pos();
- _curPos = 0;
-}
-
-FileChunk::FileChunk(const Common::String &name, int offset) {
- _data = new ScummFile();
- _deleteData = true;
- if (!g_scumm->openFile(*_data, name.c_str()))
- error("FileChunk: Unable to open file %s", name.c_str());
-
- _data->seek(offset, seek_start);
- _type = _data->readUint32BE();
- _size = _data->readUint32BE();
- _offset = _data->pos();
- _curPos = 0;
-}
-
-FileChunk::~FileChunk() {
- if (_deleteData)
- delete _data;
-}
-
-Chunk *FileChunk::subBlock() {
- FileChunk *ptr = new FileChunk(_data, _offset + _curPos);
- seek(sizeof(Chunk::type) + sizeof(uint32) + ptr->getSize());
- return ptr;
-}
-
-void FileChunk::reseek() {
- _data->seek(_offset + _curPos);
-}
-
-bool FileChunk::read(void *buffer, uint32 size) {
- if (size <= 0 || (_curPos + size) > _size)
- error("invalid buffer read request");
-
- _data->read(buffer, size);
- _curPos += size;
- return true;
-}
-
-int8 FileChunk::getChar() {
- return (int8)getByte();
-}
-
-byte FileChunk::getByte() {
- _curPos++;
-
- if (_curPos > _size)
- error("invalid byte read request");
-
- return _data->readByte();
-}
-
-int16 FileChunk::getShort() {
- return (int16)getWord();
-}
-
-uint16 FileChunk::getWord() {
- _curPos += 2;
-
- if (_curPos > _size)
- error("invalid word read request");
-
- return _data->readUint16LE();
-}
-
-uint32 FileChunk::getDword() {
- _curPos += 4;
-
- if (_curPos > _size)
- error("invalid dword read request");
-
- return _data->readUint32LE();
-}
-
-MemoryChunk::MemoryChunk(byte *data) {
- if (data == 0)
- error("Chunk() called with NULL pointer");
-
- _type = (Chunk::type)READ_BE_UINT32(data);
- _size = READ_BE_UINT32(data + 4);
- _data = data + sizeof(Chunk::type) + sizeof(uint32);
- _curPos = 0;
-}
-
-Chunk *MemoryChunk::subBlock() {
- MemoryChunk *ptr = new MemoryChunk(_data + _curPos);
- seek(sizeof(Chunk::type) + sizeof(uint32) + ptr->getSize());
- return ptr;
-}
-
-void MemoryChunk::reseek() {
-}
-
-bool MemoryChunk::read(void *buffer, uint32 size) {
- if (size <= 0 || (_curPos + size) > _size)
- error("invalid buffer read request");
-
- memcpy(buffer, _data + _curPos, size);
- _curPos += size;
- return true;
-}
-
-int8 MemoryChunk::getChar() {
- if (_curPos >= _size)
- error("invalid char read request");
-
- return _data[_curPos++];
-}
-
-byte MemoryChunk::getByte() {
- if (_curPos >= _size)
- error("invalid byte read request");
-
- byte *ptr = (byte *)(_data + _curPos);
- _curPos += 1;
- return *ptr;
-}
-
-int16 MemoryChunk::getShort() {
- if (_curPos >= _size - 1)
- error("invalid int16 read request");
-
- int16 buffer = getWord();
- return *((int16 *)&buffer);
-}
-
-uint16 MemoryChunk::getWord() {
- if (_curPos >= _size - 1)
- error("invalid word read request");
-
- uint16 *ptr = (uint16 *)(_data + _curPos);
- _curPos += 2;
- return READ_LE_UINT16(ptr);
-}
-
-uint32 MemoryChunk::getDword() {
- if (_curPos >= _size - 3)
- error("invalid dword read request");
-
- uint32 *ptr = (uint32 *)(_data + _curPos);
- _curPos += 4;
- return READ_LE_UINT32(ptr);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/smush/chunk.h b/scumm/smush/chunk.h
deleted file mode 100644
index 26290538a6..0000000000
--- a/scumm/smush/chunk.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef CHUNK_H
-#define CHUNK_H
-
-#include "common/scummsys.h"
-#include "common/str.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-class ScummFile;
-
-class Chunk {
-public:
- virtual ~Chunk() {};
- enum seek_type { seek_start, seek_end, seek_cur };
- typedef uint32 type;
- static const char *ChunkString(type t);
- virtual type getType() const = 0;
- virtual uint32 getSize() const = 0;
- virtual Chunk *subBlock() = 0;
- virtual void reseek() = 0;
- virtual bool eof() const = 0;
- virtual uint32 tell() const = 0;
- virtual bool seek(int32 delta, seek_type dir = seek_cur) = 0;
- virtual bool read(void *buffer, uint32 size) = 0;
- virtual int8 getChar() = 0;
- virtual byte getByte() = 0;
- virtual int16 getShort() = 0;
- virtual uint16 getWord() = 0;
- virtual uint32 getDword() = 0;
-};
-
-// Common functionality for concrete chunks (FileChunk, MemoryChunk)
-class BaseChunk : public Chunk {
-protected:
- Chunk::type _type;
- uint32 _size;
- uint32 _curPos;
-
- BaseChunk();
-
-public:
- Chunk::type getType() const;
- uint32 getSize() const;
- bool eof() const;
- uint32 tell() const;
- bool seek(int32 delta, seek_type dir = seek_cur);
-};
-
-class FileChunk : public BaseChunk {
-private:
- ScummFile *_data;
- bool _deleteData;
- uint32 _offset;
-
- FileChunk(ScummFile *data, int offset);
-public:
- FileChunk(const Common::String &name, int offset = 0);
- virtual ~FileChunk();
- Chunk *subBlock();
- void reseek();
- bool read(void *buffer, uint32 size);
- int8 getChar();
- byte getByte();
- short getShort();
- uint16 getWord();
- uint32 getDword();
-};
-
-class MemoryChunk : public BaseChunk {
-private:
- byte *_data;
-
-public:
- MemoryChunk(byte *data);
- Chunk *subBlock();
- void reseek();
- bool read(void *buffer, uint32 size);
- int8 getChar();
- byte getByte();
- int16 getShort();
- uint16 getWord();
- uint32 getDword();
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/chunk_type.h b/scumm/smush/chunk_type.h
deleted file mode 100644
index 18c49f0dbf..0000000000
--- a/scumm/smush/chunk_type.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef CHUNK_TYPE_H
-#define CHUNK_TYPE_H
-
-#include "common/scummsys.h"
-#include "scumm/smush/chunk.h"
-
-namespace Scumm {
-
-static const Chunk::type TYPE_ANIM = 'ANIM';
-static const Chunk::type TYPE_AHDR = 'AHDR';
-static const Chunk::type TYPE_FRME = 'FRME';
-static const Chunk::type TYPE_NPAL = 'NPAL';
-static const Chunk::type TYPE_FOBJ = 'FOBJ';
-static const Chunk::type TYPE_ZFOB = 'ZFOB';
-static const Chunk::type TYPE_PSAD = 'PSAD';
-static const Chunk::type TYPE_TRES = 'TRES';
-static const Chunk::type TYPE_XPAL = 'XPAL';
-static const Chunk::type TYPE_IACT = 'IACT';
-static const Chunk::type TYPE_STOR = 'STOR';
-static const Chunk::type TYPE_FTCH = 'FTCH';
-static const Chunk::type TYPE_SKIP = 'SKIP';
-static const Chunk::type TYPE_STRK = 'STRK';
-static const Chunk::type TYPE_SMRK = 'SMRK';
-static const Chunk::type TYPE_SHDR = 'SHDR';
-static const Chunk::type TYPE_SDAT = 'SDAT';
-static const Chunk::type TYPE_SAUD = 'SAUD';
-static const Chunk::type TYPE_iMUS = 'iMUS';
-static const Chunk::type TYPE_FRMT = 'FRMT';
-static const Chunk::type TYPE_TEXT = 'TEXT';
-static const Chunk::type TYPE_REGN = 'REGN';
-static const Chunk::type TYPE_STOP = 'STOP';
-static const Chunk::type TYPE_MAP_ = 'MAP ';
-static const Chunk::type TYPE_DATA = 'DATA';
-static const Chunk::type TYPE_ETRS = 'ETRS';
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/codec1.cpp b/scumm/smush/codec1.cpp
deleted file mode 100644
index 04d55e2ed7..0000000000
--- a/scumm/smush/codec1.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/scummsys.h"
-
-namespace Scumm {
-
-void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch) {
- byte val, code;
- int32 length;
- int h = height, size_line;
-
- dst += top * pitch;
- for (h = 0; h < height; h++) {
- size_line = READ_LE_UINT16(src);
- src += 2;
- dst += left;
- while (size_line > 0) {
- code = *src++;
- size_line--;
- length = (code >> 1) + 1;
- if (code & 1) {
- val = *src++;
- size_line--;
- if (val)
- memset(dst, val, length);
- dst += length;
- } else {
- size_line -= length;
- while (length--) {
- val = *src++;
- if (val)
- *dst = val;
- dst++;
- }
- }
- }
- dst += pitch - left - width;
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/smush/codec37.cpp b/scumm/smush/codec37.cpp
deleted file mode 100644
index 732bffeeae..0000000000
--- a/scumm/smush/codec37.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/util.h"
-#include "scumm/bomp.h"
-#include "scumm/smush/codec37.h"
-
-namespace Scumm {
-
-void Codec37Decoder::init(int width, int height) {
- deinit();
- _width = width;
- _height = height;
- _frameSize = _width * _height;
- _deltaSize = _frameSize * 3 + 0x13600;
- _deltaBuf = (byte *)calloc(_deltaSize, sizeof(byte));
- if (_deltaBuf == 0)
- error("unable to allocate decoder buffer");
- _deltaBufs[0] = _deltaBuf + 0x4D80;
- _deltaBufs[1] = _deltaBuf + 0xE880 + _frameSize;
- _offsetTable = new int16[255];
- _curtable = 0;
- if (_offsetTable == 0)
- error("unable to allocate decoder offset table");
- _tableLastPitch = -1;
- _tableLastIndex = -1;
-}
-
-Codec37Decoder::Codec37Decoder() {
- _deltaSize = 0;
- _deltaBuf = 0;
- _deltaBufs[0] = 0;
- _deltaBufs[1] = 0;
- _curtable = 0;
- _offsetTable = 0;
- _tableLastPitch = -1;
- _tableLastIndex = -1;
- _prevSeqNb = 0;
-}
-
-void Codec37Decoder::deinit() {
- if (_offsetTable) {
- delete []_offsetTable;
- _offsetTable = 0;
- _tableLastPitch = -1;
- _tableLastIndex = -1;
- }
- if (_deltaBuf) {
- free(_deltaBuf);
- _deltaSize = 0;
- _deltaBuf = 0;
- _deltaBufs[0] = 0;
- _deltaBufs[1] = 0;
- }
-}
-
-Codec37Decoder::~Codec37Decoder() {
- deinit();
-}
-
-void Codec37Decoder::maketable(int pitch, int index) {
- static const int8 maketable_bytes[] = {
- 0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
- 8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
- -3, 0, -5, 0, -8, 0, -13, 0, -17, 0,
- -21, 0, 0, 1, 1, 1, 2, 1, 3, 1,
- 5, 1, 8, 1, 13, 1, 21, 1, -1, 1,
- -2, 1, -3, 1, -5, 1, -8, 1, -13, 1,
- -17, 1, -21, 1, 0, 2, 1, 2, 2, 2,
- 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
- -1, 2, -2, 2, -3, 2, -5, 2, -8, 2,
- -13, 2, -17, 2, -21, 2, 0, 3, 1, 3,
- 2, 3, 3, 3, 5, 3, 8, 3, 13, 3,
- 21, 3, -1, 3, -2, 3, -3, 3, -5, 3,
- -8, 3, -13, 3, -17, 3, -21, 3, 0, 5,
- 1, 5, 2, 5, 3, 5, 5, 5, 8, 5,
- 13, 5, 21, 5, -1, 5, -2, 5, -3, 5,
- -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
- 0, 8, 1, 8, 2, 8, 3, 8, 5, 8,
- 8, 8, 13, 8, 21, 8, -1, 8, -2, 8,
- -3, 8, -5, 8, -8, 8, -13, 8, -17, 8,
- -21, 8, 0, 13, 1, 13, 2, 13, 3, 13,
- 5, 13, 8, 13, 13, 13, 21, 13, -1, 13,
- -2, 13, -3, 13, -5, 13, -8, 13, -13, 13,
- -17, 13, -21, 13, 0, 21, 1, 21, 2, 21,
- 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
- -1, 21, -2, 21, -3, 21, -5, 21, -8, 21,
- -13, 21, -17, 21, -21, 21, 0, -1, 1, -1,
- 2, -1, 3, -1, 5, -1, 8, -1, 13, -1,
- 21, -1, -1, -1, -2, -1, -3, -1, -5, -1,
- -8, -1, -13, -1, -17, -1, -21, -1, 0, -2,
- 1, -2, 2, -2, 3, -2, 5, -2, 8, -2,
- 13, -2, 21, -2, -1, -2, -2, -2, -3, -2,
- -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
- 0, -3, 1, -3, 2, -3, 3, -3, 5, -3,
- 8, -3, 13, -3, 21, -3, -1, -3, -2, -3,
- -3, -3, -5, -3, -8, -3, -13, -3, -17, -3,
- -21, -3, 0, -5, 1, -5, 2, -5, 3, -5,
- 5, -5, 8, -5, 13, -5, 21, -5, -1, -5,
- -2, -5, -3, -5, -5, -5, -8, -5, -13, -5,
- -17, -5, -21, -5, 0, -8, 1, -8, 2, -8,
- 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
- -1, -8, -2, -8, -3, -8, -5, -8, -8, -8,
- -13, -8, -17, -8, -21, -8, 0, -13, 1, -13,
- 2, -13, 3, -13, 5, -13, 8, -13, 13, -13,
- 21, -13, -1, -13, -2, -13, -3, -13, -5, -13,
- -8, -13, -13, -13, -17, -13, -21, -13, 0, -17,
- 1, -17, 2, -17, 3, -17, 5, -17, 8, -17,
- 13, -17, 21, -17, -1, -17, -2, -17, -3, -17,
- -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
- 0, -21, 1, -21, 2, -21, 3, -21, 5, -21,
- 8, -21, 13, -21, 21, -21, -1, -21, -2, -21,
- -3, -21, -5, -21, -8, -21, -13, -21, -17, -21,
- 0, 0, -8, -29, 8, -29, -18, -25, 17, -25,
- 0, -23, -6, -22, 6, -22, -13, -19, 12, -19,
- 0, -18, 25, -18, -25, -17, -5, -17, 5, -17,
- -10, -15, 10, -15, 0, -14, -4, -13, 4, -13,
- 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
- 2, -11, 8, -11, -15, -10, -4, -10, 4, -10,
- 15, -10, -6, -9, -1, -9, 1, -9, 6, -9,
- -29, -8, -11, -8, -8, -8, -3, -8, 3, -8,
- 8, -8, 11, -8, 29, -8, -5, -7, -2, -7,
- 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
- -6, -6, -3, -6, -1, -6, 1, -6, 3, -6,
- 6, -6, 9, -6, 22, -6, -17, -5, -7, -5,
- -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
- 7, -5, 17, -5, -13, -4, -10, -4, -5, -4,
- -3, -4, -1, -4, 0, -4, 1, -4, 3, -4,
- 5, -4, 10, -4, 13, -4, -8, -3, -6, -3,
- -4, -3, -3, -3, -2, -3, -1, -3, 0, -3,
- 1, -3, 2, -3, 4, -3, 6, -3, 8, -3,
- -11, -2, -7, -2, -5, -2, -3, -2, -2, -2,
- -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
- 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
- -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
- 1, -1, 2, -1, 3, -1, 4, -1, 6, -1,
- 9, -1, -31, 0, -23, 0, -18, 0, -14, 0,
- -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
- -2, 0, -1, 0, 0, -31, 1, 0, 2, 0,
- 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
- 14, 0, 18, 0, 23, 0, 31, 0, -9, 1,
- -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
- 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
- 6, 1, 9, 1, -11, 2, -7, 2, -5, 2,
- -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
- 2, 2, 3, 2, 5, 2, 7, 2, 11, 2,
- -8, 3, -6, 3, -4, 3, -2, 3, -1, 3,
- 0, 3, 1, 3, 2, 3, 3, 3, 4, 3,
- 6, 3, 8, 3, -13, 4, -10, 4, -5, 4,
- -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
- 5, 4, 10, 4, 13, 4, -17, 5, -7, 5,
- -4, 5, -2, 5, 0, 5, 2, 5, 4, 5,
- 7, 5, 17, 5, -22, 6, -9, 6, -6, 6,
- -3, 6, -1, 6, 1, 6, 3, 6, 6, 6,
- 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
- 2, 7, 5, 7, -29, 8, -11, 8, -8, 8,
- -3, 8, 3, 8, 8, 8, 11, 8, 29, 8,
- -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
- -4, 10, 4, 10, 15, 10, -8, 11, -2, 11,
- 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
- -4, 13, 4, 13, 0, 14, -10, 15, 10, 15,
- -5, 17, 5, 17, 25, 17, -25, 18, 0, 18,
- -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
- -17, 25, 18, 25, -8, 29, 8, 29, 0, 31,
- 0, 0, -6, -22, 6, -22, -13, -19, 12, -19,
- 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
- 0, -14, -4, -13, 4, -13, 19, -13, -19, -12,
- -8, -11, -2, -11, 0, -11, 2, -11, 8, -11,
- -15, -10, -4, -10, 4, -10, 15, -10, -6, -9,
- -1, -9, 1, -9, 6, -9, -11, -8, -8, -8,
- -3, -8, 0, -8, 3, -8, 8, -8, 11, -8,
- -5, -7, -2, -7, 0, -7, 2, -7, 5, -7,
- -22, -6, -9, -6, -6, -6, -3, -6, -1, -6,
- 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
- -17, -5, -7, -5, -4, -5, -2, -5, -1, -5,
- 0, -5, 1, -5, 2, -5, 4, -5, 7, -5,
- 17, -5, -13, -4, -10, -4, -5, -4, -3, -4,
- -2, -4, -1, -4, 0, -4, 1, -4, 2, -4,
- 3, -4, 5, -4, 10, -4, 13, -4, -8, -3,
- -6, -3, -4, -3, -3, -3, -2, -3, -1, -3,
- 0, -3, 1, -3, 2, -3, 3, -3, 4, -3,
- 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
- -4, -2, -3, -2, -2, -2, -1, -2, 0, -2,
- 1, -2, 2, -2, 3, -2, 4, -2, 5, -2,
- 7, -2, 11, -2, -9, -1, -6, -1, -5, -1,
- -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
- 1, -1, 2, -1, 3, -1, 4, -1, 5, -1,
- 6, -1, 9, -1, -23, 0, -18, 0, -14, 0,
- -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
- -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
- 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
- 14, 0, 18, 0, 23, 0, -9, 1, -6, 1,
- -5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
- 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
- 5, 1, 6, 1, 9, 1, -11, 2, -7, 2,
- -5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
- 0, 2, 1, 2, 2, 2, 3, 2, 4, 2,
- 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
- -4, 3, -3, 3, -2, 3, -1, 3, 0, 3,
- 1, 3, 2, 3, 3, 3, 4, 3, 6, 3,
- 8, 3, -13, 4, -10, 4, -5, 4, -3, 4,
- -2, 4, -1, 4, 0, 4, 1, 4, 2, 4,
- 3, 4, 5, 4, 10, 4, 13, 4, -17, 5,
- -7, 5, -4, 5, -2, 5, -1, 5, 0, 5,
- 1, 5, 2, 5, 4, 5, 7, 5, 17, 5,
- -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
- 1, 6, 3, 6, 6, 6, 9, 6, 22, 6,
- -5, 7, -2, 7, 0, 7, 2, 7, 5, 7,
- -11, 8, -8, 8, -3, 8, 0, 8, 3, 8,
- 8, 8, 11, 8, -6, 9, -1, 9, 1, 9,
- 6, 9, -15, 10, -4, 10, 4, 10, 15, 10,
- -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
- 19, 12, -19, 13, -4, 13, 4, 13, 0, 14,
- -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
- -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
- };
-
- if (_tableLastPitch == pitch && _tableLastIndex == index)
- return;
-
- _tableLastPitch = pitch;
- _tableLastIndex = index;
- index *= 255;
- assert(index + 254 < (int32)(sizeof(maketable_bytes) / 2));
-
- for (int32 i = 0; i < 255; i++) {
- int32 j = (i + index) * 2;
- _offsetTable[i] = maketable_bytes[j + 1] * pitch + maketable_bytes[j];
- }
-}
-
-#if defined(SCUMM_NEED_ALIGNMENT)
-
-#define DECLARE_LITERAL_TEMP(v) \
- byte v
-
-#define READ_LITERAL_PIXEL(src, v) \
- v = *src++
-
-#define WRITE_4X1_LINE(dst, v) \
- do { \
- int j; \
- for (j=0; j<4; j++) \
- (dst)[j] = v; \
- } while (0)
-
-#define COPY_4X1_LINE(dst, src) \
- do { \
- int j; \
- for (j=0; j<4; j++) \
- (dst)[j] = (src)[j]; \
- } while (0)
-
-#else /* SCUMM_NEED_ALIGNMENT */
-
-#define DECLARE_LITERAL_TEMP(v) \
- uint32 v
-
-#define READ_LITERAL_PIXEL(src, v) \
- do { \
- v = *src++; \
- v += (v << 8) + (v << 16) + (v << 24); \
- } while (0)
-
-#define WRITE_4X1_LINE(dst, v) \
- *(uint32 *)(dst) = v
-
-#define COPY_4X1_LINE(dst, src) \
- *(uint32 *)(dst) = *(const uint32 *)(src)
-
-#endif /* SCUMM_NEED_ALIGNMENT */
-
-/* Fill a 4x4 pixel block with a literal pixel value */
-
-#define LITERAL_4X4(src, dst, pitch) \
- do { \
- int x; \
- DECLARE_LITERAL_TEMP(t); \
- READ_LITERAL_PIXEL(src, t); \
- for (x=0; x<4; x++) { \
- WRITE_4X1_LINE(dst + pitch * x, t); \
- } \
- dst += 4; \
- } while (0)
-
-/* Fill four 4x1 pixel blocks with literal pixel values */
-
-#define LITERAL_4X1(src, dst, pitch) \
- do { \
- int x; \
- DECLARE_LITERAL_TEMP(t); \
- for (x=0; x<4; x++) { \
- READ_LITERAL_PIXEL(src, t); \
- WRITE_4X1_LINE(dst + pitch * x, t); \
- } \
- dst += 4; \
- } while (0)
-
-/* Fill sixteen 1x1 pixel blocks with literal pixel values */
-
-#define LITERAL_1X1(src, dst, pitch) \
- do { \
- int x; \
- for (x=0; x<4; x++) { \
- COPY_4X1_LINE(dst + pitch * x, src); \
- src += 4; \
- } \
- dst += 4; \
- } while (0)
-
-/* Copy a 4x4 pixel block from a different place in the framebuffer */
-
-#define COPY_4X4(dst2, dst, pitch) \
- do { \
- int x; \
- for (x=0; x<4; x++) { \
- COPY_4X1_LINE(dst + pitch * x, dst2 + pitch * x); \
- } \
- dst += 4; \
- } while (0)
-
-void Codec37Decoder::proc1(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
- uint8 code;
- bool filling, skipCode;
- int32 len;
- int i, p;
- uint32 pitches[16];
-
- i = bw;
- for (p = 0; p < 16; ++p) {
- pitches[p] = (p >> 2) * pitch + (p & 0x3);
- }
- code = 0;
- filling = false;
- len = -1;
- while (1) {
- if (len < 0) {
- filling = (*src & 1) == 1;
- len = *src++ >> 1;
- skipCode = false;
- } else {
- skipCode = true;
- }
- if (!filling || !skipCode) {
- code = *src++;
- if (code == 0xFF) {
- --len;
- for (p = 0; p < 0x10; ++p) {
- if (len < 0) {
- filling = (*src & 1) == 1;
- len = *src++ >> 1;
- if (filling) {
- code = *src++;
- }
- }
- if (filling) {
- *(dst + pitches[p]) = code;
- } else {
- *(dst + pitches[p]) = *src++;
- }
- --len;
- }
- dst += 4;
- --i;
- if (i == 0) {
- dst += pitch * 3;
- --bh;
- if (bh == 0) return;
- i = bw;
- }
- continue;
- }
- }
- byte *dst2 = dst + offset_table[code] + next_offs;
- COPY_4X4(dst2, dst, pitch);
- --i;
- if (i == 0) {
- dst += pitch * 3;
- --bh;
- if (bh == 0) return;
- i = bw;
- }
- --len;
- }
-}
-
-void Codec37Decoder::proc3WithFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
- do {
- int32 i = bw;
- do {
- int32 code = *src++;
- if (code == 0xFD) {
- LITERAL_4X4(src, dst, pitch);
- } else if (code == 0xFE) {
- LITERAL_4X1(src, dst, pitch);
- } else if (code == 0xFF) {
- LITERAL_1X1(src, dst, pitch);
- } else {
- byte *dst2 = dst + _offsetTable[code] + next_offs;
- COPY_4X4(dst2, dst, pitch);
- }
- } while (--i);
- dst += pitch * 3;
- } while (--bh);
-}
-
-void Codec37Decoder::proc3WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
- do {
- int32 i = bw;
- do {
- int32 code = *src++;
- if (code == 0xFF) {
- LITERAL_1X1(src, dst, pitch);
- } else {
- byte *dst2 = dst + _offsetTable[code] + next_offs;
- COPY_4X4(dst2, dst, pitch);
- }
- } while (--i);
- dst += pitch * 3;
- } while (--bh);
-}
-
-void Codec37Decoder::proc4WithFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
- do {
- int32 i = bw;
- do {
- int32 code = *src++;
- if (code == 0xFD) {
- LITERAL_4X4(src, dst, pitch);
- } else if (code == 0xFE) {
- LITERAL_4X1(src, dst, pitch);
- } else if (code == 0xFF) {
- LITERAL_1X1(src, dst, pitch);
- } else if (code == 0x00) {
- int32 length = *src++ + 1;
- for (int32 l = 0; l < length; l++) {
- byte *dst2 = dst + next_offs;
- COPY_4X4(dst2, dst, pitch);
- i--;
- if (i == 0) {
- dst += pitch * 3;
- bh--;
- i = bw;
- }
- }
- if (bh == 0) {
- return;
- }
- i++;
- } else {
- byte *dst2 = dst + _offsetTable[code] + next_offs;
- COPY_4X4(dst2, dst, pitch);
- }
- } while (--i);
- dst += pitch * 3;
- } while (--bh);
-}
-
-void Codec37Decoder::proc4WithoutFDFE(byte *dst, const byte *src, int32 next_offs, int bw, int bh, int pitch, int16 *offset_table) {
- do {
- int32 i = bw;
- do {
- int32 code = *src++;
- if (code == 0xFF) {
- LITERAL_1X1(src, dst, pitch);
- } else if (code == 0x00) {
- int32 length = *src++ + 1;
- for (int32 l = 0; l < length; l++) {
- byte *dst2 = dst + next_offs;
- COPY_4X4(dst2, dst, pitch);
- i--;
- if (i == 0) {
- dst += pitch * 3;
- bh--;
- i = bw;
- }
- }
- if (bh == 0) {
- return;
- }
- i++;
- } else {
- byte *dst2 = dst + _offsetTable[code] + next_offs;
- COPY_4X4(dst2, dst, pitch);
- }
- } while (--i);
- dst += pitch * 3;
- } while (--bh);
-}
-
-void Codec37Decoder::decode(byte *dst, const byte *src) {
- int32 bw = (_width + 3) / 4, bh = (_height + 3) / 4;
- int32 pitch = bw * 4;
-
- int16 seq_nb = READ_LE_UINT16(src + 2);
- int32 decoded_size = READ_LE_UINT32(src + 4);
- byte mask_flags = src[12];
- maketable(pitch, src[1]);
- int32 tmp;
-
- switch(src[0]) {
- case 0:
- if ((_deltaBufs[_curtable] - _deltaBuf) > 0) {
- memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf);
- }
- tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curtable] - decoded_size;
- if (tmp > 0) {
- memset(_deltaBufs[_curtable] + decoded_size, 0, tmp);
- }
- memcpy(_deltaBufs[_curtable], src + 16, decoded_size);
- break;
- case 1:
- if ((seq_nb & 1) || !(mask_flags & 1)) {
- _curtable ^= 1;
- }
- proc1(_deltaBufs[_curtable], src + 16, _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable],
- bw, bh, pitch, _offsetTable);
- break;
- case 2:
- bompDecodeLine(_deltaBufs[_curtable], src + 16, decoded_size);
- if ((_deltaBufs[_curtable] - _deltaBuf) > 0) {
- memset(_deltaBuf, 0, _deltaBufs[_curtable] - _deltaBuf);
- }
- tmp = (_deltaBuf + _deltaSize) - _deltaBufs[_curtable] - decoded_size;
- if (tmp > 0) {
- memset(_deltaBufs[_curtable] + decoded_size, 0, tmp);
- }
- break;
- case 3:
- if ((seq_nb & 1) || !(mask_flags & 1)) {
- _curtable ^= 1;
- }
-
- if ((mask_flags & 4) != 0) {
- proc3WithFDFE(_deltaBufs[_curtable], src + 16,
- _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
- pitch, _offsetTable);
- } else {
- proc3WithoutFDFE(_deltaBufs[_curtable], src + 16,
- _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
- pitch, _offsetTable);
- }
- break;
- case 4:
- if ((seq_nb & 1) || !(mask_flags & 1)) {
- _curtable ^= 1;
- }
-
- if ((mask_flags & 4) != 0) {
- proc4WithFDFE(_deltaBufs[_curtable], src + 16,
- _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
- pitch, _offsetTable);
- } else {
- proc4WithoutFDFE(_deltaBufs[_curtable], src + 16,
- _deltaBufs[_curtable ^ 1] - _deltaBufs[_curtable], bw, bh,
- pitch, _offsetTable);
- }
- break;
- default:
- break;
- }
- _prevSeqNb = seq_nb;
-
- memcpy(dst, _deltaBufs[_curtable], _frameSize);
-}
-
-} // End of namespace Scumm
-
diff --git a/scumm/smush/codec37.h b/scumm/smush/codec37.h
deleted file mode 100644
index 534316c1e5..0000000000
--- a/scumm/smush/codec37.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SMUSH_CODEC37_H
-#define SMUSH_CODEC37_H
-
-#include "common/scummsys.h"
-
-namespace Scumm {
-
-class Codec37Decoder {
-private:
-
- int32 _deltaSize;
- byte *_deltaBufs[2];
- byte *_deltaBuf;
- int16 *_offsetTable;
- int _curtable;
- uint16 _prevSeqNb;
- int _tableLastPitch;
- int _tableLastIndex;
- int32 _frameSize;
- int _width, _height;
-
-public:
- Codec37Decoder();
- ~Codec37Decoder();
- void init(int width, int height);
- void deinit();
-protected:
- void maketable(int, int);
- void proc1(byte *dst, const byte *src, int32, int, int, int, int16 *);
- void proc3WithFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
- void proc3WithoutFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
- void proc4WithFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
- void proc4WithoutFDFE(byte *dst, const byte *src, int32, int, int, int, int16 *);
-public:
- void decode(byte *dst, const byte *src);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/codec47.cpp b/scumm/smush/codec47.cpp
deleted file mode 100644
index ef10a282a9..0000000000
--- a/scumm/smush/codec47.cpp
+++ /dev/null
@@ -1,630 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/util.h"
-#include "scumm/bomp.h"
-#include "scumm/smush/codec47.h"
-
-namespace Scumm {
-
-#if defined(SCUMM_NEED_ALIGNMENT)
-
-#define COPY_4X1_LINE(dst, src) \
- do { \
- (dst)[0] = (src)[0]; \
- (dst)[1] = (src)[1]; \
- (dst)[2] = (src)[2]; \
- (dst)[3] = (src)[3]; \
- } while (0)
-
-#define COPY_2X1_LINE(dst, src) \
- do { \
- (dst)[0] = (src)[0]; \
- (dst)[1] = (src)[1]; \
- } while (0)
-
-
-#else /* SCUMM_NEED_ALIGNMENT */
-
-#define COPY_4X1_LINE(dst, src) \
- *(uint32 *)(dst) = *(const uint32 *)(src)
-
-#define COPY_2X1_LINE(dst, src) \
- *(uint16 *)(dst) = *(const uint16 *)(src)
-
-#endif
-
-#define FILL_4X1_LINE(dst, val) \
- do { \
- (dst)[0] = val; \
- (dst)[1] = val; \
- (dst)[2] = val; \
- (dst)[3] = val; \
- } while (0)
-
-#define FILL_2X1_LINE(dst, val) \
- do { \
- (dst)[0] = val; \
- (dst)[1] = val; \
- } while (0)
-
-static int8 codec47_table_small1[] = {
- 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1,
-};
-
-static int8 codec47_table_small2[] = {
- 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2,
-};
-
-static int8 codec47_table_big1[] = {
- 0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0,
-};
-
-static int8 codec47_table_big2[] = {
- 0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1,
-};
-
-#ifdef PALMOS_68K
-static const int8 *codec47_table;
-#else
-static const int8 codec47_table[] = {
- 0, 0, -1, -43, 6, -43, -9, -42, 13, -41,
- -16, -40, 19, -39, -23, -36, 26, -34, -2, -33,
- 4, -33, -29, -32, -9, -32, 11, -31, -16, -29,
- 32, -29, 18, -28, -34, -26, -22, -25, -1, -25,
- 3, -25, -7, -24, 8, -24, 24, -23, 36, -23,
- -12, -22, 13, -21, -38, -20, 0, -20, -27, -19,
- -4, -19, 4, -19, -17, -18, -8, -17, 8, -17,
- 18, -17, 28, -17, 39, -17, -12, -15, 12, -15,
- -21, -14, -1, -14, 1, -14, -41, -13, -5, -13,
- 5, -13, 21, -13, -31, -12, -15, -11, -8, -11,
- 8, -11, 15, -11, -2, -10, 1, -10, 31, -10,
- -23, -9, -11, -9, -5, -9, 4, -9, 11, -9,
- 42, -9, 6, -8, 24, -8, -18, -7, -7, -7,
- -3, -7, -1, -7, 2, -7, 18, -7, -43, -6,
- -13, -6, -4, -6, 4, -6, 8, -6, -33, -5,
- -9, -5, -2, -5, 0, -5, 2, -5, 5, -5,
- 13, -5, -25, -4, -6, -4, -3, -4, 3, -4,
- 9, -4, -19, -3, -7, -3, -4, -3, -2, -3,
- -1, -3, 0, -3, 1, -3, 2, -3, 4, -3,
- 6, -3, 33, -3, -14, -2, -10, -2, -5, -2,
- -3, -2, -2, -2, -1, -2, 0, -2, 1, -2,
- 2, -2, 3, -2, 5, -2, 7, -2, 14, -2,
- 19, -2, 25, -2, 43, -2, -7, -1, -3, -1,
- -2, -1, -1, -1, 0, -1, 1, -1, 2, -1,
- 3, -1, 10, -1, -5, 0, -3, 0, -2, 0,
- -1, 0, 1, 0, 2, 0, 3, 0, 5, 0,
- 7, 0, -10, 1, -7, 1, -3, 1, -2, 1,
- -1, 1, 0, 1, 1, 1, 2, 1, 3, 1,
- -43, 2, -25, 2, -19, 2, -14, 2, -5, 2,
- -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
- 2, 2, 3, 2, 5, 2, 7, 2, 10, 2,
- 14, 2, -33, 3, -6, 3, -4, 3, -2, 3,
- -1, 3, 0, 3, 1, 3, 2, 3, 4, 3,
- 19, 3, -9, 4, -3, 4, 3, 4, 7, 4,
- 25, 4, -13, 5, -5, 5, -2, 5, 0, 5,
- 2, 5, 5, 5, 9, 5, 33, 5, -8, 6,
- -4, 6, 4, 6, 13, 6, 43, 6, -18, 7,
- -2, 7, 0, 7, 2, 7, 7, 7, 18, 7,
- -24, 8, -6, 8, -42, 9, -11, 9, -4, 9,
- 5, 9, 11, 9, 23, 9, -31, 10, -1, 10,
- 2, 10, -15, 11, -8, 11, 8, 11, 15, 11,
- 31, 12, -21, 13, -5, 13, 5, 13, 41, 13,
- -1, 14, 1, 14, 21, 14, -12, 15, 12, 15,
- -39, 17, -28, 17, -18, 17, -8, 17, 8, 17,
- 17, 18, -4, 19, 0, 19, 4, 19, 27, 19,
- 38, 20, -13, 21, 12, 22, -36, 23, -24, 23,
- -8, 24, 7, 24, -3, 25, 1, 25, 22, 25,
- 34, 26, -18, 28, -32, 29, 16, 29, -11, 31,
- 9, 32, 29, 32, -4, 33, 2, 33, -26, 34,
- 23, 36, -19, 39, 16, 40, -13, 41, 9, 42,
- -6, 43, 1, 43, 0, 0, 0, 0, 0, 0
-};
-#endif
-
-void Codec47Decoder::makeTablesInterpolation(int param) {
- int32 variable1, variable2;
- int32 b1, b2;
- int32 value_table47_1_2, value_table47_1_1, value_table47_2_2, value_table47_2_1;
- int32 tableSmallBig[64], tmp, s;
- int8 *table47_1 = 0, *table47_2 = 0;
- int32 *ptr_small_big;
- byte *ptr;
- int i, x, y;
-
- if (param == 8) {
- table47_1 = codec47_table_big1;
- table47_2 = codec47_table_big2;
- ptr = _tableBig + 384;
- for (i = 0; i < 256; i++) {
- *ptr = 0;
- ptr += 388;
- }
- ptr = _tableBig + 385;
- for (i = 0; i < 256; i++) {
- *ptr = 0;
- ptr += 388;
- }
- } else if (param == 4) {
- table47_1 = codec47_table_small1;
- table47_2 = codec47_table_small2;
- ptr = _tableSmall + 96;
- for (i = 0; i < 256; i++) {
- *ptr = 0;
- ptr += 128;
- }
- ptr = _tableSmall + 97;
- for (i = 0; i < 256; i++) {
- *ptr = 0;
- ptr += 128;
- }
- } else {
- error("Codec47Decoder::makeTablesInterpolation: unknown param %d", param);
- }
-
- s = 0;
- for (x = 0; x < 16; x++) {
- value_table47_1_1 = table47_1[x];
- value_table47_2_1 = table47_2[x];
- for (y = 0; y < 16; y++) {
- value_table47_1_2 = table47_1[y];
- value_table47_2_2 = table47_2[y];
-
- if (value_table47_2_1 == 0) {
- b1 = 0;
- } else if (value_table47_2_1 == param - 1) {
- b1 = 1;
- } else if (value_table47_1_1 == 0) {
- b1 = 2;
- } else if (value_table47_1_1 == param - 1) {
- b1 = 3;
- } else {
- b1 = 4;
- }
-
- if (value_table47_2_2 == 0) {
- b2 = 0;
- } else if (value_table47_2_2 == param - 1) {
- b2 = 1;
- } else if (value_table47_1_2 == 0) {
- b2 = 2;
- } else if (value_table47_1_2 == param - 1) {
- b2 = 3;
- } else {
- b2 = 4;
- }
-
- memset(tableSmallBig, 0, param * param * 4);
-
- variable2 = ABS(value_table47_2_2 - value_table47_2_1);
- tmp = ABS(value_table47_1_2 - value_table47_1_1);
- if (variable2 <= tmp) {
- variable2 = tmp;
- }
-
- for (variable1 = 0; variable1 <= variable2; variable1++) {
- int32 variable3, variable4;
-
- if (variable2 > 0) {
- // Linearly interpolate between value_table47_1_1 and value_table47_1_2
- // respectively value_table47_2_1 and value_table47_2_2.
- variable4 = (value_table47_1_1 * variable1 + value_table47_1_2 * (variable2 - variable1) + variable2 / 2) / variable2;
- variable3 = (value_table47_2_1 * variable1 + value_table47_2_2 * (variable2 - variable1) + variable2 / 2) / variable2;
- } else {
- variable4 = value_table47_1_1;
- variable3 = value_table47_2_1;
- }
- ptr_small_big = &tableSmallBig[param * variable3 + variable4];
- *ptr_small_big = 1;
-
- if ((b1 == 2 && b2 == 3) || (b2 == 2 && b1 == 3) ||
- (b1 == 0 && b2 != 1) || (b2 == 0 && b1 != 1)) {
- if (variable3 >= 0) {
- i = variable3 + 1;
- while (i--) {
- *ptr_small_big = 1;
- ptr_small_big -= param;
- }
- }
- } else if ((b2 != 0 && b1 == 1) || (b1 != 0 && b2 == 1)) {
- if (param > variable3) {
- i = param - variable3;
- while (i--) {
- *ptr_small_big = 1;
- ptr_small_big += param;
- }
- }
- } else if ((b1 == 2 && b2 != 3) || (b2 == 2 && b1 != 3)) {
- if (variable4 >= 0) {
- i = variable4 + 1;
- while (i--) {
- *(ptr_small_big--) = 1;
- }
- }
- } else if ((b1 == 0 && b2 == 1) || (b2 == 0 && b1 == 1) ||
- (b1 == 3 && b2 != 2) || (b2 == 3 && b1 != 2)) {
- if (param > variable4) {
- i = param - variable4;
- while (i--) {
- *(ptr_small_big++) = 1;
- }
- }
- }
- }
-
- if (param == 8) {
- for (i = 64 - 1; i >= 0; i--) {
- if (tableSmallBig[i] != 0) {
- _tableBig[256 + s + _tableBig[384 + s]] = (byte)i;
- _tableBig[384 + s]++;
- } else {
- _tableBig[320 + s + _tableBig[385 + s]] = (byte)i;
- _tableBig[385 + s]++;
- }
- }
- s += 388;
- }
- if (param == 4) {
- for (i = 16 - 1; i >= 0; i--) {
- if (tableSmallBig[i] != 0) {
- _tableSmall[64 + s + _tableSmall[96 + s]] = (byte)i;
- _tableSmall[96 + s]++;
- } else {
- _tableSmall[80 + s + _tableSmall[97 + s]] = (byte)i;
- _tableSmall[97 + s]++;
- }
- }
- s += 128;
- }
- }
- }
-}
-
-void Codec47Decoder::makeTables47(int width) {
- if (_lastTableWidth == width)
- return;
-
- _lastTableWidth = width;
-
- int32 a, c, d;
- int16 tmp;
-
- for (int l = 0; l < 512; l += 2) {
- _table[l / 2] = (int16)(codec47_table[l + 1] * width + codec47_table[l]);
- }
-
- a = 0;
- c = 0;
- do {
- for (d = 0; d < _tableSmall[96 + c]; d++) {
- tmp = _tableSmall[64 + c + d];
- tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
- _tableSmall[c + d * 2] = (byte)tmp;
- _tableSmall[c + d * 2 + 1] = tmp >> 8;
- }
- for (d = 0; d < _tableSmall[97 + c]; d++) {
- tmp = _tableSmall[80 + c + d];
- tmp = (int16)((byte)(tmp >> 2) * width + (tmp & 3));
- _tableSmall[32 + c + d * 2] = (byte)tmp;
- _tableSmall[32 + c + d * 2 + 1] = tmp >> 8;
- }
- for (d = 0; d < _tableBig[384 + a]; d++) {
- tmp = _tableBig[256 + a + d];
- tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
- _tableBig[a + d * 2] = (byte)tmp;
- _tableBig[a + d * 2 + 1] = tmp >> 8;
- }
- for (d = 0; d < _tableBig[385 + a]; d++) {
- tmp = _tableBig[320 + a + d];
- tmp = (int16)((byte)(tmp >> 3) * width + (tmp & 7));
- _tableBig[128 + a + d * 2] = (byte)tmp;
- _tableBig[128 + a + d * 2 + 1] = tmp >> 8;
- }
-
- a += 388;
- c += 128;
- } while (c < 32768);
-}
-
-void Codec47Decoder::level3(byte *d_dst) {
- int32 tmp;
- byte code = *_d_src++;
-
- if (code < 0xF8) {
- tmp = _table[code] + _offset1;
- COPY_2X1_LINE(d_dst, d_dst + tmp);
- COPY_2X1_LINE(d_dst + _d_pitch, d_dst + _d_pitch + tmp);
- } else if (code == 0xFF) {
- COPY_2X1_LINE(d_dst, _d_src + 0);
- COPY_2X1_LINE(d_dst + _d_pitch, _d_src + 2);
- _d_src += 4;
- } else if (code == 0xFE) {
- byte t = *_d_src++;
- FILL_2X1_LINE(d_dst, t);
- FILL_2X1_LINE(d_dst + _d_pitch, t);
- } else if (code == 0xFC) {
- tmp = _offset2;
- COPY_2X1_LINE(d_dst, d_dst + tmp);
- COPY_2X1_LINE(d_dst + _d_pitch, d_dst + _d_pitch + tmp);
- } else {
- byte t = _paramPtr[code];
- FILL_2X1_LINE(d_dst, t);
- FILL_2X1_LINE(d_dst + _d_pitch, t);
- }
-}
-
-void Codec47Decoder::level2(byte *d_dst) {
- int32 tmp;
- byte code = *_d_src++;
- int i;
-
- if (code < 0xF8) {
- tmp = _table[code] + _offset1;
- for (i = 0; i < 4; i++) {
- COPY_4X1_LINE(d_dst, d_dst + tmp);
- d_dst += _d_pitch;
- }
- } else if (code == 0xFF) {
- level3(d_dst);
- d_dst += 2;
- level3(d_dst);
- d_dst += _d_pitch * 2 - 2;
- level3(d_dst);
- d_dst += 2;
- level3(d_dst);
- } else if (code == 0xFE) {
- byte t = *_d_src++;
- for (i = 0; i < 4; i++) {
- FILL_4X1_LINE(d_dst, t);
- d_dst += _d_pitch;
- }
- } else if (code == 0xFD) {
- byte *tmp_ptr = _tableSmall + *_d_src++ * 128;
- int32 l = tmp_ptr[96];
- byte val = *_d_src++;
- int16 *tmp_ptr2 = (int16 *)tmp_ptr;
- while (l--) {
- *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
- tmp_ptr2++;
- }
- l = tmp_ptr[97];
- val = *_d_src++;
- tmp_ptr2 = (int16 *)(tmp_ptr + 32);
- while (l--) {
- *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
- tmp_ptr2++;
- }
- } else if (code == 0xFC) {
- tmp = _offset2;
- for (i = 0; i < 4; i++) {
- COPY_4X1_LINE(d_dst, d_dst + tmp);
- d_dst += _d_pitch;
- }
- } else {
- byte t = _paramPtr[code];
- for (i = 0; i < 4; i++) {
- FILL_4X1_LINE(d_dst, t);
- d_dst += _d_pitch;
- }
- }
-}
-
-void Codec47Decoder::level1(byte *d_dst) {
- int32 tmp, tmp2;
- byte code = *_d_src++;
- int i;
-
- if (code < 0xF8) {
- tmp2 = _table[code] + _offset1;
- for (i = 0; i < 8; i++) {
- COPY_4X1_LINE(d_dst + 0, d_dst + tmp2);
- COPY_4X1_LINE(d_dst + 4, d_dst + tmp2 + 4);
- d_dst += _d_pitch;
- }
- } else if (code == 0xFF) {
- level2(d_dst);
- d_dst += 4;
- level2(d_dst);
- d_dst += _d_pitch * 4 - 4;
- level2(d_dst);
- d_dst += 4;
- level2(d_dst);
- } else if (code == 0xFE) {
- byte t = *_d_src++;
- for (i = 0; i < 8; i++) {
- FILL_4X1_LINE(d_dst, t);
- FILL_4X1_LINE(d_dst + 4, t);
- d_dst += _d_pitch;
- }
- } else if (code == 0xFD) {
- tmp = *_d_src++;
- byte *tmp_ptr = _tableBig + tmp * 388;
- byte l = tmp_ptr[384];
- byte val = *_d_src++;
- int16 *tmp_ptr2 = (int16 *)tmp_ptr;
- while (l--) {
- *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
- tmp_ptr2++;
- }
- l = tmp_ptr[385];
- val = *_d_src++;
- tmp_ptr2 = (int16 *)(tmp_ptr + 128);
- while (l--) {
- *(d_dst + READ_LE_UINT16(tmp_ptr2)) = val;
- tmp_ptr2++;
- }
- } else if (code == 0xFC) {
- tmp2 = _offset2;
- for (i = 0; i < 8; i++) {
- COPY_4X1_LINE(d_dst + 0, d_dst + tmp2);
- COPY_4X1_LINE(d_dst + 4, d_dst + tmp2 + 4);
- d_dst += _d_pitch;
- }
- } else {
- byte t = _paramPtr[code];
- for (i = 0; i < 8; i++) {
- FILL_4X1_LINE(d_dst, t);
- FILL_4X1_LINE(d_dst + 4, t);
- d_dst += _d_pitch;
- }
- }
-}
-
-void Codec47Decoder::decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr) {
- _d_src = src;
- _paramPtr = param_ptr - 0xf8;
- int bw = (width + 7) / 8;
- int bh = (height + 7) / 8;
- int next_line = width * 7;
- _d_pitch = width;
-
- do {
- int tmp_bw = bw;
- do {
- level1(dst);
- dst += 8;
- } while (--tmp_bw);
- dst += next_line;
- } while (--bh);
-}
-
-void Codec47Decoder::init(int width, int height) {
- deinit();
- _width = width;
- _height = height;
- makeTablesInterpolation(4);
- makeTablesInterpolation(8);
-
- _frameSize = _width * _height;
- _deltaSize = _frameSize * 3;
- _deltaBuf = (byte *)malloc(_deltaSize);
- _deltaBufs[0] = _deltaBuf;
- _deltaBufs[1] = _deltaBuf + _frameSize;
- _curBuf = _deltaBuf + _frameSize * 2;
-}
-
-Codec47Decoder::Codec47Decoder() {
- _tableBig = (byte *)malloc(99328);
- _tableSmall = (byte *)malloc(32768);
- _deltaBuf = NULL;
-}
-
-void Codec47Decoder::deinit() {
- _lastTableWidth = -1;
- if (_deltaBuf) {
- free(_deltaBuf);
- _deltaSize = 0;
- _deltaBuf = NULL;
- _deltaBufs[0] = NULL;
- _deltaBufs[1] = NULL;
- }
-}
-
-Codec47Decoder::~Codec47Decoder() {
- if (_tableBig) {
- free(_tableBig);
- _tableBig = NULL;
- }
- if (_tableSmall) {
- free(_tableSmall);
- _tableSmall = NULL;
- }
- deinit();
-}
-
-bool Codec47Decoder::decode(byte *dst, const byte *src) {
- _offset1 = _deltaBufs[1] - _curBuf;
- _offset2 = _deltaBufs[0] - _curBuf;
-
- int32 seq_nb = READ_LE_UINT16(src + 0);
-
- const byte *gfx_data = src + 26;
- byte *tmp_ptr;
-
- if (seq_nb == 0) {
- makeTables47(_width);
- memset(_deltaBufs[0], src[12], _frameSize);
- memset(_deltaBufs[1], src[13], _frameSize);
- _prevSeqNb = -1;
- }
-
- if ((src[4] & 1) != 0) {
- gfx_data += 32896;
- }
-
- switch(src[2]) {
- case 0:
- memcpy(_curBuf, gfx_data, _frameSize);
- break;
- case 1:
- error("codec47: not implemented decode1 proc");
- break;
- case 2:
- if (seq_nb == _prevSeqNb + 1) {
- decode2(_curBuf, gfx_data, _width, _height, src + 8);
- }
- break;
- case 3:
- memcpy(_curBuf, _deltaBufs[1], _frameSize);
- break;
- case 4:
- memcpy(_curBuf, _deltaBufs[0], _frameSize);
- break;
- case 5:
- bompDecodeLine(_curBuf, gfx_data, READ_LE_UINT32(src + 14));
- break;
- }
-
- memcpy(dst, _curBuf, _frameSize);
-
- if (seq_nb == _prevSeqNb + 1) {
- if (src[3] == 1) {
- tmp_ptr = _curBuf;
- _curBuf = _deltaBufs[1];
- _deltaBufs[1] = tmp_ptr;
- } else if (src[3] == 2) {
- tmp_ptr = _deltaBufs[0];
- _deltaBufs[0] = _deltaBufs[1];
- _deltaBufs[1] = _curBuf;
- _curBuf = tmp_ptr;
- }
- }
- _prevSeqNb = seq_nb;
-
- return true;
-}
-
-} // End of namespace Scumm
-
-#ifdef PALMOS_68K
-#include "scumm_globals.h"
-
-_GINIT(Codec47)
-_GSETPTR(Scumm::codec47_table, GBVARS_CODEC47TABLE_INDEX, int8, GBVARS_SCUMM)
-_GEND
-
-_GRELEASE(Codec47)
-_GRELEASEPTR(GBVARS_CODEC47TABLE_INDEX, GBVARS_SCUMM)
-_GEND
-
-#endif
diff --git a/scumm/smush/codec47.h b/scumm/smush/codec47.h
deleted file mode 100644
index ea71c22963..0000000000
--- a/scumm/smush/codec47.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SMUSH_CODEC_47_H
-#define SMUSH_CODEC_47_H
-
-#include "common/scummsys.h"
-
-namespace Scumm {
-
-class Codec47Decoder {
-private:
-
- int32 _deltaSize;
- byte *_deltaBufs[2];
- byte *_deltaBuf;
- byte *_curBuf;
- int32 _prevSeqNb;
- int _lastTableWidth;
- const byte *_d_src, *_paramPtr;
- int _d_pitch;
- int32 _offset1, _offset2;
- byte *_tableBig;
- byte *_tableSmall;
- int16 _table[256];
- int32 _frameSize;
- int _width, _height;
-
- void makeTablesInterpolation(int param);
- void makeTables47(int width);
- void level1(byte *d_dst);
- void level2(byte *d_dst);
- void level3(byte *d_dst);
- void decode2(byte *dst, const byte *src, int width, int height, const byte *param_ptr);
-
-public:
- Codec47Decoder();
- ~Codec47Decoder();
- void init(int width, int height);
- void deinit();
- bool decode(byte *dst, const byte *src);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/imuse_channel.cpp b/scumm/smush/imuse_channel.cpp
deleted file mode 100644
index 76a10a9e9e..0000000000
--- a/scumm/smush/imuse_channel.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/smush/channel.h"
-#include "scumm/smush/chunk.h"
-#include "scumm/smush/chunk_type.h"
-
-namespace Scumm {
-
-ImuseChannel::ImuseChannel(int32 track, int32 freq) :
- _track(track),
- _tbuffer(0),
- _tbufferSize(0),
- _sbuffer(0),
- _sbufferSize(0),
- _frequency(freq),
- _dataSize(-1),
- _inData(false) {
-}
-
-ImuseChannel::~ImuseChannel() {
- if (_tbuffer) {
- delete []_tbuffer;
- }
- if (_sbuffer) {
- warning("_sbuffer should be 0 !!!");
- delete []_sbuffer;
- }
-}
-
-bool ImuseChannel::isTerminated() const {
- return (_dataSize <= 0 && _sbuffer == 0);
-}
-
-bool ImuseChannel::setParameters(int32 nb, int32 size, int32 flags, int32 unk1, int32) {
- if ((flags == 1) || (flags == 2) || (flags == 3)) {
- _volume = 127;
- } else if ((flags >= 100) && (flags <= 163)) {
- _volume = flags * 2 - 200;
- } else if ((flags >= 200) && (flags <= 263)) {
- _volume = flags * 2 - 400;
- } else if ((flags >= 300) && (flags <= 363)) {
- _volume = flags * 2 - 600;
- } else {
- error("ImuseChannel::setParameters(): bad flags: %d", flags);
- }
- _pan = 0;
- return true;
-}
-
-bool ImuseChannel::checkParameters(int32 index, int32 nbframes, int32 size, int32 track_flags, int32 unk1) {
- return true;
-}
-
-bool ImuseChannel::appendData(Chunk &b, int32 size) {
- if (_dataSize == -1) {
- assert(size > 8);
- Chunk::type imus_type = b.getDword(); imus_type = SWAP_BYTES_32(imus_type);
- uint32 imus_size = b.getDword(); imus_size = SWAP_BYTES_32(imus_size);
- if (imus_type != TYPE_iMUS)
- error("Invalid Chunk for imuse_channel");
- size -= 8;
- _tbufferSize = size;
- assert(_tbufferSize);
- _tbuffer = new byte[_tbufferSize];
- if (!_tbuffer)
- error("imuse_channel failed to allocate memory");
- b.read(_tbuffer, size);
- _dataSize = -2;
- } else {
- if (_tbuffer) {
- byte *old = _tbuffer;
- int32 new_size = size + _tbufferSize;
- _tbuffer = new byte[new_size];
- if (!_tbuffer)
- error("imuse_channel failed to allocate memory");
- memcpy(_tbuffer, old, _tbufferSize);
- delete []old;
- b.read(_tbuffer + _tbufferSize, size);
- _tbufferSize += size;
- } else {
- _tbufferSize = size;
- _tbuffer = new byte[_tbufferSize];
- if (!_tbuffer)
- error("imuse_channel failed to allocate memory");
- b.read(_tbuffer, size);
- }
- }
- return processBuffer();
-}
-
-bool ImuseChannel::handleFormat(Chunk &src) {
- if (src.getSize() != 20) error("invalid size for FRMT Chunk");
- uint32 imuse_start = src.getDword();
- imuse_start = SWAP_BYTES_32(imuse_start);
- src.seek(4);
- _bitsize = src.getDword();
- _bitsize = SWAP_BYTES_32(_bitsize);
- _rate = src.getDword();
- _rate = SWAP_BYTES_32(_rate);
- _channels = src.getDword();
- _channels = SWAP_BYTES_32(_channels);
- assert(_channels == 1 || _channels == 2);
- return true;
-}
-
-bool ImuseChannel::handleRegion(Chunk &src) {
- if (src.getSize() != 8)
- error("invalid size for REGN Chunk");
- return true;
-}
-
-bool ImuseChannel::handleStop(Chunk &src) {
- if (src.getSize() != 4)
- error("invalid size for STOP Chunk");
- return true;
-}
-
-bool ImuseChannel::handleMap(Chunk &map) {
- while (!map.eof()) {
- Chunk *sub = map.subBlock();
- switch(sub->getType()) {
- case TYPE_FRMT:
- handleFormat(*sub);
- break;
- case TYPE_TEXT:
- break;
- case TYPE_REGN:
- handleRegion(*sub);
- break;
- case TYPE_STOP:
- handleStop(*sub);
- break;
- default:
- error("Unknown iMUS subChunk found : %s, %d", Chunk::ChunkString(sub->getType()), sub->getSize());
- }
- delete sub;
- }
- return true;
-}
-
-void ImuseChannel::decode() {
- int remaining_size = _sbufferSize % 3;
- if (remaining_size) {
- _srbufferSize -= remaining_size;
- assert(_inData);
- if (_tbuffer == 0) {
- _tbuffer = new byte[remaining_size];
- memcpy(_tbuffer, _sbuffer + _sbufferSize - remaining_size, remaining_size);
- _tbufferSize = remaining_size;
- _sbufferSize -= remaining_size;
- } else {
- debugC(DEBUG_SMUSH, "impossible ! : %p, %d, %d, %p(%d), %p(%d, %d)",
- this, _dataSize, _inData, _tbuffer, _tbufferSize, _sbuffer, _sbufferSize, _srbufferSize);
- byte *old = _tbuffer;
- int new_size = remaining_size + _tbufferSize;
- _tbuffer = new byte[new_size];
- if (!_tbuffer) error("imuse_channel failed to allocate memory");
- memcpy(_tbuffer, old, _tbufferSize);
- delete []old;
- memcpy(_tbuffer + _tbufferSize, _sbuffer + _sbufferSize - remaining_size, remaining_size);
- _tbufferSize += remaining_size;
- }
- }
-
- // FIXME: Code duplication! See decode12BitsSample() in scumm/imuse_digi.cpp
-
- int loop_size = _sbufferSize / 3;
- int new_size = loop_size * 4;
- byte *keep, *decoded;
- uint32 value;
- keep = decoded = new byte[new_size];
- assert(keep);
- unsigned char * source = _sbuffer;
-
- while (loop_size--) {
- byte v1 = *source++;
- byte v2 = *source++;
- byte v3 = *source++;
- value = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
- WRITE_BE_UINT16(decoded, value); decoded += 2;
- value = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
- WRITE_BE_UINT16(decoded, value); decoded += 2;
- }
- delete []_sbuffer;
- _sbuffer = (byte *)keep;
- _sbufferSize = new_size;
-}
-
-bool ImuseChannel::handleSubTags(int32 &offset) {
- if (_tbufferSize - offset >= 8) {
- Chunk::type type = READ_BE_UINT32(_tbuffer + offset);
- uint32 size = READ_BE_UINT32(_tbuffer + offset + 4);
- uint32 available_size = _tbufferSize - offset;
- switch(type) {
- case TYPE_MAP_:
- _inData = false;
- if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- handleMap(c);
- }
- break;
- case TYPE_DATA:
- _inData = true;
- _dataSize = size;
- offset += 8;
- {
- int reqsize = 1;
- if (_channels == 2)
- reqsize *= 2;
- if (_bitsize == 16)
- reqsize *= 2;
- else if (_bitsize == 12) {
- if (reqsize > 1)
- reqsize = reqsize * 3 / 2;
- else reqsize = 3;
- }
- if ((size % reqsize) != 0) {
- debugC(DEBUG_SMUSH, "Invalid iMUS sound data size : (%d %% %d) != 0, correcting...", size, reqsize);
- size += 3 - (size % reqsize);
- }
- }
- return false;
- default:
- error("unknown Chunk in iMUS track : %s ", Chunk::ChunkString(type));
- }
- offset += size + 8;
- return true;
- }
- return false;
-}
-
-bool ImuseChannel::processBuffer() {
- assert(_tbuffer != 0);
- assert(_tbufferSize != 0);
- assert(_sbuffer == 0);
- assert(_sbufferSize == 0);
-
- if (_inData) {
- if (_dataSize < _tbufferSize) {
- int32 offset= _dataSize;
- while (handleSubTags(offset));
- _sbufferSize = _dataSize;
- _sbuffer = _tbuffer;
- if (offset < _tbufferSize) {
- int32 new_size = _tbufferSize - offset;
- _tbuffer = new byte[new_size];
- if (!_tbuffer) error("imuse_channel failed to allocate memory");
- memcpy(_tbuffer, _sbuffer + offset, new_size);
- _tbufferSize = new_size;
- } else {
- _tbuffer = 0;
- _tbufferSize = 0;
- }
- if (_sbufferSize == 0) {
- delete []_sbuffer;
- _sbuffer = 0;
- }
- } else {
- _sbufferSize = _tbufferSize;
- _sbuffer = _tbuffer;
- _tbufferSize = 0;
- _tbuffer = 0;
- }
- } else {
- int32 offset = 0;
- while (handleSubTags(offset));
- if (_inData) {
- _sbufferSize = _tbufferSize - offset;
- assert(_sbufferSize);
- _sbuffer = new byte[_sbufferSize];
- if (!_sbuffer) error("imuse_channel failed to allocate memory");
- memcpy(_sbuffer, _tbuffer + offset, _sbufferSize);
- delete []_tbuffer;
- _tbuffer = 0;
- _tbufferSize = 0;
- } else {
- if (offset) {
- byte * old = _tbuffer;
- int32 new_size = _tbufferSize - offset;
- _tbuffer = new byte[new_size];
- if (!_tbuffer) error("imuse_channel failed to allocate memory");
- memcpy(_tbuffer, old + offset, new_size);
- _tbufferSize = new_size;
- delete []old;
- }
- }
- }
- _srbufferSize = _sbufferSize;
- if (_sbuffer && _bitsize == 12) decode();
- return true;
-}
-
-int32 ImuseChannel::availableSoundData(void) const {
- int32 ret = _sbufferSize;
- if (_channels == 2) ret /= 2;
- if (_bitsize > 8) ret /= 2;
- return ret;
-}
-
-void ImuseChannel::getSoundData(int16 *snd, int32 size) {
- if (_dataSize <= 0 || _bitsize <= 8) error("invalid call to imuse_channel::read_sound_data()");
- if (_channels == 2) size *= 2;
-
- memcpy(snd, _sbuffer, size * 2);
-
- delete []_sbuffer;
- assert(_sbufferSize == 2 * size);
- _sbuffer = 0;
- _sbufferSize = 0;
- _dataSize -= _srbufferSize;
-}
-
-void ImuseChannel::getSoundData(int8 *snd, int32 size) {
- if (_dataSize <= 0 || _bitsize > 8) error("invalid call to imuse_channel::read_sound_data()");
- if (_channels == 2) size *= 2;
-
- memcpy(snd, _sbuffer, size);
-
- delete []_sbuffer;
- _sbuffer = 0;
- _sbufferSize = 0;
- _dataSize -= _srbufferSize;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/smush/saud_channel.cpp b/scumm/smush/saud_channel.cpp
deleted file mode 100644
index 2277336570..0000000000
--- a/scumm/smush/saud_channel.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/smush/channel.h"
-#include "scumm/smush/chunk.h"
-#include "scumm/smush/chunk_type.h"
-
-namespace Scumm {
-
-void SaudChannel::handleStrk(Chunk &b) {
- int32 size = b.getSize();
- if (size != 14 && size != 10) {
- error("STRK has an invalid size : %d", size);
- }
-}
-
-void SaudChannel::handleSmrk(Chunk &b) {
- _markReached = true;
-}
-
-void SaudChannel::handleShdr(Chunk &b) {
- int32 size = b.getSize();
- if (size != 4)
- error("SHDR has an invalid size : %d", size);
-}
-
-bool SaudChannel::handleSubTags(int32 &offset) {
- if (_tbufferSize - offset >= 8) {
- Chunk::type type = READ_BE_UINT32(_tbuffer + offset);
- uint32 size = READ_BE_UINT32(_tbuffer + offset + 4);
- uint32 available_size = _tbufferSize - offset;
-
- switch(type) {
- case TYPE_STRK:
- _inData = false;
- if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- handleStrk(c);
- } else
- return false;
- break;
- case TYPE_SMRK:
- _inData = false;
- if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- handleSmrk(c);
- } else
- return false;
- break;
- case TYPE_SHDR:
- _inData = false;
- if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- handleShdr(c);
- } else
- return false;
- break;
- case TYPE_SDAT:
- _inData = true;
- _dataSize = size;
- offset += 8;
- return false;
- default:
- error("unknown Chunk in SAUD track : %s ", Chunk::ChunkString(type));
- }
- offset += size + 8;
- return true;
- }
- return false;
-}
-
-bool SaudChannel::processBuffer() {
- assert(_tbuffer != 0);
- assert(_tbufferSize != 0);
- assert(_sbuffer == 0);
- assert(_sbufferSize == 0);
-
- if (_keepSize) {
- _sbufferSize = _tbufferSize;
- _sbuffer = _tbuffer;
- _tbufferSize = 0;
- _tbuffer = 0;
- } else if (_inData) {
- if (_dataSize < _tbufferSize) {
- int32 offset = _dataSize;
- while (handleSubTags(offset)) ;
- _sbufferSize = _dataSize;
- _sbuffer = _tbuffer;
- if (offset < _tbufferSize) {
- int new_size = _tbufferSize - offset;
- _tbuffer = new byte[new_size];
- if (!_tbuffer)
- error("SaudChannel failed to allocate memory");
- memcpy(_tbuffer, _sbuffer + offset, new_size);
- _tbufferSize = new_size;
- } else {
- _tbuffer = 0;
- _tbufferSize = 0;
- }
- if (_sbufferSize == 0) {
- delete []_sbuffer;
- _sbuffer = 0;
- }
- } else {
- _sbufferSize = _tbufferSize;
- _sbuffer = _tbuffer;
- _tbufferSize = 0;
- _tbuffer = 0;
- }
- } else {
- int32 offset = 0;
- while (handleSubTags(offset));
- if (_inData) {
- _sbufferSize = _tbufferSize - offset;
- assert(_sbufferSize);
- _sbuffer = new byte[_sbufferSize];
- if (!_sbuffer)
- error("saud_channel failed to allocate memory");
- memcpy(_sbuffer, _tbuffer + offset, _sbufferSize);
- delete []_tbuffer;
- _tbuffer = 0;
- _tbufferSize = 0;
- } else {
- if (offset) {
- byte *old = _tbuffer;
- int32 new_size = _tbufferSize - offset;
- _tbuffer = new byte[new_size];
- if (!_tbuffer)
- error("SaudChannel failed to allocate memory");
- memcpy(_tbuffer, old + offset, new_size);
- _tbufferSize = new_size;
- delete []old;
- }
- }
- }
- return true;
-}
-
-SaudChannel::SaudChannel(int32 track, int32 freq) :
- _track(track),
- _nbframes(0),
- _dataSize(-1),
- _frequency(freq),
- _inData(false),
- _markReached(false),
- _index(0),
- _tbuffer(0),
- _tbufferSize(0),
- _sbuffer(0),
- _sbufferSize(0),
- _keepSize(false) {
-}
-
-SaudChannel::~SaudChannel() {
- _dataSize = 0;
- _tbufferSize = 0;
- _sbufferSize = 0;
- _markReached = true;
- if (_tbuffer)
- delete []_tbuffer;
- if (_sbuffer) {
- // _sbuffer can be not empty here with insane when it seeks in video
- delete []_sbuffer;
- }
- _sbuffer = 0;
-}
-
-bool SaudChannel::isTerminated() const {
- return (_markReached && _dataSize == 0 && _sbuffer == 0);
-}
-
-bool SaudChannel::setParameters(int32 nb, int32 flags, int32 volume, int32 pan, int32 index) {
- _nbframes = nb;
- _flags = flags; // bit 7 == IS_VOICE, bit 6 == IS_BACKGROUND_MUSIC, other ??
- _volume = volume;
- _pan = pan;
- _index = index;
- if (index != 0) {
- _dataSize = -2;
- _keepSize = true;
- _inData = true;
- }
- return true;
-}
-
-bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volume, int32 pan) {
- if (++_index != index)
- error("invalid index in SaudChannel::checkParameters()");
- if (_nbframes != nb)
- error("invalid duration in SaudChannel::checkParameters()");
- if (_flags != flags)
- error("invalid flags in SaudChannel::checkParameters()");
- if (_volume != volume || _pan != pan) {
- _volume = volume;
- _pan = pan;
- }
- return true;
-}
-
-bool SaudChannel::appendData(Chunk &b, int32 size) {
- if (_dataSize == -1) {
- assert(size > 8);
- Chunk::type saud_type = b.getDword();
- saud_type = SWAP_BYTES_32(saud_type);
- uint32 saud_size = b.getDword();
- saud_size = SWAP_BYTES_32(saud_size);
- if (saud_type != TYPE_SAUD)
- error("Invalid Chunk for SaudChannel : %X", saud_type);
- size -= 8;
- _dataSize = -2;
- }
- if (_tbuffer) {
- byte *old = _tbuffer;
- _tbuffer = new byte[_tbufferSize + size];
- if (!_tbuffer)
- error("saud_channel failed to allocate memory");
- memcpy(_tbuffer, old, _tbufferSize);
- delete []old;
- b.read(_tbuffer + _tbufferSize, size);
- _tbufferSize += size;
- } else {
- _tbufferSize = size;
- _tbuffer = new byte[_tbufferSize];
- if (!_tbuffer)
- error("saud_channel failed to allocate memory");
- b.read(_tbuffer, _tbufferSize);
- }
- return processBuffer();
-}
-
-int32 SaudChannel::availableSoundData(void) const {
- return _sbufferSize;
-}
-
-void SaudChannel::getSoundData(int16 *snd, int32 size) {
- for (int32 i = 0; i < size; i++) {
- snd[2 * i] = TO_LE_16(_sbuffer[i] ^ 0x80);
- snd[2 * i + 1] = TO_LE_16(_sbuffer[i] ^ 0x80);
- }
- if (!_keepSize)
- _dataSize -= size;
- delete []_sbuffer;
- _sbuffer = 0;
- _sbufferSize = 0;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/smush/smush_font.cpp b/scumm/smush/smush_font.cpp
deleted file mode 100644
index 96d9e2f7c5..0000000000
--- a/scumm/smush/smush_font.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/file.h"
-#include "scumm/scumm.h"
-#include "scumm/util.h"
-
-#include "scumm/smush/smush_font.h"
-
-namespace Scumm {
-
-SmushFont::SmushFont(ScummEngine *vm, bool use_original_colors, bool new_colors) :
- NutRenderer(vm),
- _color(-1),
- _new_colors(new_colors),
- _original(use_original_colors) {
-}
-
-int SmushFont::getStringWidth(const char *str) {
- assert(str);
- if (!_loaded) {
- error("SmushFont::getStringWidth() Font is not loaded");
- return 0;
- }
-
- int width = 0;
- while (*str) {
- if (*str & 0x80 && _vm->_useCJKMode) {
- width += _vm->_2byteWidth + 1;
- str += 2;
- } else
- width += getCharWidth(*str++);
- }
- return width;
-}
-
-int SmushFont::getStringHeight(const char *str) {
- assert(str);
- if (!_loaded) {
- error("SmushFont::getStringHeight() Font is not loaded");
- return 0;
- }
-
- int height = 0;
- while (*str) {
- int charHeight = getCharHeight(*str++);
- if (height < charHeight)
- height = charHeight;
- }
- return height;
-}
-
-int SmushFont::drawChar(byte *buffer, int dst_width, int x, int y, byte chr) {
- int w = _chars[chr].width;
- int h = _chars[chr].height;
- const byte *src = _chars[chr].src;
- byte *dst = buffer + dst_width * y + x;
-
- assert(dst_width == _vm->_screenWidth);
-
- if (_original) {
- for (int j = 0; j < h; j++) {
- for (int i = 0; i < w; i++) {
- int8 value = *src++;
- if (value)
- dst[i] = value;
- }
- dst += dst_width;
- }
- } else {
- char color = (_color != -1) ? _color : 1;
- if (_new_colors) {
- for (int j = 0; j < h; j++) {
- for (int i = 0; i < w; i++) {
- int8 value = *src++;
- if (value == -color) {
- dst[i] = 0xFF;
- } else if (value == -31) {
- dst[i] = 0;
- } else if (value) {
- dst[i] = value;
- }
- }
- dst += dst_width;
- }
- } else {
- for (int j = 0; j < h; j++) {
- for (int i = 0; i < w; i++) {
- int8 value = *src++;
- if (value == 1) {
- dst[i] = color;
- } else if (value) {
- dst[i] = 0;
- }
- }
- dst += dst_width;
- }
- }
- }
- return w;
-}
-
-int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) {
- int w = _vm->_2byteWidth;
- int h = _vm->_2byteHeight;
-
- byte *src = _vm->get2byteCharPtr(idx);
- byte *dst = buffer + dst_width * (y + (_vm->_gameId == GID_CMI ? 7 : (_vm->_gameId == GID_DIG ? 2 : 0))) + x;
- byte bits = 0;
-
- char color = (_color != -1) ? _color : 1;
-
- if (_new_colors)
- color = (char)0xff;
-
- if (_vm->_gameId == GID_FT)
- color = 1;
-
- for (int j = 0; j < h; j++) {
- for (int i = 0; i < w; i++) {
- if ((i % 8) == 0)
- bits = *src++;
- if (bits & revBitMask(i % 8)) {
- dst[i + 1] = 0;
- dst[dst_width + i] = 0;
- dst[dst_width + i + 1] = 0;
- dst[i] = color;
- }
- }
- dst += dst_width;
- }
- return w + 1;
-}
-
-void SmushFont::drawSubstring(const char *str, byte *buffer, int dst_width, int x, int y) {
- // This happens in the Full Throttle intro. I don't know if our
- // text-drawing functions are buggy, or if this function is supposed
- // to have to check for it.
- if (x < 0)
- x = 0;
-
- for (int i = 0; str[i] != 0; i++) {
- if ((byte)str[i] >= 0x80 && _vm->_useCJKMode) {
- x += draw2byte(buffer, dst_width, x, y, (byte)str[i] + 256 * (byte)str[i+1]);
- i++;
- } else
- x += drawChar(buffer, dst_width, x, y, str[i]);
- }
-}
-
-#define MAX_WORDS 60
-
-
-void SmushFont::drawString(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, bool center) {
- debugC(DEBUG_SMUSH, "SmushFont::drawString(%s, %d, %d, %d)", str, x, y, center);
-
- while (str) {
- char line[256];
- char *pos = (char *)strchr(str, '\n');
- if (pos) {
- memcpy(line, str, pos - str - 1);
- line[pos - str - 1] = 0;
- str = pos + 1;
- } else {
- strcpy(line, str);
- str = 0;
- }
- drawSubstring(line, buffer, dst_width, center ? (x - getStringWidth(line) / 2) : x, y);
- y += getStringHeight(line);
- }
-}
-
-void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right, bool center) {
- debugC(DEBUG_SMUSH, "SmushFont::drawStringWrap(%s, %d, %d, %d, %d, %d)", str, x, y, left, right, center);
-
- const int width = right - left;
- char *s = strdup(str);
- char *words[MAX_WORDS];
- int word_count = 0;
-
- char *tmp = s;
- while (tmp) {
- assert(word_count < MAX_WORDS);
- words[word_count++] = tmp;
- tmp = strpbrk(tmp, " \t\r\n");
- if (tmp == 0)
- break;
- *tmp++ = 0;
- }
-
- int i = 0, max_width = 0, height = 0, line_count = 0;
-
- char *substrings[MAX_WORDS];
- int substr_widths[MAX_WORDS];
- const int space_width = getCharWidth(' ');
-
- i = 0;
- while (i < word_count) {
- char *substr = words[i++];
- int substr_width = getStringWidth(substr);
-
- while (i < word_count) {
- int word_width = getStringWidth(words[i]);
- if ((substr_width + space_width + word_width) >= width)
- break;
- substr_width += word_width + space_width;
- *(words[i]-1) = ' '; // Convert 0 byte back to space
- i++;
- }
-
- substrings[line_count] = substr;
- substr_widths[line_count++] = substr_width;
- if (max_width < substr_width)
- max_width = substr_width;
- height += getStringHeight(substr);
- }
-
- if (y > dst_height - height) {
- y = dst_height - height;
- }
-
- if (center) {
- max_width = (max_width + 1) / 2;
- x = left + width / 2;
-
- if (x < left + max_width)
- x = left + max_width;
- if (x > right - max_width)
- x = right - max_width;
-
- for (i = 0; i < line_count; i++) {
- drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y);
- y += getStringHeight(substrings[i]);
- }
- } else {
- if (x > dst_width - max_width)
- x = dst_width - max_width;
-
- for (i = 0; i < line_count; i++) {
- drawSubstring(substrings[i], buffer, dst_width, x, y);
- y += getStringHeight(substrings[i]);
- }
- }
-
- free(s);
-}
-
-} // End of namespace Scumm
-
diff --git a/scumm/smush/smush_font.h b/scumm/smush/smush_font.h
deleted file mode 100644
index 724eb46658..0000000000
--- a/scumm/smush/smush_font.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SMUSH_FONT_H
-#define SMUSH_FONT_H
-
-#include "common/scummsys.h"
-#include "scumm/nut_renderer.h"
-
-namespace Scumm {
-
-class SmushFont : public NutRenderer {
-protected:
- int16 _color;
- bool _new_colors;
- bool _original;
-
-
- int getStringWidth(const char *str);
- int getStringHeight(const char *str);
- int draw2byte(byte *buffer, int dst_width, int x, int y, int idx);
- int drawChar(byte *buffer, int dst_width, int x, int y, byte chr);
- void drawSubstring(const char *str, byte *buffer, int dst_width, int x, int y);
-
-public:
- SmushFont(ScummEngine *vm, bool use_original_colors, bool new_colors);
-
- void setColor(byte c) { _color = c; }
- void drawString (const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, bool center);
- void drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right, bool center);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/smush_mixer.cpp b/scumm/smush/smush_mixer.cpp
deleted file mode 100644
index 00a50321da..0000000000
--- a/scumm/smush/smush_mixer.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/util.h"
-
-#include "scumm/smush/smush_mixer.h"
-#include "scumm/smush/channel.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/imuse.h"
-
-#include "sound/mixer.h"
-
-
-namespace Scumm {
-
-SmushMixer::SmushMixer(Audio::Mixer *m) :
- _mixer(m),
- _soundFrequency(22050) {
- for (int32 i = 0; i < NUM_CHANNELS; i++) {
- _channels[i].id = -1;
- _channels[i].chan = NULL;
- _channels[i].stream = NULL;
- }
-}
-
-SmushMixer::~SmushMixer() {
- Common::StackLock lock(_mutex);
- for (int32 i = 0; i < NUM_CHANNELS; i++) {
- _mixer->stopHandle(_channels[i].handle);
- }
-}
-
-SmushChannel *SmushMixer::findChannel(int32 track) {
- Common::StackLock lock(_mutex);
- debugC(DEBUG_SMUSH, "SmushMixer::findChannel(%d)", track);
- for (int32 i = 0; i < NUM_CHANNELS; i++) {
- if (_channels[i].id == track)
- return _channels[i].chan;
- }
- return NULL;
-}
-
-void SmushMixer::addChannel(SmushChannel *c) {
- Common::StackLock lock(_mutex);
- int32 track = c->getTrackIdentifier();
- int i;
-
- debugC(DEBUG_SMUSH, "SmushMixer::addChannel(%d)", track);
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- if (_channels[i].id == track)
- debugC(DEBUG_SMUSH, "SmushMixer::addChannel(%d): channel already exists", track);
- }
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- if ((_channels[i].chan == NULL || _channels[i].id == -1) && !_mixer->isSoundHandleActive(_channels[i].handle)) {
- _channels[i].chan = c;
- _channels[i].id = track;
- return;
- }
- }
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- debugC(DEBUG_SMUSH, "channel %d : %p(%d, %d)", i, (void *)_channels[i].chan,
- _channels[i].chan ? _channels[i].chan->getTrackIdentifier() : -1,
- _channels[i].chan ? _channels[i].chan->isTerminated() : 1);
- }
-
- error("SmushMixer::addChannel(%d): no channel available", track);
-}
-
-bool SmushMixer::handleFrame() {
- Common::StackLock lock(_mutex);
- debugC(DEBUG_SMUSH, "SmushMixer::handleFrame()");
- for (int i = 0; i < NUM_CHANNELS; i++) {
- if (_channels[i].id != -1) {
- if (_channels[i].chan->isTerminated()) {
- delete _channels[i].chan;
- _channels[i].id = -1;
- _channels[i].chan = NULL;
- if (_channels[i].stream) {
- _channels[i].stream->finish();
- _channels[i].stream = 0;
- }
- } else {
- int32 rate, vol, pan;
- bool stereo, is_16bit;
- void *data;
-
- _channels[i].chan->getParameters(rate, stereo, is_16bit, vol, pan);
- int32 size = _channels[i].chan->availableSoundData();
- byte flags = stereo ? Audio::Mixer::FLAG_STEREO : 0;
-
- if (is_16bit) {
- data = malloc(size * (stereo ? 2 : 1) * 4);
- _channels[i].chan->getSoundData((int16 *)data, size);
- size *= stereo ? 4 : 2;
-
- flags |= Audio::Mixer::FLAG_16BITS;
-
- } else {
- data = malloc(size * (stereo ? 2 : 1) * 2);
- _channels[i].chan->getSoundData((int8 *)data, size);
- size *= stereo ? 2 : 1;
-
- flags |= Audio::Mixer::FLAG_UNSIGNED;
- }
-
- if (_mixer->isReady()) {
- if (!_channels[i].stream) {
- _channels[i].stream = makeAppendableAudioStream(rate, flags, 500000);
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_channels[i].handle, _channels[i].stream);
- }
- _mixer->setChannelVolume(_channels[i].handle, vol);
- _mixer->setChannelBalance(_channels[i].handle, pan);
- _channels[i].stream->append((byte *)data, size);
- }
- free(data);
- }
- }
- }
- return true;
-}
-
-bool SmushMixer::stop() {
- Common::StackLock lock(_mutex);
- debugC(DEBUG_SMUSH, "SmushMixer::stop()");
- for (int i = 0; i < NUM_CHANNELS; i++) {
- if (_channels[i].id != -1) {
- delete _channels[i].chan;
- _channels[i].id = -1;
- _channels[i].chan = NULL;
- if (_channels[i].stream) {
- _channels[i].stream->finish();
- _channels[i].stream = 0;
- }
- }
- }
- return true;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/smush/smush_mixer.h b/scumm/smush/smush_mixer.h
deleted file mode 100644
index 2a7c2d3ebc..0000000000
--- a/scumm/smush/smush_mixer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SMUSH_MIXER_H
-#define SMUSH_MIXER_H
-
-#include "common/stdafx.h"
-#include "scumm/sound.h"
-
-namespace Scumm {
-
-class SmushChannel;
-
-class SmushMixer {
- enum {
- NUM_CHANNELS = 16
- };
-private:
-
- Audio::Mixer *_mixer;
- struct channels {
- int id;
- SmushChannel *chan;
- Audio::SoundHandle handle;
- AppendableAudioStream *stream;
- } _channels[NUM_CHANNELS];
-
- int _soundFrequency;
-
- Common::Mutex _mutex;
-
-public:
-
- SmushMixer(Audio::Mixer *);
- virtual ~SmushMixer();
- SmushChannel *findChannel(int32 track);
- void addChannel(SmushChannel *c);
- bool handleFrame();
- bool stop();
- bool update();
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp
deleted file mode 100644
index 926e7f9f87..0000000000
--- a/scumm/smush/smush_player.cpp
+++ /dev/null
@@ -1,1359 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "base/engine.h"
-
-#include "common/config-manager.h"
-#include "common/file.h"
-#include "common/system.h"
-#include "common/timer.h"
-#include "common/util.h"
-
-#include "scumm/bomp.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/imuse.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/smush/channel.h"
-#include "scumm/smush/chunk_type.h"
-#include "scumm/smush/chunk.h"
-#include "scumm/smush/smush_font.h"
-#include "scumm/smush/smush_mixer.h"
-#include "scumm/smush/smush_player.h"
-
-#include "scumm/insane/insane.h"
-
-#include "sound/mixer.h"
-#include "sound/vorbis.h"
-#include "sound/mp3.h"
-
-#ifdef DUMP_SMUSH_FRAMES
-#include <png.h>
-#endif
-
-#ifdef USE_ZLIB
-#include <zlib.h>
-#endif
-
-namespace Scumm {
-
-const int MAX_STRINGS = 200;
-
-class StringResource {
-private:
-
- struct {
- int id;
- char *string;
- } _strings[MAX_STRINGS];
-
- int _nbStrings;
- int _lastId;
- const char *_lastString;
-
-public:
-
- StringResource() :
- _nbStrings(0),
- _lastId(-1) {
- };
- ~StringResource() {
- for (int32 i = 0; i < _nbStrings; i++) {
- delete []_strings[i].string;
- }
- }
-
- bool init(char *buffer, int32 length) {
- char *def_start = strchr(buffer, '#');
- while (def_start != NULL) {
- char *def_end = strchr(def_start, '\n');
- assert(def_end != NULL);
-
- char *id_end = def_end;
- while (id_end >= def_start && !isdigit(*(id_end-1))) {
- id_end--;
- }
-
- assert(id_end > def_start);
- char *id_start = id_end;
- while (isdigit(*(id_start - 1))) {
- id_start--;
- }
-
- char idstring[32];
- memcpy(idstring, id_start, id_end - id_start);
- idstring[id_end - id_start] = 0;
- int32 id = atoi(idstring);
- char *data_start = def_end;
-
- while (*data_start == '\n' || *data_start == '\r') {
- data_start++;
- }
- char *data_end = data_start;
-
- while (1) {
- if (data_end[-2] == '\r' && data_end[-1] == '\n' && data_end[0] == '\r' && data_end[1] == '\n') {
- break;
- }
- // In Russian Full Throttle strings are finished with
- // just one pair of CR-LF
- if (data_end[-2] == '\r' && data_end[-1] == '\n' && data_end[0] == '#') {
- break;
- }
- data_end++;
- if (data_end >= buffer + length) {
- data_end = buffer + length;
- break;
- }
- }
-
- data_end -= 2;
- assert(data_end > data_start);
- char *value = new char[data_end - data_start + 1];
- assert(value);
- memcpy(value, data_start, data_end - data_start);
- value[data_end - data_start] = 0;
- char *line_start = value;
- char *line_end;
-
- while ((line_end = strchr(line_start, '\n'))) {
- line_start = line_end+1;
- if (line_start[0] == '/' && line_start[1] == '/') {
- line_start += 2;
- if (line_end[-1] == '\r')
- line_end[-1] = ' ';
- else
- *line_end++ = ' ';
- memmove(line_end, line_start, strlen(line_start)+1);
- }
- }
- _strings[_nbStrings].id = id;
- _strings[_nbStrings].string = value;
- _nbStrings ++;
- def_start = strchr(data_end + 2, '#');
- }
- return true;
- }
-
- const char *get(int id) {
- if (id == _lastId) {
- return _lastString;
- }
- debugC(DEBUG_SMUSH, "StringResource::get(%d)", id);
- for (int i = 0; i < _nbStrings; i++) {
- if (_strings[i].id == id) {
- _lastId = id;
- _lastString = _strings[i].string;
- return _strings[i].string;
- }
- }
- warning("invalid string id : %d", id);
- _lastId = -1;
- _lastString = "unknown string";
- return _lastString;
- }
-};
-
-static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_encoded) {
- debugC(DEBUG_SMUSH, "trying to read text ressources from %s", file);
- ScummFile theFile;
-
- vm->openFile(theFile, file);
- if (!theFile.isOpen()) {
- return 0;
- }
- int32 length = theFile.size();
- char *filebuffer = new char [length + 1];
- assert(filebuffer);
- theFile.read(filebuffer, length);
- filebuffer[length] = 0;
-
- if (is_encoded) {
- enum {
- ETRS_HEADER_LENGTH = 16
- };
- assert(length > ETRS_HEADER_LENGTH);
- Chunk::type type = READ_BE_UINT32(filebuffer);
-
- if (type != TYPE_ETRS) {
- delete [] filebuffer;
- return getStrings(vm, file, false);
- }
-
- char *old = filebuffer;
- filebuffer = new char[length - ETRS_HEADER_LENGTH + 1];
- for (int32 i = ETRS_HEADER_LENGTH; i < length; i++) {
- filebuffer[i - ETRS_HEADER_LENGTH] = old[i] ^ 0xCC;
- }
- filebuffer[length - ETRS_HEADER_LENGTH] = '\0';
- delete []old;
- length -= ETRS_HEADER_LENGTH;
- }
- StringResource *sr = new StringResource;
- assert(sr);
- sr->init(filebuffer, length);
- delete []filebuffer;
- return sr;
-}
-
-void SmushPlayer::timerCallback(void *refCon) {
- ((SmushPlayer *)refCon)->parseNextFrame();
-#ifdef _WIN32_WCE
- ((SmushPlayer *)refCon)->_inTimer = true;
- ((SmushPlayer *)refCon)->_inTimerCount++;
-#endif
-}
-
-SmushPlayer::SmushPlayer(ScummEngine_v6 *scumm, int speed) {
- _vm = scumm;
- _version = -1;
- _nbframes = 0;
- _smixer = 0;
- _strings = NULL;
- _sf[0] = NULL;
- _sf[1] = NULL;
- _sf[2] = NULL;
- _sf[3] = NULL;
- _sf[4] = NULL;
- _base = NULL;
- _frameBuffer = NULL;
- _specialBuffer = NULL;
-
- _seekPos = -1;
-
- _skipNext = false;
- _subtitles = ConfMan.getBool("subtitles");
- _dst = NULL;
- _storeFrame = false;
- _compressedFileMode = false;
- _width = 0;
- _height = 0;
- _IACTpos = 0;
- _soundFrequency = 22050;
- _initDone = false;
- _speed = speed;
- _insanity = false;
- _middleAudio = false;
- _skipPalette = false;
- _IACTstream = NULL;
-#ifdef _WIN32_WCE
- _inTimer = false;
- _inTimerCount = 0;
- _inTimerCountRedraw = ConfMan.getInt("Smush_force_redraw");
-#endif
-}
-
-SmushPlayer::~SmushPlayer() {
- release();
-}
-
-void SmushPlayer::init() {
- _frame = 0;
- _alreadyInit = false;
- _vm->_smushVideoShouldFinish = false;
- _vm->setDirtyColors(0, 255);
- _dst = _vm->virtscr[0].getPixels(0, 0);
-
- // HACK HACK HACK: This is an *evil* trick, beware!
- // We do this to fix bug #1037052. A proper solution would change all the
- // drawing code to use the pitch value specified by the virtual screen.
- // However, since a lot of the SMUSH code currently assumes the screen
- // width and pitch to be equal, this will require lots of changes. So
- // we resort to this hackish solution for now.
- _origPitch = _vm->virtscr[0].pitch;
- _origNumStrips = _vm->gdi._numStrips;
- _vm->virtscr[0].pitch = _vm->virtscr[0].w;
- _vm->gdi._numStrips = _vm->virtscr[0].w / 8;
-
- _smixer = new SmushMixer(_vm->_mixer);
- Common::g_timer->installTimerProc(&timerCallback, 1000000 / _speed, this);
-
- _initDone = true;
-}
-
-void SmushPlayer::release() {
- if (!_initDone)
- return;
-
- _vm->_timer->removeTimerProc(&timerCallback);
-
- _vm->_smushVideoShouldFinish = true;
-
- for (int i = 0; i < 5; i++) {
- delete _sf[i];
- _sf[i] = NULL;
- }
-
- delete _strings;
- _strings = NULL;
-
- if (_smixer)
- _smixer->stop();
-
- delete _smixer;
- _smixer = NULL;
-
- delete _base;
- _base = NULL;
-
- free(_specialBuffer);
- _specialBuffer = NULL;
-
- free(_frameBuffer);
- _frameBuffer = NULL;
-
- _vm->_mixer->stopHandle(_compressedFileSoundHandle);
-
- _vm->_mixer->stopHandle(_IACTchannel);
- _IACTstream = 0;
-
- _vm->_fullRedraw = true;
-
- // WORKAROUND bug #1035739: This is hack to workaround some ugly palette
- // issues, see the mentioned bug report for details.
- _vm->_doEffect = false;
-
-
- // HACK HACK HACK: This is an *evil* trick, beware! See above for
- // some explanation.
- _vm->virtscr[0].pitch = _origPitch;
- _vm->gdi._numStrips = _origNumStrips;
-
-
- _initDone = false;
-}
-
-void SmushPlayer::checkBlock(const Chunk &b, Chunk::type type_expected, uint32 min_size) {
- if (type_expected != b.getType()) {
- error("Chunk type is different from expected : %x != %x", b.getType(), type_expected);
- }
- if (min_size > b.getSize()) {
- error("Chunk size is inferior than minimum required size : %d < %d", b.getSize(), min_size);
- }
-}
-
-void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frames, int32 flags, int32 vol, int32 pan, Chunk &b, int32 size) {
- debugC(DEBUG_SMUSH, "SmushPlayer::handleSoundBuffer(%d, %d)", track_id, index);
-// if ((flags & 128) == 128) {
-// return;
-// }
-// if ((flags & 64) == 64) {
-// return;
-// }
- SmushChannel *c = _smixer->findChannel(track_id);
- if (c == NULL) {
- c = new SaudChannel(track_id, _soundFrequency);
- _smixer->addChannel(c);
- }
-
- if (_middleAudio || (index == 0)) {
- c->setParameters(max_frames, flags, vol, pan, index);
- } else {
- c->checkParameters(index, max_frames, flags, vol, pan);
- }
- _middleAudio = false;
- c->appendData(b, size);
-}
-
-void SmushPlayer::handleSoundFrame(Chunk &b) {
- checkBlock(b, TYPE_PSAD);
- debugC(DEBUG_SMUSH, "SmushPlayer::handleSoundFrame()");
-
- int32 track_id = b.getWord();
- int32 index = b.getWord();
- int32 max_frames = b.getWord();
- int32 flags = b.getWord();
- int32 vol = b.getByte();
- int32 pan = b.getChar();
- if (index == 0) {
- debugC(DEBUG_SMUSH, "track_id:%d, max_frames:%d, flags:%d, vol:%d, pan:%d", track_id, max_frames, flags, vol, pan);
- }
- int32 size = b.getSize() - 10;
- handleSoundBuffer(track_id, index, max_frames, flags, vol, pan, b, size);
-}
-
-void SmushPlayer::handleSkip(Chunk &b) {
- checkBlock(b, TYPE_SKIP, 4);
- int32 code = b.getDword();
- debugC(DEBUG_SMUSH, "SmushPlayer::handleSkip(%d)", code);
- if (code >= 0 && code < 37)
- _skipNext = _skips[code];
- else
- _skipNext = true;
-}
-
-void SmushPlayer::handleStore(Chunk &b) {
- debugC(DEBUG_SMUSH, "SmushPlayer::handleStore()");
- checkBlock(b, TYPE_STOR, 4);
- _storeFrame = true;
-}
-
-void SmushPlayer::handleFetch(Chunk &b) {
- debugC(DEBUG_SMUSH, "SmushPlayer::handleFetch()");
- checkBlock(b, TYPE_FTCH, 6);
-
- if (_frameBuffer != NULL) {
- memcpy(_dst, _frameBuffer, _width * _height);
- }
-}
-
-void SmushPlayer::handleIACT(Chunk &b) {
- checkBlock(b, TYPE_IACT, 8);
- debugC(DEBUG_SMUSH, "SmushPlayer::handleImuseAction()");
-
- /* int code = */ b.getWord();
- int flags = b.getWord();
- int unknown = b.getShort();
- int track_flags = b.getWord();
-
- assert(flags == 46 && unknown == 0);
- int track_id = b.getWord();
- int index = b.getWord();
- int nbframes = b.getWord();
- int32 size = b.getDword();
- int32 bsize = b.getSize() - 18;
-
- if (_vm->_gameId != GID_CMI) {
- int32 track = track_id;
- if (track_flags == 1) {
- track = track_id + 100;
- } else if (track_flags == 2) {
- track = track_id + 200;
- } else if (track_flags == 3) {
- track = track_id + 300;
- } else if ((track_flags >= 100) && (track_flags <= 163)) {
- track = track_id + 400;
- } else if ((track_flags >= 200) && (track_flags <= 263)) {
- track = track_id + 500;
- } else if ((track_flags >= 300) && (track_flags <= 363)) {
- track = track_id + 600;
- } else {
- error("ImuseChannel::handleIACT(): bad track_flags: %d", track_flags);
- }
- debugC(DEBUG_SMUSH, "SmushPlayer::handleIACT(): %d, %d, %d", track, index, track_flags);
-
- SmushChannel *c = _smixer->findChannel(track);
- if (c == 0) {
- c = new ImuseChannel(track, _soundFrequency);
- _smixer->addChannel(c);
- }
- if (index == 0)
- c->setParameters(nbframes, size, track_flags, unknown, 0);
- else
- c->checkParameters(index, nbframes, size, track_flags, unknown);
- c->appendData(b, bsize);
- } else {
- byte output_data[4096];
- byte *src = (byte *)malloc(bsize);
- b.read(src, bsize);
- byte *d_src = src;
- byte value;
-
- while (bsize > 0) {
- if (_IACTpos >= 2) {
- int32 len = READ_BE_UINT16(_IACToutput) + 2;
- len -= _IACTpos;
- if (len > bsize) {
- memcpy(_IACToutput + _IACTpos, d_src, bsize);
- _IACTpos += bsize;
- bsize = 0;
- } else {
- memcpy(_IACToutput + _IACTpos, d_src, len);
- byte *dst = output_data;
- byte *d_src2 = _IACToutput;
- d_src2 += 2;
- int32 count = 1024;
- byte variable1 = *d_src2++;
- byte variable2 = variable1 / 16;
- variable1 &= 0x0f;
- do {
- value = *(d_src2++);
- if (value == 0x80) {
- *dst++ = *d_src2++;
- *dst++ = *d_src2++;
- } else {
- int16 val = (int8)value << variable2;
- *dst++ = val >> 8;
- *dst++ = (byte)(val);
- }
- value = *(d_src2++);
- if (value == 0x80) {
- *dst++ = *d_src2++;
- *dst++ = *d_src2++;
- } else {
- int16 val = (int8)value << variable1;
- *dst++ = val >> 8;
- *dst++ = (byte)(val);
- }
- } while (--count);
-
- if (!_IACTstream) {
- _IACTstream = makeAppendableAudioStream(22050, Audio::Mixer::FLAG_STEREO | Audio::Mixer::FLAG_16BITS, 400000);
- _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_IACTchannel, _IACTstream);
- }
- _IACTstream->append(output_data, 0x1000);
-
- bsize -= len;
- d_src += len;
- _IACTpos = 0;
- }
- } else {
- if (bsize > 1 && _IACTpos == 0) {
- *(_IACToutput + 0) = *d_src++;
- _IACTpos = 1;
- bsize--;
- }
- *(_IACToutput + _IACTpos) = *d_src++;
- _IACTpos++;
- bsize--;
- }
- }
-
- free(src);
- }
-}
-
-void SmushPlayer::handleTextResource(Chunk &b) {
- int pos_x = b.getShort();
- int pos_y = b.getShort();
- int flags = b.getShort();
- int left = b.getShort();
- int top = b.getShort();
- int right = b.getShort();
- /*int32 height =*/ b.getShort();
- /*int32 unk2 =*/ b.getWord();
-
- const char *str;
- char *string = NULL, *string2 = NULL;
- if (b.getType() == TYPE_TEXT) {
- string = (char *)malloc(b.getSize() - 16);
- str = string;
- b.read(string, b.getSize() - 16);
- } else {
- int string_id = b.getWord();
- if (!_strings)
- return;
- str = _strings->get(string_id);
- }
-
- // if subtitles disabled and bit 3 is set, then do not draw
- if ((!_subtitles) && ((flags & 8) == 8))
- return;
-
- SmushFont *sf = _sf[0];
- int color = 15;
- while (*str == '/') {
- str++; // For Full Throttle text resources
- }
-
- byte transBuf[512];
- if (_vm->_gameId == GID_CMI) {
- _vm->translateText((const byte *)str - 1, transBuf);
- while (*str++ != '/')
- ;
- string2 = (char *)transBuf;
-
- // If string2 contains formatting information there probably
- // wasn't any translation for it in the language.tab file. In
- // that case, pretend there is no string2.
- if (string2[0] == '^')
- string2[0] = 0;
- }
-
- while (str[0] == '^') {
- switch (str[1]) {
- case 'f':
- {
- int id = str[3] - '0';
- str += 4;
- sf = _sf[id];
- }
- break;
- case 'c':
- {
- color = str[4] - '0' + 10 *(str[3] - '0');
- str += 5;
- }
- break;
- default:
- error("invalid escape code in text string");
- }
- }
-
- // HACK. This is to prevent bug #1310846. In updated Win95 dig
- // there is such line:
- //
- // ^f01^c001LEAD TESTER
- // Chris Purvis
- // ^f01
- // ^f01^c001WINDOWS COMPATIBILITY
- // Chip Hinnenberg
- // ^f01^c001WINDOWS TESTING
- // Jim Davison
- // Lynn Selk
- //
- // i.e. formatting exists not in the first line only
- // We just strip that off and assume that neither font
- // nor font color was altered. Proper fix would be to feed
- // drawString() with each line sequentally
- char *string3 = NULL, *sptr2;
- const char *sptr;
-
- if (strchr(str, '^')) {
- string3 = (char *)malloc(strlen(str) + 1);
-
- for (sptr = str, sptr2 = string3; *sptr;) {
- if (*sptr == '^') {
- switch (sptr[1]) {
- case 'f':
- sptr += 4;
- break;
- case 'c':
- sptr += 5;
- break;
- default:
- error("invalid escape code in text string");
- }
- } else {
- *sptr2++ = *sptr++;
- }
- }
- *sptr2++ = *sptr++; // copy zero character
- str = string3;
- }
-
- assert(sf != NULL);
- sf->setColor(color);
-
- if (_vm->_gameId == GID_CMI && string2[0] != 0) {
- str = string2;
- }
-
- // flags:
- // bit 0 - center 1
- // bit 1 - not used 2
- // bit 2 - ??? 4
- // bit 3 - wrap around 8
- switch (flags & 9) {
- case 0:
- sf->drawString(str, _dst, _width, _height, pos_x, pos_y, false);
- break;
- case 1:
- sf->drawString(str, _dst, _width, _height, pos_x, MAX(pos_y, top), true);
- break;
- case 8:
- // FIXME: Is 'right' the maximum line width here, just
- // as it is in the next case? It's used several times
- // in The Dig's intro, where 'left' and 'right' are
- // always 0 and 321 respectively, and apparently we
- // handle that correctly.
- sf->drawStringWrap(str, _dst, _width, _height, pos_x, MAX(pos_y, top), left, right, false);
- break;
- case 9:
- // In this case, the 'right' parameter is actually the
- // maximum line width. This explains why it's sometimes
- // smaller than 'left'.
- //
- // Note that in The Dig's "Spacetime Six" movie it's
- // 621. I have no idea what that means.
- sf->drawStringWrap(str, _dst, _width, _height, pos_x, MAX(pos_y, top), left, MIN(left + right, _width), true);
- break;
- default:
- error("SmushPlayer::handleTextResource. Not handled flags: %d", flags);
- }
-
- if (string != NULL) {
- free (string);
- }
- if (string3 != NULL) {
- free (string3);
- }
-}
-
-const char *SmushPlayer::getString(int id) {
- return _strings->get(id);
-}
-
-bool SmushPlayer::readString(const char *file) {
- const char *i = strrchr(file, '.');
- if (i == NULL) {
- error("invalid filename : %s", file);
- }
- char fname[260];
- memcpy(fname, file, i - file);
- strcpy(fname + (i - file), ".trs");
- if ((_strings = getStrings(_vm, fname, false)) != 0) {
- return true;
- }
-
- if ((_strings = getStrings(_vm, "digtxt.trs", true)) != 0) {
- return true;
- }
- return false;
-}
-
-void SmushPlayer::readPalette(byte *out, Chunk &in) {
- in.read(out, 0x300);
-}
-
-static byte delta_color(byte org_color, int16 delta_color) {
- int t = (org_color * 129 + delta_color) / 128;
- if (t > 255)
- t = 255;
- if (t < 0)
- t = 0;
- return (byte)t;
-}
-
-void SmushPlayer::handleDeltaPalette(Chunk &b) {
- checkBlock(b, TYPE_XPAL);
- debugC(DEBUG_SMUSH, "SmushPlayer::handleDeltaPalette()");
-
- if (b.getSize() == 0x300 * 3 + 4) {
-
- b.getWord();
- b.getWord();
-
- for (int i = 0; i < 0x300; i++) {
- _deltaPal[i] = b.getWord();
- }
- readPalette(_pal, b);
- setDirtyColors(0, 255);
- } else if (b.getSize() == 6) {
-
- b.getWord();
- b.getWord();
- b.getWord();
-
- for (int i = 0; i < 0x300; i++) {
- _pal[i] = delta_color(_pal[i], _deltaPal[i]);
- }
- setDirtyColors(0, 255);
- } else {
- error("SmushPlayer::handleDeltaPalette() Wrong size for DeltaPalette");
- }
-}
-
-void SmushPlayer::handleNewPalette(Chunk &b) {
- checkBlock(b, TYPE_NPAL, 0x300);
- debugC(DEBUG_SMUSH, "SmushPlayer::handleNewPalette()");
-
- if (_skipPalette)
- return;
-
- readPalette(_pal, b);
- setDirtyColors(0, 255);
-}
-
-void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
-
-#ifdef USE_ZLIB
-void SmushPlayer::handleZlibFrameObject(Chunk &b) {
- if (_skipNext) {
- _skipNext = false;
- return;
- }
-
- int32 chunkSize = b.getSize();
- byte *chunkBuffer = (byte *)malloc(chunkSize);
- assert(chunkBuffer);
- b.read(chunkBuffer, chunkSize);
-
- unsigned long decompressedSize = READ_BE_UINT32(chunkBuffer);
- byte *fobjBuffer = (byte *)malloc(decompressedSize);
- int result = uncompress(fobjBuffer, &decompressedSize, chunkBuffer + 4, chunkSize - 4);
- if (result != Z_OK)
- error("SmushPlayer::handleZlibFrameObject() Zlib uncompress error");
- free(chunkBuffer);
-
- byte *ptr = fobjBuffer;
- int codec = READ_LE_UINT16(ptr); ptr += 2;
- int left = READ_LE_UINT16(ptr); ptr += 2;
- int top = READ_LE_UINT16(ptr); ptr += 2;
- int width = READ_LE_UINT16(ptr); ptr += 2;
- int height = READ_LE_UINT16(ptr); ptr += 2;
-
- if ((height == 242) && (width == 384)) {
- if (_specialBuffer == 0)
- _specialBuffer = (byte *)malloc(242 * 384);
- _dst = _specialBuffer;
- } else if ((height > _vm->_screenHeight) || (width > _vm->_screenWidth))
- return;
- // FT Insane uses smaller frames to draw overlays with moving objects
- // Other .san files do have them as well but their purpose in unknown
- // and often it causes memory overdraw. So just skip those frames
- else if (!_insanity && ((height != _vm->_screenHeight) || (width != _vm->_screenWidth)))
- return;
-
- if (!_alreadyInit) {
- _codec37.init(width, height);
- _codec47.init(width, height);
- _alreadyInit = true;
- }
-
- if ((height == 242) && (width == 384)) {
- _width = width;
- _height = height;
- } else {
- _width = _vm->_screenWidth;
- _height = _vm->_screenHeight;
- }
-
- switch (codec) {
- case 1:
- case 3:
- smush_decode_codec1(_dst, fobjBuffer + 14, left, top, width, height, _vm->_screenWidth);
- break;
- case 37:
- _codec37.decode(_dst, fobjBuffer + 14);
- break;
- case 47:
- _codec47.decode(_dst, fobjBuffer + 14);
- break;
- default:
- error("Invalid codec for frame object : %d", (int)codec);
- }
-
- if (_storeFrame) {
- if (_frameBuffer == NULL) {
- _frameBuffer = (byte *)malloc(_width * _height);
- }
- memcpy(_frameBuffer, _dst, _width * _height);
- _storeFrame = false;
- }
-
- free(fobjBuffer);
-}
-#endif
-
-void SmushPlayer::handleFrameObject(Chunk &b) {
- checkBlock(b, TYPE_FOBJ, 14);
- if (_skipNext) {
- _skipNext = false;
- return;
- }
-
- int codec = b.getWord();
- int left = b.getWord();
- int top = b.getWord();
- int width = b.getWord();
- int height = b.getWord();
-
- if ((height == 242) && (width == 384)) {
- if (_specialBuffer == 0)
- _specialBuffer = (byte *)malloc(242 * 384);
- _dst = _specialBuffer;
- } else if ((height > _vm->_screenHeight) || (width > _vm->_screenWidth))
- return;
- // FT Insane uses smaller frames to draw overlays with moving objects
- // Other .san files do have them as well but their purpose in unknown
- // and often it causes memory overdraw. So just skip those frames
- else if (!_insanity && ((height != _vm->_screenHeight) || (width != _vm->_screenWidth)))
- return;
-
- if (!_alreadyInit) {
- _codec37.init(width, height);
- _codec47.init(width, height);
- _alreadyInit = true;
- }
-
- if ((height == 242) && (width == 384)) {
- _width = width;
- _height = height;
- } else {
- _width = _vm->_screenWidth;
- _height = _vm->_screenHeight;
- }
-
- b.getWord();
- b.getWord();
-
- int32 chunk_size = b.getSize() - 14;
- byte *chunk_buffer = (byte *)malloc(chunk_size);
- assert(chunk_buffer);
- b.read(chunk_buffer, chunk_size);
-
- switch (codec) {
- case 1:
- case 3:
- smush_decode_codec1(_dst, chunk_buffer, left, top, width, height, _vm->_screenWidth);
- break;
- case 37:
- _codec37.decode(_dst, chunk_buffer);
- break;
- case 47:
- _codec47.decode(_dst, chunk_buffer);
- break;
- default:
- error("Invalid codec for frame object : %d", (int)codec);
- }
-
- if (_storeFrame) {
- if (_frameBuffer == NULL) {
- _frameBuffer = (byte *)malloc(_width * _height);
- }
- memcpy(_frameBuffer, _dst, _width * _height);
- _storeFrame = false;
- }
-
- free(chunk_buffer);
-}
-
-void SmushPlayer::handleFrame(Chunk &b) {
- checkBlock(b, TYPE_FRME);
- debugC(DEBUG_SMUSH, "SmushPlayer::handleFrame(%d)", _frame);
- _skipNext = false;
-
- uint32 start_time, end_time;
- start_time = _vm->_system->getMillis();
-
- if (_insanity) {
- _vm->_insane->procPreRendering();
- }
-
- while (!b.eof()) {
- Chunk *sub = b.subBlock();
- switch (sub->getType()) {
- case TYPE_NPAL:
- handleNewPalette(*sub);
- break;
- case TYPE_FOBJ:
- handleFrameObject(*sub);
- break;
-#ifdef USE_ZLIB
- case TYPE_ZFOB:
- handleZlibFrameObject(*sub);
- break;
-#endif
- case TYPE_PSAD:
- if (!_compressedFileMode)
- handleSoundFrame(*sub);
- break;
- case TYPE_TRES:
- handleTextResource(*sub);
- break;
- case TYPE_XPAL:
- handleDeltaPalette(*sub);
- break;
- case TYPE_IACT:
- // FIXME: check parameters
- if (_insanity)
- _vm->_insane->procIACT(_dst, 0, 0, 0, *sub, 0, 0);
- else {
- if (!_compressedFileMode)
- handleIACT(*sub);
- }
- break;
- case TYPE_STOR:
- handleStore(*sub);
- break;
- case TYPE_FTCH:
- handleFetch(*sub);
- break;
- case TYPE_SKIP:
- if (_insanity)
- _vm->_insane->procSKIP(*sub);
- else
- handleSkip(*sub);
- break;
- case TYPE_TEXT:
- handleTextResource(*sub);
- break;
- default:
- error("Unknown frame subChunk found : %s, %d", Chunk::ChunkString(sub->getType()), sub->getSize());
- }
-
- b.reseek();
- if (sub->getSize() & 1)
- b.seek(1);
-
- delete sub;
- }
-
- if (_insanity) {
- _vm->_insane->procPostRendering(_dst, 0, 0, 0, _frame, _nbframes-1);
- }
-
- end_time = _vm->_system->getMillis();
-
- if (_width != 0 && _height != 0) {
-#ifdef _WIN32_WCE
- if (!_inTimer || _inTimerCount == _inTimerCountRedraw) {
- updateScreen();
- _inTimerCount = 0;
- }
-#else
- updateScreen();
-#endif
- }
- _smixer->handleFrame();
-
- debugC(DEBUG_SMUSH, "Smush stats: FRME( %03d ), Limit(%d)", end_time - start_time, _speed);
-
- _frame++;
-}
-
-void SmushPlayer::handleAnimHeader(Chunk &b) {
- checkBlock(b, TYPE_AHDR, 0x300 + 6);
- debugC(DEBUG_SMUSH, "SmushPlayer::handleAnimHeader()");
-
- _version = b.getWord();
- _nbframes = b.getWord();
- b.getWord();
-
- if (_skipPalette)
- return;
-
- readPalette(_pal, b);
- setDirtyColors(0, 255);
-}
-
-void SmushPlayer::setupAnim(const char *file) {
- int i;
- char file_font[11];
-
- if (_insanity) {
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC)))
- readString("mineroad.trs");
- } else
- readString(file);
-
- if (_vm->_gameId == GID_FT) {
- if (!((_vm->_features & GF_DEMO) && (_vm->_platform == Common::kPlatformPC))) {
- _sf[0] = new SmushFont(_vm, true, false);
- _sf[1] = new SmushFont(_vm, true, false);
- _sf[2] = new SmushFont(_vm, true, false);
- _sf[3] = new SmushFont(_vm, true, false);
- _sf[0]->loadFont("scummfnt.nut");
- _sf[1]->loadFont("techfnt.nut");
- _sf[2]->loadFont("titlfnt.nut");
- _sf[3]->loadFont("specfnt.nut");
- }
- } else if (_vm->_gameId == GID_DIG) {
- if (!(_vm->_features & GF_DEMO)) {
- for (i = 0; i < 4; i++) {
- sprintf(file_font, "font%d.nut", i);
- _sf[i] = new SmushFont(_vm, i != 0, false);
- _sf[i]->loadFont(file_font);
- }
- }
- } else if (_vm->_gameId == GID_CMI) {
- for (i = 0; i < 5; i++) {
- if ((_vm->_features & GF_DEMO) && (i == 4))
- break;
- sprintf(file_font, "font%d.nut", i);
- _sf[i] = new SmushFont(_vm, false, true);
- _sf[i]->loadFont(file_font);
- }
- } else {
- error("SmushPlayer::setupAnim() Unknown font setup for game");
- }
-}
-
-void SmushPlayer::parseNextFrame() {
- Common::StackLock lock(_mutex);
-
- Chunk *sub;
-
- if (_vm->_smushPaused)
- return;
-
- if (_seekPos >= 0) {
- if (_smixer)
- _smixer->stop();
-
- if (_seekFile.size() > 0) {
- delete _base;
- _base = new FileChunk(_seekFile);
-
- if (_seekPos > 0) {
- assert(_seekPos > 8);
- // In this case we need to get palette and number of frames
- sub = _base->subBlock();
- checkBlock(*sub, TYPE_AHDR);
- handleAnimHeader(*sub);
- delete sub;
-
- _middleAudio = true;
- _seekPos -= 8;
- } else {
- // We need this in Full Throttle when entering/leaving
- // the old mine road.
- tryCmpFile(_seekFile.c_str());
- }
- _skipPalette = false;
- } else {
- _skipPalette = true;
- }
-
- _base->seek(_seekPos, FileChunk::seek_start);
- _frame = _seekFrame;
-
- _seekPos = -1;
- }
-
- assert(_base);
- if (_base->eof()) {
- _vm->_smushVideoShouldFinish = true;
- return;
- }
-
- sub = _base->subBlock();
-
- switch (sub->getType()) {
- case TYPE_AHDR: // FT INSANE may seek file to the beginning
- handleAnimHeader(*sub);
- break;
- case TYPE_FRME:
- handleFrame(*sub);
- break;
- default:
- error("Unknown Chunk found at %x: %x, %d", _base->tell(), sub->getType(), sub->getSize());
- }
- delete sub;
-
- _base->reseek();
-
- if (_insanity)
- _vm->_sound->processSound();
-
- _vm->_imuseDigital->flushTracks();
-}
-
-void SmushPlayer::setPalette(const byte *palette) {
- memcpy(_pal, palette, 0x300);
- setDirtyColors(0, 255);
-}
-
-void SmushPlayer::setPaletteValue(int n, byte r, byte g, byte b) {
- _pal[n * 3 + 0] = r;
- _pal[n * 3 + 1] = g;
- _pal[n * 3 + 2] = b;
- setDirtyColors(n, n);
-}
-
-void SmushPlayer::setDirtyColors(int min, int max) {
- if (_palDirtyMin > min)
- _palDirtyMin = min;
- if (_palDirtyMax < max)
- _palDirtyMax = max;
-}
-
-void SmushPlayer::warpMouse(int x, int y, int buttons) {
- _warpNeeded = true;
- _warpX = x;
- _warpY = y;
- _warpButtons = buttons;
-}
-
-void SmushPlayer::updateScreen() {
-#ifdef DUMP_SMUSH_FRAMES
- char fileName[100];
- // change path below for dump png files
- sprintf(fileName, "/path/to/somethere/%s%04d.png", _vm->getBaseName(), _frame);
- FILE *file = fopen(fileName, "wb");
- if (file == NULL)
- error("can't open file for writing png");
-
- png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
- if (png_ptr == NULL) {
- fclose(file);
- error("can't write png header");
- }
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- fclose(file);
- error("can't create png info struct");
- }
- if (setjmp(png_ptr->jmpbuf)) {
- fclose(file);
- error("png jmpbuf error");
- }
-
- png_init_io(png_ptr, file);
-
- png_set_IHDR(png_ptr, info_ptr, _width, _height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- png_colorp palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof (png_color));
- for (int i = 0; i != 256; ++i) {
- (palette + i)->red = _pal[i * 3 + 0];
- (palette + i)->green = _pal[i * 3 + 1];
- (palette + i)->blue = _pal[i * 3 + 2];
- }
-
- png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
-
- png_write_info(png_ptr, info_ptr);
- png_set_flush(png_ptr, 10);
-
- png_bytep row_pointers[480];
- for (int y = 0 ; y < _height ; y++)
- row_pointers[y] = (png_byte *) (_dst + y * _width);
- png_write_image(png_ptr, row_pointers);
- png_write_end(png_ptr, info_ptr);
- png_free(png_ptr, palette);
-
- fclose(file);
- png_destroy_write_struct(&png_ptr, &info_ptr);
-#endif
-
- uint32 end_time, start_time = _vm->_system->getMillis();
- _updateNeeded = true;
- end_time = _vm->_system->getMillis();
- debugC(DEBUG_SMUSH, "Smush stats: updateScreen( %03d )", end_time - start_time);
-}
-
-void SmushPlayer::insanity(bool flag) {
- _insanity = flag;
-}
-
-void SmushPlayer::seekSan(const char *file, int32 pos, int32 contFrame) {
- Common::StackLock lock(_mutex);
-
- _seekFile = file ? file : "";
- _seekPos = pos;
- _seekFrame = contFrame;
-}
-
-void SmushPlayer::tryCmpFile(const char *filename) {
- if (_compressedFile.isOpen()) {
- _vm->_mixer->stopHandle(_compressedFileSoundHandle);
- _compressedFile.close();
- }
- _compressedFileMode = false;
- const char *i = strrchr(filename, '.');
- if (i == NULL) {
- error("invalid filename : %s", filename);
- }
-#if defined(USE_MAD) || defined(USE_VORBIS)
- char fname[260];
-#endif
-#ifdef USE_MAD
- memcpy(fname, filename, i - filename);
- strcpy(fname + (i - filename), ".mp3");
- _compressedFile.open(fname);
- if (_compressedFile.isOpen()) {
- int size = _compressedFile.size();
- _compressedFileMode = true;
- _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_compressedFileSoundHandle, makeMP3Stream(&_compressedFile, size));
- return;
- }
-#endif
-#ifdef USE_VORBIS
- memcpy(fname, filename, i - filename);
- strcpy(fname + (i - filename), ".ogg");
- _compressedFile.open(fname);
- if (_compressedFile.isOpen()) {
- int size = _compressedFile.size();
- _compressedFileMode = true;
- _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_compressedFileSoundHandle, makeVorbisStream(&_compressedFile, size));
- return;
- }
-#endif
-}
-
-void SmushPlayer::play(const char *filename, int32 offset, int32 startFrame) {
-
- // Verify the specified file exists
- ScummFile f;
- _vm->openFile(f, filename);
- if (!f.isOpen()) {
- warning("SmushPlayer::play() File not found %s", filename);
- return;
- }
- f.close();
-
- _updateNeeded = false;
- _warpNeeded = false;
- _palDirtyMin = 256;
- _palDirtyMax = -1;
-
- // Hide mouse
- bool oldMouseState = _vm->_system->showMouse(false);
-
- // Load the video
- _seekFile = filename;
- _seekPos = offset;
- _seekFrame = startFrame;
- _base = 0;
-
- setupAnim(filename);
- init();
-
- for (;;) {
- if (_warpNeeded) {
- _vm->_system->warpMouse(_warpX, _warpY);
- _warpNeeded = false;
- }
- _vm->parseEvents();
- _vm->processKbd(true);
- if (_palDirtyMax >= _palDirtyMin) {
- byte palette_colors[1024];
- byte *p = palette_colors;
-
- for (int i = _palDirtyMin; i <= _palDirtyMax; i++) {
- byte *data = _pal + i * 3;
-
- *p++ = data[0];
- *p++ = data[1];
- *p++ = data[2];
- *p++ = 0;
- }
-
- _vm->_system->setPalette(palette_colors, _palDirtyMin, _palDirtyMax - _palDirtyMin + 1);
-
- _palDirtyMax = -1;
- _palDirtyMin = 256;
- }
- if (_updateNeeded) {
- uint32 end_time, start_time;
-
- start_time = _vm->_system->getMillis();
- _vm->_system->copyRectToScreen(_dst, _width, 0, 0, _width, _height);
- _vm->_system->updateScreen();
- _updateNeeded = false;
-#ifdef _WIN32_WCE
- _inTimer = false;
- _inTimerCount = 0;
-#endif
-
- end_time = _vm->_system->getMillis();
-
- debugC(DEBUG_SMUSH, "Smush stats: BackendUpdateScreen( %03d )", end_time - start_time);
-
- }
- if (_vm->_smushVideoShouldFinish || _vm->_quit || _vm->_saveLoadFlag)
- break;
- _vm->_system->delayMillis(10);
- }
-
- release();
-
- // Reset mouse state
- _vm->_system->showMouse(oldMouseState);
-}
-
-} // End of namespace Scumm
-
diff --git a/scumm/smush/smush_player.h b/scumm/smush/smush_player.h
deleted file mode 100644
index f697057d89..0000000000
--- a/scumm/smush/smush_player.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(SMUSH_PLAYER_H) && !defined(DISABLE_SCUMM_7_8)
-#define SMUSH_PLAYER_H
-
-#include "common/util.h"
-#include "scumm/smush/chunk.h"
-#include "scumm/smush/codec37.h"
-#include "scumm/smush/codec47.h"
-#include "scumm/sound.h"
-
-namespace Scumm {
-
-class ScummEngine_v6;
-class SmushFont;
-class SmushMixer;
-class StringResource;
-
-class SmushPlayer {
- friend class Insane;
-private:
- ScummEngine_v6 *_vm;
- int _version;
- int32 _nbframes;
- SmushMixer *_smixer;
- int16 _deltaPal[0x300];
- byte _pal[0x300];
- StringResource *_strings;
- Codec37Decoder _codec37;
- Codec47Decoder _codec47;
- FileChunk *_base;
- byte *_frameBuffer;
- byte *_specialBuffer;
-
- Common::String _seekFile;
- int32 _seekPos;
- int32 _seekFrame;
-
- bool _skipNext;
- bool _subtitles;
- bool _skips[37];
- int32 _frame;
-
- Audio::SoundHandle _IACTchannel;
- AppendableAudioStream *_IACTstream;
-
- Audio::SoundHandle _compressedFileSoundHandle;
- bool _compressedFileMode;
- Common::File _compressedFile;
- byte _IACToutput[4096];
- int32 _IACTpos;
- bool _storeFrame;
- int _soundFrequency;
- bool _alreadyInit;
- bool _initDone;
- int _speed;
- bool _outputSound;
-
- byte *_dst;
- bool _updateNeeded;
- bool _warpNeeded;
- int _palDirtyMin, _palDirtyMax;
- int _warpX, _warpY;
- int _warpButtons;
- bool _insanity;
- bool _middleAudio;
- bool _skipPalette;
-#ifdef _WIN32_WCE
- bool _inTimer;
- int16 _inTimerCount;
- int16 _inTimerCountRedraw;
-#endif
-
- Common::Mutex _mutex;
-
-public:
- SmushPlayer(ScummEngine_v6 *scumm, int speed);
- ~SmushPlayer();
-
- void play(const char *filename, int32 offset = 0, int32 startFrame = 0);
- void warpMouse(int x, int y, int buttons);
-
-protected:
- SmushFont *_sf[5];
- int _width, _height;
-
- int _origPitch, _origNumStrips;
-
- void insanity(bool);
- void setPalette(const byte *palette);
- void setPaletteValue(int n, byte r, byte g, byte b);
- void setDirtyColors(int min, int max);
- void seekSan(const char *file, int32 pos, int32 contFrame);
- const char *getString(int id);
-
-private:
- void parseNextFrame();
- void init();
- void release();
- void setupAnim(const char *file);
- void updateScreen();
- void tryCmpFile(const char *filename);
-
- bool readString(const char *file);
- void checkBlock(const Chunk &, Chunk::type, uint32 = 0);
- void handleAnimHeader(Chunk &);
- void handleFrame(Chunk &);
- void handleNewPalette(Chunk &);
-#ifdef USE_ZLIB
- void handleZlibFrameObject(Chunk &b);
-#endif
- void handleFrameObject(Chunk &);
- void handleSoundBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
- void handleSoundFrame(Chunk &);
- void handleSkip(Chunk &);
- void handleStore(Chunk &);
- void handleFetch(Chunk &);
- void handleIACT(Chunk &);
- void handleTextResource(Chunk &);
- void handleDeltaPalette(Chunk &);
- void readPalette(byte *, Chunk &);
-
- static void timerCallback(void *ptr);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
deleted file mode 100644
index 26f0c712c8..0000000000
--- a/scumm/sound.cpp
+++ /dev/null
@@ -1,2364 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/imuse.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-#include "common/config-manager.h"
-#include "common/timer.h"
-#include "common/util.h"
-
-#include "sound/adpcm.h"
-#include "sound/audiocd.h"
-#include "sound/flac.h"
-#include "sound/mididrv.h"
-#include "sound/mixer.h"
-#include "sound/mp3.h"
-#include "sound/voc.h"
-#include "sound/vorbis.h"
-#include "sound/wave.h"
-
-
-
-namespace Scumm {
-
-struct MP3OffsetTable { /* Compressed Sound (.SO3) */
- int org_offset;
- int new_offset;
- int num_tags;
- int compressed_size;
-};
-
-
-Sound::Sound(ScummEngine *parent)
- :
- _vm(parent),
- _soundQuePos(0),
- _soundQue2Pos(0),
- _sfxFile(0),
- _offsetTable(0),
- _numSoundEffects(0),
- _soundMode(kVOCMode),
- _talk_sound_a1(0),
- _talk_sound_a2(0),
- _talk_sound_b1(0),
- _talk_sound_b2(0),
- _talk_sound_mode(0),
- _talk_sound_channel(0),
- _mouthSyncMode(false),
- _endOfMouthSync(false),
- _curSoundPos(0),
- _overrideFreq(0),
- _currentCDSound(0),
- _currentMusic(0),
- _soundsPaused(false),
- _sfxMode(0),
- _heMusic(0),
- _heMusicTracks(0) {
-
- memset(_heChannel, 0, sizeof(_heChannel));
- memset(_soundQue, 0, sizeof(_soundQue));
- memset(_soundQue2, 0, sizeof(_soundQue2));
- memset(_mouthSyncTimes, 0, sizeof(_mouthSyncTimes));
-}
-
-Sound::~Sound() {
- stopCDTimer();
- delete _sfxFile;
-
- // HE Specific
- free(_heMusic);
-}
-
-void Sound::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlags) {
- if (_vm->VAR_LAST_SOUND != 0xFF)
- _vm->VAR(_vm->VAR_LAST_SOUND) = sound;
-
- if (heFlags & 16) {
- playHESound(sound, heOffset, heChannel, heFlags);
- return;
- }
-
- // HE music resources are in separate file
- if (sound <= _vm->_numSounds)
- _vm->ensureResourceLoaded(rtSound, sound);
-
- addSoundToQueue2(sound, heOffset, heChannel, heFlags);
-}
-
-void Sound::addSoundToQueue2(int sound, int heOffset, int heChannel, int heFlags) {
- if (_vm->_heversion >= 60 && _soundQue2Pos) {
- int i = _soundQue2Pos;
- while (i--) {
- if (_soundQue2[i].sound == sound && !(heFlags & 2))
- return;
- }
- }
-
- assert(_soundQue2Pos < ARRAYSIZE(_soundQue2));
- _soundQue2[_soundQue2Pos].sound = sound;
- _soundQue2[_soundQue2Pos].offset = heOffset;
- _soundQue2[_soundQue2Pos].channel = heChannel;
- _soundQue2[_soundQue2Pos].flags = heFlags;
- _soundQue2Pos++;
-}
-
-void Sound::processSound() {
- if (_vm->_heversion >= 60) {
- processSoundQueues();
- processSfxQueues();
- } else {
- processSfxQueues();
-
- if (_vm->_features & GF_DIGI_IMUSE)
- return;
-
- processSoundQueues();
- }
-}
-
-void Sound::processSoundQueues() {
- int i = 0, num;
- int snd, heOffset, heChannel, heFlags;
- int data[16];
-
- if (_vm->_heversion >= 72) {
- for (i = 0; i <_soundQue2Pos; i++) {
- snd = _soundQue2[i].sound;
- heOffset = _soundQue2[i].offset;
- heChannel = _soundQue2[i].channel;
- heFlags = _soundQue2[i].flags;
- if (snd) {
- if (_vm->_heversion>= 60)
- playHESound(snd, heOffset, heChannel, heFlags);
- else
- playSound(snd);
- }
- }
- _soundQue2Pos = 0;
- } else {
- while (_soundQue2Pos) {
- _soundQue2Pos--;
- snd = _soundQue2[_soundQue2Pos].sound;
- heOffset = _soundQue2[_soundQue2Pos].offset;
- heChannel = _soundQue2[_soundQue2Pos].channel;
- heFlags = _soundQue2[_soundQue2Pos].flags;
- if (snd) {
- if (_vm->_heversion>= 60)
- playHESound(snd, heOffset, heChannel, heFlags);
- else
- playSound(snd);
- }
- }
- }
-
- while (i < _soundQuePos) {
- num = _soundQue[i++];
- if (i + num > _soundQuePos) {
- error("processSoundQues: invalid num value");
- break;
- }
- memset(data, 0, sizeof(data));
- if (num > 0) {
- for (int j = 0; j < num; j++)
- data[j] = _soundQue[i + j];
- i += num;
-
- debugC(DEBUG_IMUSE, "processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)",
- data[0] >> 8, data[0] & 0xFF,
- data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
-
- if (_vm->_imuse) {
- _vm->VAR(_vm->VAR_SOUNDRESULT) = (short)_vm->_imuse->doCommand (num, data);
- }
- }
- }
- _soundQuePos = 0;
-}
-
-void Sound::playSound(int soundID) {
- byte *mallocedPtr = NULL;
- byte *ptr;
- char *sound;
- int size = -1;
- int rate;
- byte flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
-
- debugC(DEBUG_SOUND, "playSound #%d (room %d)", soundID,
- _vm->getResourceRoomNr(rtSound, soundID));
-
- ptr = _vm->getResourceAddress(rtSound, soundID);
-
- if (!ptr) {
- return;
- }
-
- // Support for SFX in Monkey Island 1, Mac version
- // This is rather hackish right now, but works OK. SFX are not sounding
- // 100% correct, though, not sure right now what is causing this.
- else if (READ_UINT32(ptr) == MKID('Mac1')) {
- // Read info from the header
- size = READ_BE_UINT32(ptr+0x60);
- rate = READ_BE_UINT16(ptr+0x64);
-
- // Skip over the header (fixed size)
- ptr += 0x72;
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr, size);
- _vm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
- }
- // WORKAROUND bug # 1311447
- else if (READ_UINT32(ptr) == MKID(0x460e200d)) {
- // This sound resource occurs in the Macintosh version of Monkey Island.
- // I do now know whether it is used in any place other than the one
- // mentioned in the bug report above; in case it is, I put a check here.
- assert(soundID == 39);
-
- // The samplerate is copied from the sound resouce 39 of the PC CD/VGA
- // version of Monkey Island.
-
- // Read info from the header
- size = READ_BE_UINT32(ptr+4);
- rate = 6849;
-
- // Skip over the header (fixed size)
- ptr += 0x26;
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr, size);
- _vm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
- }
- // Support for sampled sound effects in Monkey Island 1 and 2
- else if (READ_UINT32(ptr) == MKID('SBL ')) {
- debugC(DEBUG_SOUND, "Using SBL sound effect");
-
- // SBL resources essentially contain VOC sound data.
- // There are at least two main variants: in one,
- // there are two subchunks AUhd and AUdt, in the other
- // the chunks are called WVhd and WVdt. Besides that,
- // the two variants seem pretty similiar.
-
- // The first subchunk (AUhd resp. WVhd) seems to always
- // contain three bytes (00 00 80) of unknown meaning.
- // After that, a second subchunk contains VOC data.
- // Two real examples:
- //
- // 53 42 4c 20 00 00 11 ae |SBL ....|
- // 41 55 68 64 00 00 00 03 |AUhd....|
- // 00 00 80 41 55 64 74 00 |...AUdt.|
- // 00 11 9b 01 96 11 00 a6 |........|
- // 00 7f 7f 7e 7e 7e 7e 7e |...~~~~~|
- // 7e 7f 7f 80 80 7f 7f 7f |~.......|
- // 7f 80 80 7f 7e 7d 7d 7e |....~}}~|
- // 7e 7e 7e 7e 7e 7e 7e 7f |~~~~~~~.|
- //
- // And from the non-interactive Sam & Max demo:
- //
- // 53 42 4c 20 00 01 15 6e |SBL ...n|
- // 57 56 68 64 00 00 00 03 |WVhd....|
- // 00 00 80 57 56 64 74 00 |...WVdt.|
- // 01 15 5b 01 56 15 01 a6 |..[.V...|
- // 00 80 80 80 80 80 80 80 |........|
- // 80 80 80 80 80 80 80 80 |........|
- // 80 80 80 80 80 80 80 80 |........|
- // 80 80 80 80 80 80 80 80 |........|
-
- size = READ_BE_UINT32(ptr + 4) - 27;
- ptr += 27;
-
- // Fingolfin says: after eyeballing a single SEGA
- // SBL resource, it would seem as if the content of the
- // data subchunk (AUdt) is XORed with 0x16. At least
- // then a semi-sane VOC header is revealed, with
- // a sampling rate of ~25000 Hz (does that make sense?).
- // I'll add some code to test that theory for now.
-
- // Check if the resource has already been demangled
- if ((_vm->_platform == Common::kPlatformSegaCD) && (ptr[0] != 1)) {
- for (int i = 0; i < size; i++) {
- ptr[i] ^= 0x16;
- if (ptr[i] >= 0x7F) {
- ptr[i] = 0xFE - ptr[i];
- ptr[i] ^= 0x80;
- }
- }
- }
-
- // TODO: It would be nice if we could use readVOCFromMemory() here.
- // We'd have to add the 'Creative Voice File' header for this, though,
- // or make readVOCFromMemory() less strict.
-
- VocBlockHeader &voc_block_hdr = *(VocBlockHeader *)ptr;
- assert(voc_block_hdr.blocktype == 1);
- size = voc_block_hdr.size[0] + (voc_block_hdr.size[1] << 8) + (voc_block_hdr.size[2] << 16) - 2;
- rate = getSampleRateFromVOCRate(voc_block_hdr.sr);
- assert(voc_block_hdr.pack == 0);
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + 6, size);
- _vm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
- }
- else if ((_vm->_platform == Common::kPlatformFMTowns && _vm->_version == 3) || READ_UINT32(ptr) == MKID('SOUN') || READ_UINT32(ptr) == MKID('TOWS')) {
-
- bool tows = READ_UINT32(ptr) == MKID('TOWS');
- if (_vm->_version == 3) {
- size = READ_LE_UINT32(ptr);
- } else {
- size = READ_BE_UINT32(ptr + 4) - 2;
- if (tows)
- size += 8;
- ptr += 2;
- }
-
- rate = 11025;
- int type = *(ptr + 0x0D);
- int numInstruments;
-
- if (tows)
- type = 0;
-
- switch (type) {
- case 0: // Sound effect
- numInstruments = *(ptr + 0x14);
- if (tows)
- numInstruments = 1;
- ptr += 0x16;
- size -= 0x16;
-
- while (numInstruments--) {
- int waveSize = READ_LE_UINT32(ptr + 0x0C);
- int loopStart = READ_LE_UINT32(ptr + 0x10) * 2;
- int loopEnd = READ_LE_UINT32(ptr + 0x14) - 1;
- rate = READ_LE_UINT32(ptr + 0x18) * 1000 / 0x62;
- ptr += 0x20;
- size -= 0x20;
- if (size < waveSize) {
- warning("Wrong wave size in sound #%i: %i", soundID, waveSize);
- waveSize = size;
- }
- sound = (char *)malloc(waveSize);
- for (int x = 0; x < waveSize; x++) {
- int b = *ptr++;
- if (b < 0x80)
- sound[x] = 0x7F - b;
- else
- sound[x] = b;
- }
- size -= waveSize;
-
- if (loopEnd > 0)
- flags |= Audio::Mixer::FLAG_LOOP;
-
- _vm->_mixer->playRaw(NULL, sound, waveSize, rate, flags, soundID, 255, 0, loopStart, loopEnd);
- }
- break;
- case 1:
- // Music (Euphony format)
- if (_vm->_musicEngine)
- _vm->_musicEngine->startSound(soundID);
- break;
- case 2: // CD track resource
- ptr += 0x16;
-
- if (soundID == _currentCDSound && pollCD() == 1) {
- free(mallocedPtr);
- return;
- }
-
- {
- int track = ptr[0];
- int loops = ptr[1];
- int start = (ptr[2] * 60 + ptr[3]) * 75 + ptr[4];
- int end = (ptr[5] * 60 + ptr[6]) * 75 + ptr[7];
-
- playCDTrack(track, loops == 0xff ? -1 : loops, start, end <= start ? 0 : end - start);
- }
-
- _currentCDSound = soundID;
- break;
- default:
- // All other sound types are ignored
- break;
- }
- }
- else if ((_vm->_gameId == GID_LOOM) && (_vm->_platform == Common::kPlatformMacintosh)) {
- // Mac version of Loom uses yet another sound format
- /*
- playSound #9 (room 70)
- 000000: 55 00 00 45 73 6f 00 64 01 00 00 00 00 00 00 00 |U..Eso.d........|
- 000010: 00 05 00 8e 2a 8f 2d 1c 2a 8f 2a 8f 2d 1c 00 28 |....*.-.*.*.-..(|
- 000020: 00 31 00 3a 00 43 00 4c 00 01 00 00 00 01 00 64 |.1.:.C.L.......d|
- 000030: 5a 00 01 00 00 00 01 00 64 00 00 01 00 00 00 01 |Z.......d.......|
- 000040: 00 64 5a 00 01 00 00 00 01 00 64 5a 00 01 00 00 |.dZ.......dZ....|
- 000050: 00 01 00 64 00 00 00 00 00 00 00 07 00 00 00 64 |...d...........d|
- 000060: 64 00 00 4e 73 6f 00 64 01 00 00 00 00 00 00 00 |d..Nso.d........|
- 000070: 00 05 00 89 3d 57 2d 1c 3d 57 3d 57 2d 1c 00 28 |....=W-.=W=W-..(|
- playSound #16 (room 69)
- 000000: dc 00 00 a5 73 6f 00 64 01 00 00 00 00 00 00 00 |....so.d........|
- 000010: 00 05 00 00 2a 8f 03 e8 03 e8 03 e8 03 e8 00 28 |....*..........(|
- 000020: 00 79 00 7f 00 85 00 d6 00 01 00 00 00 19 01 18 |.y..............|
- 000030: 2f 00 18 00 01 18 32 00 18 00 01 18 36 00 18 00 |/.....2.....6...|
- 000040: 01 18 3b 00 18 00 01 18 3e 00 18 00 01 18 42 00 |..;.....>.....B.|
- 000050: 18 00 01 18 47 00 18 00 01 18 4a 00 18 00 01 18 |....G.....J.....|
- 000060: 4e 00 10 00 01 18 53 00 10 00 01 18 56 00 10 00 |N.....S.....V...|
- 000070: 01 18 5a 00 10 00 02 28 5f 00 01 00 00 00 00 00 |..Z....(_.......|
- */
- }
- else if ((_vm->_platform == Common::kPlatformMacintosh) && (_vm->_gameId == GID_INDY3) && (ptr[26] == 0)) {
- size = READ_BE_UINT16(ptr + 12);
- rate = 3579545 / READ_BE_UINT16(ptr + 20);
- sound = (char *)malloc(size);
- int vol = ptr[24] * 4;
- memcpy(sound, ptr + READ_BE_UINT16(ptr + 8), size);
- _vm->_mixer->playRaw(NULL, sound, size, rate, Audio::Mixer::FLAG_AUTOFREE, soundID, vol, 0);
- }
- else {
-
- if (_vm->_gameId == GID_MONKEY_VGA || _vm->_gameId == GID_MONKEY_EGA
- || (_vm->_gameId == GID_MONKEY && _vm->_platform == Common::kPlatformMacintosh)) {
- // Sound is currently not supported at all in the amiga versions of these games
- if (_vm->_platform == Common::kPlatformAmiga) {
- int track = -1;
- if (soundID == 50)
- track = 17;
- else if (ptr[6] == 0x7F && ptr[7] == 0x00 && ptr[8] == 0x80) {
- static const char tracks[16] = {13,14,10,3,4,9,16,5,1,8,2,15,6,7,11,12};
- if (ptr[9] == 0x0E)
- track = 18;
- else
- track = tracks[ptr[9] - 0x23];
- }
- if (track != -1) {
- playCDTrack(track,((track < 5) || (track > 16)) ? 1 : -1,0,0);
- stopCDTimer();
- _currentCDSound = soundID;
- }
- return;
- }
-
- // Works around the fact that in some places in MonkeyEGA/VGA,
- // the music is never explicitly stopped.
- // Rather it seems that starting a new music is supposed to
- // automatically stop the old song.
- if (_vm->_imuse) {
- if (READ_UINT32(ptr) != MKID('ASFX'))
- _vm->_imuse->stopAllSounds();
- }
- }
-
- if (_vm->_musicEngine) {
- _vm->_musicEngine->startSound(soundID);
- }
- }
-
- free(mallocedPtr);
-}
-
-void Sound::processSfxQueues() {
-
- if (_talk_sound_mode != 0) {
- if (_talk_sound_mode & 1)
- startTalkSound(_talk_sound_a1, _talk_sound_b1, 1);
- if (_talk_sound_mode & 2)
- startTalkSound(_talk_sound_a2, _talk_sound_b2, 2, &_talkChannelHandle);
- _talk_sound_mode = 0;
- }
-
- const int act = _vm->getTalkingActor();
- if ((_sfxMode & 2) && act != 0) {
- Actor *a;
- bool finished;
-
- if (_vm->_imuseDigital) {
- finished = !isSoundRunning(kTalkSoundID);
- } else if (_vm->_heversion >= 60) {
- finished = !isSoundRunning(1);
- } else {
- finished = !_vm->_mixer->isSoundHandleActive(_talkChannelHandle);
- }
-
- if ((uint) act < 0x80 && ((_vm->_version == 8) || (_vm->_version <= 7 && !_vm->_string[0].no_talk_anim))) {
- a = _vm->derefActor(act, "processSfxQueues");
- if (a->isInCurrentRoom()) {
- if (isMouthSyncOff(_curSoundPos) && !_mouthSyncMode) {
- if (!_endOfMouthSync)
- a->runActorTalkScript(a->_talkStopFrame);
- _mouthSyncMode = 0;
- } else if (isMouthSyncOff(_curSoundPos) == 0 && !_mouthSyncMode) {
- a->runActorTalkScript(a->_talkStartFrame);
- _mouthSyncMode = 1;
- }
-
- if (_vm->_version <= 6 && finished)
- a->runActorTalkScript(a->_talkStopFrame);
- }
- }
-
- if ((!ConfMan.getBool("subtitles") && finished && _vm->_version <= 6) || (finished && _vm->_talkDelay == 0)) {
- if (!(_vm->_version == 8 && _vm->VAR(_vm->VAR_HAVE_MSG) == 0))
- _vm->stopTalk();
- }
- }
-
- if (_sfxMode & 1) {
- if (isSfxFinished()) {
- _sfxMode &= ~1;
- }
- }
-}
-
-static int compareMP3OffsetTable(const void *a, const void *b) {
- return ((const MP3OffsetTable *)a)->org_offset - ((const MP3OffsetTable *)b)->org_offset;
-}
-
-void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle *handle) {
- int num = 0, i;
- int size = 0;
- int id = -1;
-
- if (_vm->_gameId == GID_CMI) {
- _sfxMode |= mode;
- return;
- } else if (_vm->_gameId == GID_DIG) {
- _sfxMode |= mode;
- if (!(_vm->_features & GF_DEMO))
- return;
-
- char filename[30];
- char roomname[10];
-
- if (offset == 1)
- strcpy(roomname, "logo");
- else if (offset == 15)
- strcpy(roomname, "canyon");
- else if (offset == 17)
- strcpy(roomname, "pig");
- else if (offset == 18)
- strcpy(roomname, "derelict");
- else if (offset == 19)
- strcpy(roomname, "wreck");
- else if (offset == 20)
- strcpy(roomname, "grave");
- else if (offset == 23)
- strcpy(roomname, "nexus");
- else if (offset == 79)
- strcpy(roomname, "newton");
- else {
- warning("startTalkSound: dig demo: unknown room number: %d", offset);
- return;
- }
-
- _sfxFile->close();
- sprintf(filename, "audio/%s.%d/%d.voc", roomname, offset, b);
- _vm->openFile(*_sfxFile, filename);
- if (!_sfxFile->isOpen()) {
- sprintf(filename, "%d.%d.voc", offset, b);
- _vm->openFile(*_sfxFile, filename);
- }
- if (!_sfxFile->isOpen()) {
- warning("startTalkSound: dig demo: voc file not found");
- return;
- }
- } else {
-
- if (!_sfxFile->isOpen()) {
- warning("startTalkSound: SFX file is not open");
- return;
- }
-
- // Some games frequently assume that starting one sound effect will
- // automatically stop any other that may be playing at that time. So
- // that is what we do here, but we make an exception for speech.
-
- if (mode == 1 && (_vm->_gameId == GID_TENTACLE || _vm->_gameId == GID_SAMNMAX)) {
- id = 777777 + _talk_sound_channel;
- _vm->_mixer->stopID(id);
- }
-
- if (b > 8) {
- num = (b - 8) >> 1;
- }
-
- if (_offsetTable != NULL) {
- MP3OffsetTable *result = NULL, key;
-
- key.org_offset = offset;
- result = (MP3OffsetTable *)bsearch(&key, _offsetTable, _numSoundEffects,
- sizeof(MP3OffsetTable), compareMP3OffsetTable);
-
- if (result == NULL) {
- warning("startTalkSound: did not find sound at offset %d !", offset);
- return;
- }
- if (2 * num != result->num_tags) {
- warning("startTalkSound: number of tags do not match (%d - %d) !", b,
- result->num_tags);
- num = result->num_tags;
- }
- offset = result->new_offset;
- size = result->compressed_size;
- } else {
- offset += 8;
- size = -1;
- }
-
- _sfxFile->seek(offset, SEEK_SET);
-
- assert(num + 1 < (int)ARRAYSIZE(_mouthSyncTimes));
- for (i = 0; i < num; i++)
- _mouthSyncTimes[i] = _sfxFile->readUint16BE();
-
- _mouthSyncTimes[i] = 0xFFFF;
- _sfxMode |= mode;
- _curSoundPos = 0;
- _mouthSyncMode = true;
- }
-
- if (!_soundsPaused && _vm->_mixer->isReady()) {
- AudioStream *input = NULL;
-
- switch (_soundMode) {
- case kMP3Mode:
- #ifdef USE_MAD
- assert(size > 0);
- input = makeMP3Stream(_sfxFile, size);
- #endif
- break;
- case kVorbisMode:
- #ifdef USE_VORBIS
- assert(size > 0);
- input = makeVorbisStream(_sfxFile, size);
- #endif
- break;
- case kFlacMode:
- #ifdef USE_FLAC
- assert(size > 0);
- input = makeFlacStream(_sfxFile, size);
- #endif
- break;
- default:
- input = makeVOCStream(*_sfxFile);
- }
-
- if (!input) {
- warning("startSfxSound failed to load sound");
- return;
- }
-
- if (_vm->_imuseDigital) {
-#ifndef DISABLE_SCUMM_7_8
- //_vm->_imuseDigital->stopSound(kTalkSoundID);
- _vm->_imuseDigital->startVoice(kTalkSoundID, input);
-#endif
- } else {
- _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, handle, input, id);
- }
- }
-}
-
-void Sound::stopTalkSound() {
- if (_sfxMode & 2) {
- if (_vm->_imuseDigital) {
-#ifndef DISABLE_SCUMM_7_8
- _vm->_imuseDigital->stopSound(kTalkSoundID);
-#endif
- } else if (_vm->_heversion >= 60) {
- stopSound(1);
- } else {
- _vm->_mixer->stopHandle(_talkChannelHandle);
- }
- _sfxMode &= ~2;
- }
-}
-
-bool Sound::isMouthSyncOff(uint pos) {
- uint j;
- bool val = true;
- uint16 *ms = _mouthSyncTimes;
-
- _endOfMouthSync = false;
- do {
- val = !val;
- j = *ms++;
- if (j == 0xFFFF) {
- _endOfMouthSync = true;
- break;
- }
- } while (pos > j);
- return val;
-}
-
-int Sound::isSoundRunning(int sound) const {
-#ifndef DISABLE_SCUMM_7_8
- if (_vm->_imuseDigital)
- return (_vm->_imuseDigital->getSoundStatus(sound) != 0);
-#endif
-
- if (sound == _currentCDSound)
- return pollCD();
-
- if (_vm->_heversion >= 70) {
- if (sound >= 10000) {
- return _vm->_mixer->getSoundID(_heSoundChannels[sound - 10000]);
- }
- } else if (_vm->_heversion >= 60) {
- if (sound == -2) {
- return !isSfxFinished();
- } else if (sound == -1) {
- // getSoundStatus(), with a -1, will return the
- // ID number of the first active music it finds.
- if (_currentMusic)
- return (_vm->_mixer->isSoundIDActive(_currentMusic) ? _currentMusic : 0);
- else if (_vm->_imuse)
- return (_vm->_imuse->getSoundStatus(sound));
- }
- }
-
- if (_vm->_mixer->isSoundIDActive(sound))
- return 1;
-
- if (isSoundInQueue(sound))
- return 1;
-
- if (sound > _vm->_numSounds || !_vm->res.isResourceLoaded(rtSound, sound))
- return 0;
-
- if (_vm->_musicEngine)
- return _vm->_musicEngine->getSoundStatus(sound);
-
- return 0;
-}
-
-/**
- * Check whether the sound resource with the specified ID is still
- * used. This is invoked by ScummEngine::isResourceInUse, to determine
- * which resources can be expired from memory.
- * Technically, this works very similar to isSoundRunning, however it
- * calls IMuse::get_sound_active() instead of IMuse::getSoundStatus().
- * The difference between those two is in how they treat sounds which
- * are being faded out: get_sound_active() returns true even when the
- * sound is being faded out, while getSoundStatus() returns false in
- * that case.
- */
-bool Sound::isSoundInUse(int sound) const {
-
-#ifndef DISABLE_SCUMM_7_8
- if (_vm->_imuseDigital)
- return (_vm->_imuseDigital->getSoundStatus(sound) != 0);
-#endif
-
- if (sound == _currentCDSound)
- return pollCD() != 0;
-
- if (isSoundInQueue(sound))
- return true;
-
- if (!_vm->res.isResourceLoaded(rtSound, sound))
- return false;
-
- if (_vm->_imuse)
- return _vm->_imuse->get_sound_active(sound);
-
- if (_vm->_mixer->isSoundIDActive(sound))
- return 1;
-
- return false;
-}
-
-bool Sound::isSoundInQueue(int sound) const {
- int i, num;
-
- i = _soundQue2Pos;
- while (i--) {
- if (_soundQue2[i].sound == sound)
- return true;
- }
-
- i = 0;
- while (i < _soundQuePos) {
- num = _soundQue[i++];
-
- if (num > 0) {
- if (_soundQue[i + 0] == 0x10F && _soundQue[i + 1] == 8 && _soundQue[i + 2] == sound)
- return true;
- i += num;
- }
- }
- return false;
-}
-
-void Sound::stopSound(int sound) {
- int i;
-
- if (_vm->_heversion >= 70) {
- if ( sound >= 10000) {
- int chan = sound - 10000;
- _vm->_mixer->stopHandle(_heSoundChannels[chan]);
- _heChannel[chan].sound = 0;
- _heChannel[chan].priority = 0;
- _heChannel[chan].sbngBlock = 0;
- _heChannel[chan].codeOffs = 0;
- memset(_heChannel[chan].soundVars, 0, sizeof(_heChannel[chan].soundVars));
- }
- } else if (_vm->_heversion >= 60) {
- if (sound == -2) {
- } else if (sound == -1) {
- // Stop current music
- if (_currentMusic)
- _vm->_mixer->stopID(_currentMusic);
- else if (_vm->_imuse)
- _vm->_imuse->stopSound(_vm->_imuse->getSoundStatus(-1));
- }
- }
-
- if (sound != 0 && sound == _currentCDSound) {
- _currentCDSound = 0;
- stopCD();
- stopCDTimer();
- }
-
- if (!(_vm->_features & GF_DIGI_IMUSE))
- _vm->_mixer->stopID(sound);
-
- if (_vm->_musicEngine)
- _vm->_musicEngine->stopSound(sound);
-
- for (i = 0; i < ARRAYSIZE(_heChannel); i++) {
- if (_heChannel[i].sound == sound) {
- _heChannel[i].sound = 0;
- _heChannel[i].priority = 0;
- _heChannel[i].sbngBlock = 0;
- _heChannel[i].codeOffs = 0;
- memset(_heChannel[i].soundVars, 0, sizeof(_heChannel[i].soundVars));
- }
- }
-
- for (i = 0; i < ARRAYSIZE(_soundQue2); i++) {
- if (_soundQue2[i].sound == sound) {
- _soundQue2[i].sound = 0;
- _soundQue2[i].offset = 0;
- _soundQue2[i].channel = 0;
- _soundQue2[i].flags = 0;
- }
- }
-}
-
-void Sound::stopAllSounds() {
- if (_currentCDSound != 0) {
- _currentCDSound = 0;
- stopCD();
- stopCDTimer();
- }
-
- // Clear sound channels for HE games
- memset(_heChannel, 0, sizeof(_heChannel));
-
- // Clear the (secondary) sound queue
- _soundQue2Pos = 0;
- memset(_soundQue2, 0, sizeof(_soundQue2));
-
- if (_vm->_musicEngine) {
- _vm->_musicEngine->stopAllSounds();
- }
- if (_vm->_imuse) {
- // FIXME: Maybe we could merge this call to clear_queue()
- // into IMuse::stopAllSounds() ?
- _vm->_imuse->clear_queue();
- }
-
- // Stop all SFX
- if (!_vm->_imuseDigital) {
- _vm->_mixer->stopAll();
- }
-}
-
-void Sound::soundKludge(int *list, int num) {
- int i;
-
-#ifndef DISABLE_SCUMM_7_8
- if (_vm->_imuseDigital) {
- _vm->_imuseDigital->parseScriptCmds(list[0], list[1], list[2], list[3], list[4],
- list[5], list[6], list[7]);
- return;
- }
-#endif
-
- if (list[0] == -1) {
- processSound();
- } else {
- _soundQue[_soundQuePos++] = num;
-
- for (i = 0; i < num; i++) {
- _soundQue[_soundQuePos++] = list[i];
- }
- }
-}
-
-void Sound::talkSound(uint32 a, uint32 b, int mode, int channel) {
- if (_vm->_version >= 6 && ConfMan.getBool("speech_mute"))
- return;
-
- if (mode == 1) {
- _talk_sound_a1 = a;
- _talk_sound_b1 = b;
- _talk_sound_channel = channel;
- } else {
- _talk_sound_a2 = a;
- _talk_sound_b2 = b;
- }
-
- _talk_sound_mode |= mode;
-}
-
-/* The sound code currently only supports General Midi.
- * General Midi is used in Day Of The Tentacle.
- * Roland music is also playable, but doesn't sound well.
- * A mapping between roland instruments and GM instruments
- * is needed.
- */
-
-void Sound::setupSound() {
- delete _sfxFile;
-
- _sfxFile = openSfxFile();
-
- if (_vm->_heversion >= 70) {
- setupHEMusicFile();
- }
-
- if (_vm->_gameId == GID_FT) {
- _vm->VAR(_vm->VAR_VOICE_BUNDLE_LOADED) = _sfxFile->isOpen();
- }
-}
-
-void Sound::pauseSounds(bool pause) {
- if (_vm->_imuse)
- _vm->_imuse->pause(pause);
-
- // Don't pause sounds if the game isn't active
- // FIXME - this is quite a nasty hack, replace with something cleaner, and w/o
- // having to access member vars directly!
- if (!_vm->_roomResource)
- return;
-
- _soundsPaused = pause;
-
-#ifndef DISABLE_SCUMM_7_8
- if (_vm->_imuseDigital) {
- _vm->_imuseDigital->pause(pause);
- }
-#endif
-
- _vm->_mixer->pauseAll(pause);
-
- if ((_vm->_features & GF_AUDIOTRACKS) && _vm->VAR(_vm->VAR_MUSIC_TIMER) > 0) {
- if (pause)
- stopCDTimer();
- else
- startCDTimer();
- }
-}
-
-ScummFile *Sound::openSfxFile() {
- struct SoundFileExtensions {
- const char *ext;
- SoundMode mode;
- };
-
- static const SoundFileExtensions extensions[] = {
- { "sou", kVOCMode },
- #ifdef USE_FLAC
- { "sof", kFlacMode },
- #endif
- #ifdef USE_VORBIS
- { "sog", kVorbisMode },
- #endif
- #ifdef USE_MAD
- { "so3", kMP3Mode },
- #endif
- { 0, kVOCMode }
- };
-
- char buf[256];
- char buf1[128];
- ScummFile *file = new ScummFile();
- _offsetTable = NULL;
-
- /* Try opening the file <baseName>.sou first, e.g. tentacle.sou.
- * That way, you can keep .sou files for multiple games in the
- * same directory */
-
- const char *basename[4] = { 0, 0, 0, 0 };
- basename[0] = _vm->getBaseName();
- basename[1] = "monster";
-
- if (_vm->_substResFileNameIndex > 0) {
-
- strcpy(buf, basename[0]);
- _vm->generateSubstResFileName(buf, buf1, sizeof(buf1));
- strcpy(buf, buf1);
- basename[2] = buf1;
- }
-
- for (int j = 0; basename[j] && !file->isOpen(); ++j) {
- for (int i = 0; extensions[i].ext; ++i) {
- sprintf(buf, "%s.%s", basename[j], extensions[i].ext);
- if (_vm->openFile(*file, buf)) {
- _soundMode = extensions[i].mode;
- break;
- }
- }
- }
-
- if (!file->isOpen()) {
- if ((_vm->_heversion <= 61 && _vm->_platform == Common::kPlatformMacintosh) || (_vm->_heversion >= 70)) {
- sprintf(buf, "%s.he2", _vm->getBaseName());
- } else {
- sprintf(buf, "%s.tlk", _vm->getBaseName());
- }
-
- if (_vm->_substResFileNameIndex > 0) {
- _vm->generateSubstResFileName(buf, buf1, sizeof(buf1));
- strcpy(buf, buf1);
- }
- if (file->open(buf) && _vm->_heversion <= 73)
- file->setEnc(0x69);
- _soundMode = kVOCMode;
- }
-
- if (_soundMode != kVOCMode) {
- /* Now load the 'offset' index in memory to be able to find the MP3 data
-
- The format of the .SO3 file is easy :
- - number of bytes of the 'index' part
- - N times the following fields (4 bytes each) :
- + offset in the original sound file
- + offset of the MP3 data in the .SO3 file WITHOUT taking into account
- the index field and the 'size' field
- + the number of 'tags'
- + the size of the MP3 data
- - and then N times :
- + the tags
- + the MP3 data
- */
- int size, compressed_offset;
- MP3OffsetTable *cur;
- compressed_offset = file->readUint32BE();
- _offsetTable = (MP3OffsetTable *) malloc(compressed_offset);
- _numSoundEffects = compressed_offset / 16;
-
- size = compressed_offset;
- cur = _offsetTable;
- while (size > 0) {
- cur->org_offset = file->readUint32BE();
- cur->new_offset = file->readUint32BE() + compressed_offset + 4; /* The + 4 is to take into accound the 'size' field */
- cur->num_tags = file->readUint32BE();
- cur->compressed_size = file->readUint32BE();
- size -= 4 * 4;
- cur++;
- }
- }
-
- return file;
-}
-
-bool Sound::isSfxFinished() const {
- return !_vm->_mixer->hasActiveChannelOfType(Audio::Mixer::kSFXSoundType);
-}
-
-// We use a real timer in an attempt to get better sync with CD tracks. This is
-// necessary for games like Loom CD.
-
-static void cd_timer_handler(void *refCon) {
- ScummEngine *scumm = (ScummEngine *)refCon;
-
- // FIXME: Turn off the timer when it's no longer needed. In theory, it
- // should be possible to check with pollCD(), but since CD sound isn't
- // properly restarted when reloading a saved game, I don't dare to.
-
- scumm->VAR(scumm->VAR_MUSIC_TIMER) += 6;
-}
-
-void Sound::startCDTimer() {
- int timer_interval;
-
- // The timer interval has been tuned for Loom CD and the Monkey 1
- // intro. I have to use 100 for Loom, or there will be a nasty stutter
- // when Chaos first appears, and I have to use 101 for Monkey 1 or the
- // intro music will be cut short.
-
- if (_vm->_gameId == GID_LOOM && _vm->_version == 4)
- timer_interval = 100;
- else
- timer_interval = 101;
-
- _vm->_timer->removeTimerProc(&cd_timer_handler);
- _vm->_timer->installTimerProc(&cd_timer_handler, 1000 * timer_interval, _vm);
-}
-
-void Sound::stopCDTimer() {
- _vm->_timer->removeTimerProc(&cd_timer_handler);
-}
-
-void Sound::playCDTrack(int track, int numLoops, int startFrame, int duration) {
- // Reset the music timer variable at the start of a new track
- _vm->VAR(_vm->VAR_MUSIC_TIMER) = 0;
-
- // Play it
- if (!_soundsPaused)
- AudioCD.play(track, numLoops, startFrame, duration);
-
- // Start the timer after starting the track. Starting an MP3 track is
- // almost instantaneous, but a CD player may take some time. Hopefully
- // playCD() will block during that delay.
- startCDTimer();
-}
-
-void Sound::stopCD() {
- AudioCD.stop();
-}
-
-int Sound::pollCD() const {
- return AudioCD.isPlaying();
-}
-
-void Sound::updateCD() {
- AudioCD.updateCD();
-}
-
-void Sound::saveLoadWithSerializer(Serializer *ser) {
- static const SaveLoadEntry soundEntries[] = {
- MKLINE(Sound, _currentCDSound, sleInt16, VER(35)),
- MKLINE(Sound, _currentMusic, sleInt16, VER(35)),
- MKEND()
- };
-
- ser->saveLoadEntries(this, soundEntries);
-}
-
-
-#pragma mark -
-#pragma mark --- Sound resource handling ---
-#pragma mark -
-
-/*
- * TODO: The way we handle sound/music resources really is one huge hack.
- * We probably should reconsider how we do this, and maybe come up with a
- * better/cleaner solution. Even if we keep the existing code, it really
- * could stand a thorough cleanup!
- */
-
-
-int ScummEngine::readSoundResource(int type, int idx) {
- uint32 pos, total_size, size, tag, basetag, max_total_size;
- int pri, best_pri;
- uint32 best_size = 0, best_offs = 0;
- byte *ptr;
-
- debugC(DEBUG_RESOURCE, "readSoundResource(%d)", idx);
-
- pos = 0;
-
- _fileHandle->readUint32LE();
- max_total_size = _fileHandle->readUint32BE() - 8;
- basetag = fileReadDword();
- total_size = _fileHandle->readUint32BE();
-
- debugC(DEBUG_RESOURCE, " basetag: %s, total_size=%d", tag2str(TO_BE_32(basetag)), total_size);
-
- switch (basetag) {
- case MKID('MIDI'):
- case MKID('iMUS'):
- if (_musicType != MDT_PCSPK) {
- _fileHandle->seek(-8, SEEK_CUR);
- _fileHandle->read(res.createResource(type, idx, total_size + 8), total_size + 8);
- return 1;
- }
- break;
- case MKID('SOU '):
- best_pri = -1;
- while (pos < total_size) {
- tag = fileReadDword();
- size = _fileHandle->readUint32BE() + 8;
- pos += size;
-
- pri = -1;
-
- switch (tag) {
- case MKID('TOWS'):
- pri = 16;
- break;
- case MKID('SBL '):
- pri = 15;
- break;
- case MKID('ADL '):
- pri = 1;
- if (_musicType == MDT_ADLIB)
- pri = 10;
- break;
- case MKID('AMI '):
- pri = 3;
- break;
- case MKID('ROL '):
- pri = 3;
- if (_native_mt32)
- pri = 5;
- break;
- case MKID('GMD '):
- pri = 4;
- break;
- case MKID('MAC '): // Occurs in Mac MI2, FOA
- pri = 2;
- break;
- case MKID('SPK '):
- pri = -1;
-// if (_musicType == MDT_PCSPK)
-// pri = 11;
- break;
- }
-
- if ((_musicType == MDT_PCSPK) && pri != 11)
- pri = -1;
-
- debugC(DEBUG_RESOURCE, " tag: %s, total_size=%d, pri=%d", tag2str(TO_BE_32(tag)), size, pri);
-
-
- if (pri > best_pri) {
- best_pri = pri;
- best_size = size;
- best_offs = _fileHandle->pos();
- }
-
- _fileHandle->seek(size - 8, SEEK_CUR);
- }
-
- if (best_pri != -1) {
- _fileHandle->seek(best_offs - 8, SEEK_SET);
- ptr = res.createResource(type, idx, best_size);
- _fileHandle->read(ptr, best_size);
- //dumpResource("sound-", idx, ptr);
- return 1;
- }
- break;
- case MKID('Mac0'):
- _fileHandle->seek(-12, SEEK_CUR);
- total_size = _fileHandle->readUint32BE() - 8;
- ptr = (byte *)calloc(total_size, 1);
- _fileHandle->read(ptr, total_size);
- //dumpResource("sound-", idx, ptr);
- convertMac0Resource(type, idx, ptr, total_size);
- free(ptr);
- return 1;
-
- case MKID('Mac1'):
- case MKID('RIFF'):
- case MKID('TALK'):
- case MKID('DIGI'):
- case MKID('Crea'):
- case MKID(0x460e200d): // WORKAROUND bug # 1311447
- _fileHandle->seek(-12, SEEK_CUR);
- total_size = _fileHandle->readUint32BE();
- ptr = res.createResource(type, idx, total_size);
- _fileHandle->read(ptr, total_size - 8);
- //dumpResource("sound-", idx, ptr);
- return 1;
-
- case MKID('HSHD'):
- // HE sound type without SOUN header
- _fileHandle->seek(-16, SEEK_CUR);
- total_size = max_total_size + 8;
- ptr = res.createResource(type, idx, total_size);
- _fileHandle->read(ptr, total_size);
- //dumpResource("sound-", idx, ptr);
- return 1;
-
- case MKID('FMUS'): {
- // Used in 3DO version of puttputt joins the parade and probably others
- // Specifies a separate file to be used for music from what I gather.
- int tmpsize;
- Common::File dmuFile;
- char buffer[128];
- debugC(DEBUG_SOUND, "Found base tag FMUS in sound %d, size %d", idx, total_size);
- debugC(DEBUG_SOUND, "It was at position %d", _fileHandle->pos());
-
- _fileHandle->seek(4, SEEK_CUR);
- // HSHD size
- tmpsize = _fileHandle->readUint32BE();
- // skip to size part of the SDAT block
- _fileHandle->seek(tmpsize - 4, SEEK_CUR);
- // SDAT size
- tmpsize = _fileHandle->readUint32BE();
-
- // SDAT contains name of file we want
- _fileHandle->read(buffer, tmpsize - 8);
- // files seem to be 11 chars (8.3) unused space is replaced by spaces
- *(strstr(buffer, " ")) = '\0';
-
- debugC(DEBUG_SOUND, "FMUS file %s", buffer);
- if (dmuFile.open(buffer) == false) {
- error("Can't open music file %s*", buffer);
- res.roomoffs[type][idx] = 0xFFFFFFFF;
- return 0;
- }
- dmuFile.seek(4, SEEK_SET);
- total_size = dmuFile.readUint32BE();
- debugC(DEBUG_SOUND, "dmu file size %d", total_size);
- dmuFile.seek(-8, SEEK_CUR);
- dmuFile.read(res.createResource(type, idx, total_size), total_size);
- dmuFile.close();
- }
- return 1;
-
- default:
- if (FROM_LE_32(basetag) == max_total_size) {
- _fileHandle->seek(-12, SEEK_CUR);
- total_size = _fileHandle->readUint32BE();
- _fileHandle->seek(-8, SEEK_CUR);
- ptr = res.createResource(type, idx, total_size);
- _fileHandle->read(ptr, total_size);
- //dumpResource("sound-", idx, ptr);
- return 1;
- }
- error("Unrecognized base tag 0x%08x in sound %d", TO_BE_32(basetag), idx);
- }
- res.roomoffs[type][idx] = 0xFFFFFFFF;
- return 0;
-}
-
-// Adlib MIDI-SYSEX to set MIDI instruments for small header games.
-static byte ADLIB_INSTR_MIDI_HACK[95] = {
- 0x00, 0xf0, 0x14, 0x7d, 0x00, // sysex 00: part on/off
- 0x00, 0x00, 0x03, // part/channel (offset 5)
- 0x00, 0x00, 0x07, 0x0f, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf7,
- 0x00, 0xf0, 0x41, 0x7d, 0x10, // sysex 16: set instrument
- 0x00, 0x01, // part/channel (offset 28)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf7,
- 0x00, 0xb0, 0x07, 0x64 // Controller 7 = 100 (offset 92)
-};
-
-static const byte map_param[7] = {
- 0, 2, 3, 4, 8, 9, 0,
-};
-
-static const byte freq2note[128] = {
- /*128*/ 6, 6, 6, 6,
- /*132*/ 7, 7, 7, 7, 7, 7, 7,
- /*139*/ 8, 8, 8, 8, 8, 8, 8, 8, 8,
- /*148*/ 9, 9, 9, 9, 9, 9, 9, 9, 9,
- /*157*/ 10, 10, 10, 10, 10, 10, 10, 10, 10,
- /*166*/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- /*176*/ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- /*186*/ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- /*197*/ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- /*209*/ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- /*222*/ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- /*235*/ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- /*249*/ 18, 18, 18, 18, 18, 18, 18
-};
-
-static const uint16 num_steps_table[] = {
- 1, 2, 4, 5,
- 6, 7, 8, 9,
- 10, 12, 14, 16,
- 18, 21, 24, 30,
- 36, 50, 64, 82,
- 100, 136, 160, 192,
- 240, 276, 340, 460,
- 600, 860, 1200, 1600
-};
-
-int ScummEngine::convert_extraflags(byte * ptr, byte * src_ptr) {
- int flags = src_ptr[0];
-
- int t1, t2, t3, t4, time;
- int v1, v2, v3;
-
- if (!(flags & 0x80))
- return -1;
-
- t1 = (src_ptr[1] & 0xf0) >> 3;
- t2 = (src_ptr[2] & 0xf0) >> 3;
- t3 = (src_ptr[3] & 0xf0) >> 3 | (flags & 0x40 ? 0x80 : 0);
- t4 = (src_ptr[3] & 0x0f) << 1;
- v1 = (src_ptr[1] & 0x0f);
- v2 = (src_ptr[2] & 0x0f);
- v3 = 31;
- if ((flags & 0x7) == 0) {
- v1 = v1 + 31 + 8;
- v2 = v2 + 31 + 8;
- } else {
- v1 = v1 * 2 + 31;
- v2 = v2 * 2 + 31;
- }
-
- /* flags a */
- if ((flags & 0x7) == 6)
- ptr[0] = 0;
- else {
- ptr[0] = (flags >> 4) & 0xb;
- ptr[1] = map_param[flags & 0x7];
- }
-
- /* extra a */
- ptr[2] = 0;
- ptr[3] = 0;
- ptr[4] = t1 >> 4;
- ptr[5] = t1 & 0xf;
- ptr[6] = v1 >> 4;
- ptr[7] = v1 & 0xf;
- ptr[8] = t2 >> 4;
- ptr[9] = t2 & 0xf;
- ptr[10] = v2 >> 4;
- ptr[11] = v2 & 0xf;
- ptr[12] = t3 >> 4;
- ptr[13] = t3 & 0xf;
- ptr[14] = t4 >> 4;
- ptr[15] = t4 & 0xf;
- ptr[16] = v3 >> 4;
- ptr[17] = v3 & 0xf;
-
- time = num_steps_table[t1] + num_steps_table[t2]
- + num_steps_table[t3 & 0x7f] + num_steps_table[t4];
- if (flags & 0x20) {
- int playtime = ((src_ptr[4] >> 4) & 0xf) * 118 +
- (src_ptr[4] & 0xf) * 8;
- if (playtime > time)
- time = playtime;
- }
- /*
- time = ((src_ptr[4] >> 4) & 0xf) * 118 +
- (src_ptr[4] & 0xf) * 8;
- */
- return time;
-}
-
-#define kMIDIHeaderSize 46
-static inline byte *writeMIDIHeader(byte *ptr, const char *type, int ppqn, int total_size) {
- uint32 dw = TO_BE_32(total_size);
-
- memcpy(ptr, type, 4); ptr += 4;
- memcpy(ptr, &dw, 4); ptr += 4;
- memcpy(ptr, "MDhd", 4); ptr += 4;
- ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 8;
- ptr += 4;
- memset(ptr, 0, 8), ptr += 8;
- memcpy(ptr, "MThd", 4); ptr += 4;
- ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 6;
- ptr += 4;
- ptr[0] = 0; ptr[1] = 0; ptr[2] = 0; ptr[3] = 1; // MIDI format 0 with 1 track
- ptr += 4;
-
- *ptr++ = ppqn >> 8;
- *ptr++ = ppqn & 0xFF;
-
- memcpy(ptr, "MTrk", 4); ptr += 4;
- memcpy(ptr, &dw, 4); ptr += 4;
-
- return ptr;
-}
-
-static inline byte *writeVLQ(byte *ptr, int value) {
- if (value > 0x7f) {
- if (value > 0x3fff) {
- *ptr++ = (value >> 14) | 0x80;
- value &= 0x3fff;
- }
- *ptr++ = (value >> 7) | 0x80;
- value &= 0x7f;
- }
- *ptr++ = value;
- return ptr;
-}
-
-static inline byte Mac0ToGMInstrument(uint32 type, int &transpose) {
- transpose = 0;
- switch (type) {
- case MKID('MARI'): return 12;
- case MKID('PLUC'): return 45;
- case MKID('HARM'): return 22;
- case MKID('PIPE'): return 19;
- case MKID('TROM'): transpose = -12; return 57;
- case MKID('STRI'): return 48;
- case MKID('HORN'): return 60;
- case MKID('VIBE'): return 11;
- case MKID('SHAK'): return 77;
- case MKID('PANP'): return 75;
- case MKID('WHIS'): return 76;
- case MKID('ORGA'): return 17;
- case MKID('BONG'): return 115;
- case MKID('BASS'): transpose = -24; return 35;
- default:
- error("Unknown Mac0 instrument %s found", tag2str(type));
- }
-}
-
-void ScummEngine::convertMac0Resource(int type, int idx, byte *src_ptr, int size) {
- /*
- From Markus Magnuson (superqult) we got this information:
- Mac0
- ---
- 4 bytes - 'SOUN'
- BE 4 bytes - block length
-
- 4 bytes - 'Mac0'
- BE 4 bytes - (blockLength - 27)
- 28 bytes - ???
-
- do this three times (once for each channel):
- 4 bytes - 'Chan'
- BE 4 bytes - channel length
- 4 bytes - instrument name (e.g. 'MARI')
-
- do this for ((chanLength-24)/4) times:
- 2 bytes - note duration
- 1 byte - note value
- 1 byte - note velocity
-
- 4 bytes - ???
- 4 bytes - 'Loop'/'Done'
- 4 bytes - ???
-
- 1 byte - 0x09
- ---
-
- Instruments (General Midi):
- "MARI" - Marimba (12)
- "PLUC" - Pizzicato Strings (45)
- "HARM" - Harmonica (22)
- "PIPE" - Church Organ? (19) or Flute? (73) or Bag Pipe (109)
- "TROM" - Trombone (57)
- "STRI" - String Ensemble (48 or 49)
- "HORN" - French Horn? (60) or English Horn? (69)
- "VIBE" - Vibraphone (11)
- "SHAK" - Shakuhachi? (77)
- "PANP" - Pan Flute (75)
- "WHIS" - Whistle (78) / Bottle (76)
- "ORGA" - Drawbar Organ (16; but could also be 17-20)
- "BONG" - Woodblock? (115)
- "BASS" - Bass (32-39)
-
-
- Now the task could be to convert this into MIDI, to be fed into iMuse.
- Or we do something similiar to what is done in Player_V3, assuming
- we can identify SFX in the MI datafiles for each of the instruments
- listed above.
- */
-
-#if 0
- byte *ptr = res.createResource(type, idx, size);
- memcpy(ptr, src_ptr, size);
-#else
- const int ppqn = 480;
- byte *ptr, *start_ptr;
-
- int total_size = 0;
- total_size += kMIDIHeaderSize; // Header
- total_size += 7; // Tempo META
- total_size += 3 * 3; // Three program change mesages
- total_size += 22; // Possible jump SysEx
- total_size += 5; // EOT META
-
- int i, len;
- byte track_instr[3];
- byte *track_data[3];
- int track_len[3];
- int track_transpose[3];
- bool looped = false;
-
- src_ptr += 8;
- // TODO: Decipher the unknown bytes in the header. For now, skip 'em
- src_ptr += 28;
-
- // Parse the three channels
- for (i = 0; i < 3; i++) {
- assert(*((uint32*)src_ptr) == MKID('Chan'));
- len = READ_BE_UINT32(src_ptr + 4);
- track_len[i] = len - 24;
- track_instr[i] = Mac0ToGMInstrument(*(uint32*)(src_ptr + 8), track_transpose[i]);
- track_data[i] = src_ptr + 12;
- src_ptr += len;
- looped = (*((uint32*)(src_ptr - 8)) == MKID('Loop'));
-
- // For each note event, we need up to 6 bytes for the
- // Note On (3 VLQ, 3 event), and 6 bytes for the Note
- // Off (3 VLQ, 3 event). So 12 bytes total.
- total_size += 12 * track_len[i];
- }
- assert(*src_ptr == 0x09);
-
- // Create sound resource
- start_ptr = res.createResource(type, idx, total_size);
-
- // Insert MIDI header
- ptr = writeMIDIHeader(start_ptr, "GMD ", ppqn, total_size);
-
- // Write a tempo change Meta event
- // 473 / 4 Hz, convert to micro seconds.
- uint32 dw = 1000000 * 437 / 4 / ppqn; // 1000000 * ppqn * 4 / 473;
- memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4;
- *ptr++ = (byte)((dw >> 16) & 0xFF);
- *ptr++ = (byte)((dw >> 8) & 0xFF);
- *ptr++ = (byte)(dw & 0xFF);
-
- // Insert program change messages
- *ptr++ = 0; // VLQ
- *ptr++ = 0xC0;
- *ptr++ = track_instr[0];
- *ptr++ = 0; // VLQ
- *ptr++ = 0xC1;
- *ptr++ = track_instr[1];
- *ptr++ = 0; // VLQ
- *ptr++ = 0xC2;
- *ptr++ = track_instr[2];
-
- // And now, the actual composition. Please turn all cell phones
- // and pagers off during the performance. Thank you.
- uint16 nextTime[3] = { 1, 1, 1 };
- int stage[3] = { 0, 0, 0 };
-
- while (track_len[0] | track_len[1] | track_len[2]) {
- int best = -1;
- uint16 bestTime = 0xFFFF;
- for (i = 0; i < 3; ++i) {
- if (track_len[i] && nextTime[i] < bestTime) {
- bestTime = nextTime[i];
- best = i;
- }
- }
- assert (best != -1);
-
- if (!stage[best]) {
- // We are STARTING this event.
- if (track_data[best][2] > 1) {
- // Note On
- ptr = writeVLQ(ptr, nextTime[best]);
- *ptr++ = 0x90 | best;
- *ptr++ = track_data[best][2] + track_transpose[best];
- *ptr++ = track_data[best][3] * 127 / 100; // Scale velocity
- for (i = 0; i < 3; ++i)
- nextTime[i] -= bestTime;
- }
- nextTime[best] += READ_BE_UINT16 (track_data[best]);
- stage[best] = 1;
- } else {
- // We are ENDING this event.
- if (track_data[best][2] > 1) {
- // There was a Note On, so do a Note Off
- ptr = writeVLQ(ptr, nextTime[best]);
- *ptr++ = 0x80 | best;
- *ptr++ = track_data[best][2] + track_transpose[best];
- *ptr++ = track_data[best][3] * 127 / 100; // Scale velocity
- for (i = 0; i < 3; ++i)
- nextTime[i] -= bestTime;
- }
- track_data[best] += 4;
- track_len[best] -= 4;
- stage[best] = 0;
- }
- }
-
- // Is this a looped song? If so, effect a loop by
- // using the S&M maybe_jump SysEx command.
- // FIXME: Jamieson630: The jump seems to be happening
- // too quickly! There should maybe be a pause after
- // the last Note Off? But I couldn't find one in the
- // MI1 Lookout music, where I was hearing problems.
- if (looped) {
- memcpy(ptr, "\x00\xf0\x13\x7d\x30\00", 6); ptr += 6; // maybe_jump
- memcpy(ptr, "\x00\x00", 2); ptr += 2; // cmd -> 0 means always jump
- memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4; // track -> 0 (only track)
- memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // beat -> 1 (first beat)
- memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // tick -> 1
- memcpy(ptr, "\x00\xf7", 2); ptr += 2; // SysEx end marker
- }
-
- // Insert end of song META
- memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5;
-
- assert(ptr <= start_ptr + total_size);
-
- // Rewrite MIDI header, this time with true size
- total_size = ptr - start_ptr;
- ptr = writeMIDIHeader(start_ptr, "GMD ", ppqn, total_size);
-#endif
-}
-
-void ScummEngine::convertADResource(int type, int idx, byte *src_ptr, int size) {
-
- // We will ignore the PPQN in the original resource, because
- // it's invalid anyway. We use a constant PPQN of 480.
- const int ppqn = 480;
- uint32 dw;
- int i, ch;
- byte *ptr;
- int total_size = kMIDIHeaderSize + 7 + 8 * sizeof(ADLIB_INSTR_MIDI_HACK) + size;
- total_size += 24; // Up to 24 additional bytes are needed for the jump sysex
-
- ptr = res.createResource(type, idx, total_size);
-
- src_ptr += 2;
- size -= 2;
-
- // 0x80 marks a music resource. Otherwise it's a SFX
- if (*src_ptr == 0x80) {
- byte ticks, play_once;
- byte num_instr;
- byte *channel, *instr, *track;
-
- ptr = writeMIDIHeader(ptr, "ADL ", ppqn, total_size);
-
- // The "speed" of the song
- ticks = *(src_ptr + 1);
-
- // Flag that tells us whether we should loop the song (0) or play it only once (1)
- play_once = *(src_ptr + 2);
-
- // Number of instruments used
- num_instr = *(src_ptr + 8); // Normally 8
-
- // copy the pointer to instrument data
- channel = src_ptr + 9;
- instr = src_ptr + 0x11;
-
- // skip over the rest of the header and copy the MIDI data into a buffer
- src_ptr += 0x11 + 8 * 16;
- size -= 0x11 + 8 * 16;
-
- CHECK_HEAP
-
- track = src_ptr;
-
- // Convert the ticks into a MIDI tempo.
- // Unfortunate LOOM and INDY3 have different interpretation
- // of the ticks value.
- if (_gameId == GID_INDY3) {
- // Note: since we fix ppqn at 480, ppqn/473 is almost 1
- dw = 500000 * 256 / 473 * ppqn / ticks;
- } else if (_gameId == GID_LOOM && _version == 3) {
- dw = 500000 * ppqn / 4 / ticks;
- } else {
- dw = 500000 * 256 / ticks;
- }
- debugC(DEBUG_SOUND, " ticks = %d, speed = %ld", ticks, dw);
-
- // Write a tempo change Meta event
- memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4;
- *ptr++ = (byte)((dw >> 16) & 0xFF);
- *ptr++ = (byte)((dw >> 8) & 0xFF);
- *ptr++ = (byte)(dw & 0xFF);
-
- // Copy our hardcoded instrument table into it
- // Then, convert the instrument table as given in this song resource
- // And write it *over* the hardcoded table.
- // Note: we deliberately.
-
- /* now fill in the instruments */
- for (i = 0; i < num_instr; i++) {
- ch = channel[i] - 1;
- if (ch < 0 || ch > 15)
- continue;
-
- if (instr[i*16 + 13])
- debugC(DEBUG_SOUND, "Sound %d instrument %d uses percussion", idx, i);
-
- debugC(DEBUG_SOUND, "Sound %d: instrument %d on channel %d.", idx, i, ch);
-
- memcpy(ptr, ADLIB_INSTR_MIDI_HACK, sizeof(ADLIB_INSTR_MIDI_HACK));
-
- ptr[5] += ch;
- ptr[28] += ch;
- ptr[92] += ch;
-
- /* flags_1 */
- ptr[30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf;
- ptr[30 + 1] = instr[i * 16 + 3] & 0xf;
-
- /* oplvl_1 */
- ptr[30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf;
- ptr[30 + 3] = instr[i * 16 + 4] & 0xf;
-
- /* atdec_1 */
- ptr[30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf;
- ptr[30 + 5] = (~instr[i * 16 + 5]) & 0xf;
-
- /* sustrel_1 */
- ptr[30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf;
- ptr[30 + 7] = (~instr[i * 16 + 6]) & 0xf;
-
- /* waveform_1 */
- ptr[30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf;
- ptr[30 + 9] = instr[i * 16 + 7] & 0xf;
-
- /* flags_2 */
- ptr[30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf;
- ptr[30 + 11] = instr[i * 16 + 8] & 0xf;
-
- /* oplvl_2 */
- ptr[30 + 12] = (instr[i * 16 + 9] >> 4) & 0xf;
- ptr[30 + 13] = instr[i * 16 + 9] & 0xf;
-
- /* atdec_2 */
- ptr[30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf;
- ptr[30 + 15] = (~instr[i * 16 + 10]) & 0xf;
-
- /* sustrel_2 */
- ptr[30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf;
- ptr[30 + 17] = (~instr[i * 16 + 11]) & 0xf;
-
- /* waveform_2 */
- ptr[30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf;
- ptr[30 + 19] = instr[i * 16 + 12] & 0xf;
-
- /* feedback */
- ptr[30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf;
- ptr[30 + 21] = instr[i * 16 + 2] & 0xf;
- ptr += sizeof(ADLIB_INSTR_MIDI_HACK);
- }
-
- // There is a constant delay of ppqn/3 before the music starts.
- if (ppqn / 3 >= 128)
- *ptr++ = (ppqn / 3 >> 7) | 0x80;
- *ptr++ = ppqn / 3 & 0x7f;
-
- // Now copy the actual music data
- memcpy(ptr, track, size);
- ptr += size;
-
- if (!play_once) {
- // The song is meant to be looped. We achieve this by inserting just
- // before the song end a jump to the song start. More precisely we abuse
- // a S&M sysex, "maybe_jump" to achieve this effect. We could also
- // use a set_loop sysex, but it's a bit longer, a little more complicated,
- // and has no advantage either.
-
- // First, find the track end
- byte *end = ptr;
- ptr -= size;
- for (; ptr < end; ptr++) {
- if (*ptr == 0xff && *(ptr + 1) == 0x2f)
- break;
- }
- assert(ptr < end);
-
- // Now insert the jump. The jump offset is measured in ticks.
- // We have ppqn/3 ticks before the first note.
-
- const int jump_offset = ppqn / 3;
- memcpy(ptr, "\xf0\x13\x7d\x30\00", 5); ptr += 5; // maybe_jump
- memcpy(ptr, "\x00\x00", 2); ptr += 2; // cmd -> 0 means always jump
- memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4; // track -> there is only one track, 0
- memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // beat -> for now, 1 (first beat)
- // Ticks
- *ptr++ = (byte)((jump_offset >> 12) & 0x0F);
- *ptr++ = (byte)((jump_offset >> 8) & 0x0F);
- *ptr++ = (byte)((jump_offset >> 4) & 0x0F);
- *ptr++ = (byte)(jump_offset & 0x0F);
- memcpy(ptr, "\x00\xf7", 2); ptr += 2; // sysex end marker
- }
- } else {
-
- /* This is a sfx resource. First parse it quickly to find the parallel
- * tracks.
- */
- ptr = writeMIDIHeader(ptr, "ASFX", ppqn, total_size);
-
- byte current_instr[3][14];
- int current_note[3];
- int track_time[3];
- byte *track_data[3];
-
- int track_ctr = 0;
- byte chunk_type = 0;
- int delay, delay2, olddelay;
-
- // Write a tempo change Meta event
- // 473 / 4 Hz, convert to micro seconds.
- dw = 1000000 * ppqn * 4 / 473;
- memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4;
- *ptr++ = (byte)((dw >> 16) & 0xFF);
- *ptr++ = (byte)((dw >> 8) & 0xFF);
- *ptr++ = (byte)(dw & 0xFF);
-
- for (i = 0; i < 3; i++) {
- track_time[i] = -1;
- current_note[i] = -1;
- }
- while (size > 0) {
- assert(track_ctr < 3);
- track_data[track_ctr] = src_ptr;
- track_time[track_ctr] = 0;
- track_ctr++;
- while (size > 0) {
- chunk_type = *(src_ptr);
- if (chunk_type == 1) {
- src_ptr += 15;
- size -= 15;
- } else if (chunk_type == 2) {
- src_ptr += 11;
- size -= 11;
- } else if (chunk_type == 0x80) {
- src_ptr ++;
- size --;
- } else {
- break;
- }
- }
- if (chunk_type == 0xff)
- break;
- src_ptr++;
- }
-
- int curtime = 0;
- for (;;) {
- int mintime = -1;
- ch = -1;
- for (i = 0; i < 3; i++) {
- if (track_time[i] >= 0 &&
- (mintime == -1 || mintime > track_time[i])) {
- mintime = track_time[i];
- ch = i;
- }
- }
- if (mintime < 0)
- break;
-
- src_ptr = track_data[ch];
- chunk_type = *src_ptr;
-
- if (current_note[ch] >= 0) {
- delay = mintime - curtime;
- curtime = mintime;
- ptr = writeVLQ(ptr, delay);
- *ptr++ = 0x80 + ch; // key off channel;
- *ptr++ = current_note[ch];
- *ptr++ = 0;
- current_note[ch] = -1;
- }
-
- switch (chunk_type) {
- case 1:
- /* Instrument definition */
- memcpy(current_instr[ch], src_ptr + 1, 14);
- src_ptr += 15;
- break;
-
- case 2:
- /* tone/parammodulation */
- memcpy(ptr, ADLIB_INSTR_MIDI_HACK,
- sizeof(ADLIB_INSTR_MIDI_HACK));
-
- ptr[5] += ch;
- ptr[28] += ch;
- ptr[92] += ch;
-
- /* flags_1 */
- ptr[30 + 0] = (current_instr[ch][3] >> 4) & 0xf;
- ptr[30 + 1] = current_instr[ch][3] & 0xf;
-
- /* oplvl_1 */
- ptr[30 + 2] = (current_instr[ch][4] >> 4) & 0xf;
- ptr[30 + 3] = current_instr[ch][4] & 0xf;
-
- /* atdec_1 */
- ptr[30 + 4] = ((~current_instr[ch][5]) >> 4) & 0xf;
- ptr[30 + 5] = (~current_instr[ch][5]) & 0xf;
-
- /* sustrel_1 */
- ptr[30 + 6] = ((~current_instr[ch][6]) >> 4) & 0xf;
- ptr[30 + 7] = (~current_instr[ch][6]) & 0xf;
-
- /* waveform_1 */
- ptr[30 + 8] = (current_instr[ch][7] >> 4) & 0xf;
- ptr[30 + 9] = current_instr[ch][7] & 0xf;
-
- /* flags_2 */
- ptr[30 + 10] = (current_instr[ch][8] >> 4) & 0xf;
- ptr[30 + 11] = current_instr[ch][8] & 0xf;
-
- /* oplvl_2 */
- ptr[30 + 12] = ((current_instr[ch][9]) >> 4) & 0xf;
- ptr[30 + 13] = (current_instr[ch][9]) & 0xf;
-
- /* atdec_2 */
- ptr[30 + 14] = ((~current_instr[ch][10]) >> 4) & 0xf;
- ptr[30 + 15] = (~current_instr[ch][10]) & 0xf;
-
- /* sustrel_2 */
- ptr[30 + 16] = ((~current_instr[ch][11]) >> 4) & 0xf;
- ptr[30 + 17] = (~current_instr[ch][11]) & 0xf;
-
- /* waveform_2 */
- ptr[30 + 18] = (current_instr[ch][12] >> 4) & 0xf;
- ptr[30 + 19] = current_instr[ch][12] & 0xf;
-
- /* feedback */
- ptr[30 + 20] = (current_instr[ch][2] >> 4) & 0xf;
- ptr[30 + 21] = current_instr[ch][2] & 0xf;
-
- delay = mintime - curtime;
- curtime = mintime;
-
- {
- delay = convert_extraflags(ptr + 30 + 22, src_ptr + 1);
- delay2 = convert_extraflags(ptr + 30 + 40, src_ptr + 6);
- debugC(DEBUG_SOUND, "delays: %d / %d", delay, delay2);
- if (delay2 >= 0 && delay2 < delay)
- delay = delay2;
- if (delay == -1)
- delay = 0;
- }
-
- /* duration */
- ptr[30 + 58] = 0; // ((delay * 17 / 63) >> 4) & 0xf;
- ptr[30 + 59] = 0; // (delay * 17 / 63) & 0xf;
-
- ptr += sizeof(ADLIB_INSTR_MIDI_HACK);
-
- olddelay = mintime - curtime;
- curtime = mintime;
- ptr = writeVLQ(ptr, olddelay);
-
- {
- int freq = ((current_instr[ch][1] & 3) << 8)
- | current_instr[ch][0];
- if (!freq)
- freq = 0x80;
- freq <<= ((current_instr[ch][1] >> 2) & 7) + 1;
- int note = -11;
- while (freq >= 0x100) {
- note += 12;
- freq >>= 1;
- }
- debugC(DEBUG_SOUND, "Freq: %d (%x) Note: %d", freq, freq, note);
- if (freq < 0x80)
- note = 0;
- else
- note += freq2note[freq - 0x80];
-
- debugC(DEBUG_SOUND, "Note: %d", note);
- if (note <= 0)
- note = 1;
- else if (note > 127)
- note = 127;
-
- // Insert a note on event
- *ptr++ = 0x90 + ch; // key on channel
- *ptr++ = note;
- *ptr++ = 63;
- current_note[ch] = note;
- track_time[ch] = curtime + delay;
- }
- src_ptr += 11;
- break;
-
- case 0x80:
- track_time[ch] = -1;
- src_ptr ++;
- break;
-
- default:
- track_time[ch] = -1;
- }
- track_data[ch] = src_ptr;
- }
- }
-
- // Insert end of song sysex
- memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5;
-}
-
-
-int ScummEngine::readSoundResourceSmallHeader(int type, int idx) {
- uint32 pos, total_size, size, tag;
- uint32 ad_size = 0, ad_offs = 0;
- uint32 ro_size = 0, ro_offs = 0;
- uint32 wa_size = 0, wa_offs = 0;
-
- debug(4, "readSoundResourceSmallHeader(%d)", idx);
-
- if ((_gameId == GID_LOOM) && (_version == 3) && (_platform == Common::kPlatformPC) && VAR(VAR_SOUNDCARD) == 4) {
- // Roland resources in Loom are tagless
- // So we add an RO tag to allow imuse to detect format
- byte *ptr, *src_ptr;
- ro_offs = _fileHandle->pos();
- ro_size = _fileHandle->readUint16LE();
-
- src_ptr = (byte *) calloc(ro_size - 4, 1);
- _fileHandle->seek(ro_offs + 4, SEEK_SET);
- _fileHandle->read(src_ptr, ro_size -4);
-
- ptr = res.createResource(type, idx, ro_size + 2);
- memcpy(ptr, "RO", 2); ptr += 2;
- memcpy(ptr, src_ptr, ro_size - 4); ptr += ro_size - 4;
- return 1;
- } else if (_features & GF_OLD_BUNDLE) {
- wa_offs = _fileHandle->pos();
- wa_size = _fileHandle->readUint16LE();
- _fileHandle->seek(wa_size - 2, SEEK_CUR);
-
- if (!(_platform == Common::kPlatformAtariST || _platform == Common::kPlatformMacintosh)) {
- ad_offs = _fileHandle->pos();
- ad_size = _fileHandle->readUint16LE();
- }
- _fileHandle->seek(4, SEEK_CUR);
- total_size = wa_size + ad_size;
- } else {
- total_size = size = _fileHandle->readUint32LE();
- tag = _fileHandle->readUint16LE();
- debug(4, " tag='%c%c', size=%d", (char) (tag & 0xff),
- (char) ((tag >> 8) & 0xff), size);
-
- if (tag == 0x4F52) { // RO
- ro_offs = _fileHandle->pos();
- ro_size = size;
- } else {
- pos = 6;
- while (pos < total_size) {
- size = _fileHandle->readUint32LE();
- tag = _fileHandle->readUint16LE();
- debug(4, " tag='%c%c', size=%d", (char) (tag & 0xff),
- (char) ((tag >> 8) & 0xff), size);
- pos += size;
-
- // MI1 and Indy3 uses one or more nested SO resources, which contains AD and WA
- // resources.
- if ((tag == 0x4441) && !(ad_offs)) { // AD
- ad_size = size;
- ad_offs = _fileHandle->pos();
- } else if ((tag == 0x4157) && !(wa_offs)) { // WA
- wa_size = size;
- wa_offs = _fileHandle->pos();
- } else { // other AD, WA and nested SO resources
- if (tag == 0x4F53) { // SO
- pos -= size;
- size = 6;
- pos += 6;
- }
- }
- _fileHandle->seek(size - 6, SEEK_CUR);
- }
- }
- }
-
- if ((_musicType == MDT_ADLIB) && ad_offs != 0) {
- // AD resources have a header, instrument definitions and one MIDI track.
- // We build an 'ADL ' resource from that:
- // 8 bytes resource header
- // 16 bytes MDhd header
- // 14 bytes MThd header
- // 8 bytes MTrk header
- // 7 bytes MIDI tempo sysex
- // + some default instruments
- byte *ptr;
- if (_features & GF_OLD_BUNDLE) {
- ad_size -= 4;
- _fileHandle->seek(ad_offs + 4, SEEK_SET);
- } else {
- ad_size -= 6;
- _fileHandle->seek(ad_offs, SEEK_SET);
- }
- ptr = (byte *) calloc(ad_size, 1);
- _fileHandle->read(ptr, ad_size);
- convertADResource(type, idx, ptr, ad_size);
- free(ptr);
- return 1;
- } else if ((_musicType == MDT_PCSPK) && wa_offs != 0) {
- if (_features & GF_OLD_BUNDLE) {
- _fileHandle->seek(wa_offs, SEEK_SET);
- _fileHandle->read(res.createResource(type, idx, wa_size), wa_size);
- } else {
- _fileHandle->seek(wa_offs - 6, SEEK_SET);
- _fileHandle->read(res.createResource(type, idx, wa_size + 6), wa_size + 6);
- }
- return 1;
- } else if (ro_offs != 0) {
- _fileHandle->seek(ro_offs - 2, SEEK_SET);
- _fileHandle->read(res.createResource(type, idx, ro_size - 4), ro_size - 4);
- return 1;
- }
- res.roomoffs[type][idx] = 0xFFFFFFFF;
- return 0;
-}
-
-
-#pragma mark -
-#pragma mark --- Appendable audio stream ---
-#pragma mark -
-
-
-/**
- * Wrapped memory stream.
- */
-template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
-class AppendableMemoryStream : public AppendableAudioStream {
-protected:
- Common::Mutex _mutex;
-
- byte *_bufferStart;
- byte *_bufferEnd;
- byte *_pos;
- byte *_end;
- bool _finalized;
- const int _rate;
-
- inline bool eosIntern() const { return _end == _pos; };
-public:
- AppendableMemoryStream(int rate, uint bufferSize);
- ~AppendableMemoryStream();
- int readBuffer(int16 *buffer, const int numSamples);
-
- bool isStereo() const { return stereo; }
- bool endOfStream() const { return _finalized && eosIntern(); }
- bool endOfData() const { return eosIntern(); }
-
- int getRate() const { return _rate; }
-
- void append(const byte *data, uint32 len);
- void finish() { _finalized = true; }
-};
-
-template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
-AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::AppendableMemoryStream(int rate, uint bufferSize)
- : _finalized(false), _rate(rate) {
-
- // Verify the buffer size is sane
- if (is16Bit && stereo)
- assert((bufferSize & 3) == 0);
- else if (is16Bit || stereo)
- assert((bufferSize & 1) == 0);
-
- _bufferStart = (byte *)malloc(bufferSize);
- _pos = _end = _bufferStart;
- _bufferEnd = _bufferStart + bufferSize;
-}
-
-template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
-AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::~AppendableMemoryStream() {
- free(_bufferStart);
-}
-
-template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
-int AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer, const int numSamples) {
- Common::StackLock lock(_mutex);
-
- int samples = 0;
- while (samples < numSamples && !eosIntern()) {
- // Wrap around?
- if (_pos >= _bufferEnd)
- _pos = _pos - (_bufferEnd - _bufferStart);
-
- const byte *endMarker = (_pos > _end) ? _bufferEnd : _end;
- const int len = MIN(numSamples, samples + (int)(endMarker - _pos) / (is16Bit ? 2 : 1));
- while (samples < len) {
- *buffer++ = READ_ENDIAN_SAMPLE(is16Bit, isUnsigned, _pos, isLE);
- _pos += (is16Bit ? 2 : 1);
- samples++;
- }
- }
-
- return samples;
-}
-
-template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
-void AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::append(const byte *data, uint32 len) {
- Common::StackLock lock(_mutex);
-
- // Verify the buffer size is sane
- if (is16Bit && stereo)
- assert((len & 3) == 0);
- else if (is16Bit || stereo)
- assert((len & 1) == 0);
-
- // Verify that the stream has not yet been finalized (by a call to finish())
- assert(!_finalized);
-
- if (_end + len > _bufferEnd) {
- // Wrap-around case
- uint32 size_to_end_of_buffer = _bufferEnd - _end;
- len -= size_to_end_of_buffer;
- if ((_end < _pos) || (_bufferStart + len >= _pos)) {
- debug(2, "AppendableMemoryStream: buffer overflow (A)");
- return;
- }
- memcpy(_end, data, size_to_end_of_buffer);
- memcpy(_bufferStart, data + size_to_end_of_buffer, len);
- _end = _bufferStart + len;
- } else {
- if ((_end < _pos) && (_end + len >= _pos)) {
- debug(2, "AppendableMemoryStream: buffer overflow (B)");
- return;
- }
- memcpy(_end, data, len);
- _end += len;
- }
-}
-
-
-#define MAKE_WRAPPED(STEREO, UNSIGNED) \
- if (is16Bit) { \
- if (isLE) \
- return new AppendableMemoryStream<STEREO, true, UNSIGNED, true>(rate, len); \
- else \
- return new AppendableMemoryStream<STEREO, true, UNSIGNED, false>(rate, len); \
- } else \
- return new AppendableMemoryStream<STEREO, false, UNSIGNED, false>(rate, len)
-
-AppendableAudioStream *makeAppendableAudioStream(int rate, byte _flags, uint32 len) {
- const bool isStereo = (_flags & Audio::Mixer::FLAG_STEREO) != 0;
- const bool is16Bit = (_flags & Audio::Mixer::FLAG_16BITS) != 0;
- const bool isUnsigned = (_flags & Audio::Mixer::FLAG_UNSIGNED) != 0;
- const bool isLE = (_flags & Audio::Mixer::FLAG_LITTLE_ENDIAN) != 0;
-
- if (isStereo) {
- if (isUnsigned) {
- MAKE_WRAPPED(true, true);
- } else {
- MAKE_WRAPPED(true, false);
- }
- } else {
- if (isUnsigned) {
- MAKE_WRAPPED(false, true);
- } else {
- MAKE_WRAPPED(false, false);
- }
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/sound.h b/scumm/sound.h
deleted file mode 100644
index 0b913fe7e3..0000000000
--- a/scumm/sound.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef SOUND_H
-#define SOUND_H
-
-#include "common/scummsys.h"
-#include "sound/audiostream.h"
-#include "sound/mixer.h"
-#include "scumm/saveload.h"
-
-namespace Common {
- class File;
-}
-
-namespace Scumm {
-
-class ScummEngine;
-class ScummFile;
-
-struct MP3OffsetTable;
-struct SaveLoadEntry;
-
-enum {
- kTalkSoundID = 10000
-};
-
-class Sound : public Serializable {
-#ifdef PALMOS_MODE
-public:
-#else
-protected:
-#endif
- enum SoundMode {
- kVOCMode,
- kMP3Mode,
- kVorbisMode,
- kFlacMode
- };
-
-#ifdef PALMOS_MODE
-protected:
-#endif
- ScummEngine *_vm;
-
- int16 _soundQuePos, _soundQue[0x100];
- int16 _soundQue2Pos;
-
- struct {
- int16 sound;
- int32 offset;
- int16 channel;
- int16 flags;
- } _soundQue2[10];
-
- ScummFile *_sfxFile;
- SoundMode _soundMode;
- MP3OffsetTable *_offsetTable; // For compressed audio
- int _numSoundEffects; // For compressed audio
-
- uint32 _talk_sound_a1, _talk_sound_a2, _talk_sound_b1, _talk_sound_b2;
- byte _talk_sound_mode, _talk_sound_channel;
- bool _mouthSyncMode;
- bool _endOfMouthSync;
- uint16 _mouthSyncTimes[64];
- uint _curSoundPos;
-
- int _overrideFreq;
-
- int16 _currentCDSound;
- int16 _currentMusic;
-
- struct HEMusic{
- int32 id;
- int32 offset;
- int32 size;
- };
- HEMusic *_heMusic;
- int16 _heMusicTracks;
-
-public: // Used by createSound()
- struct {
- int sound;
- int codeOffs;
- int priority;
- int sbngBlock;
- int soundVars[27];
- } _heChannel[8];
-
-public:
- Audio::SoundHandle _talkChannelHandle; // Handle of mixer channel actor is talking on
- Audio::SoundHandle _heSoundChannels[8];
-
- bool _soundsPaused;
- byte _sfxMode;
-
-public:
- Sound(ScummEngine *parent);
- ~Sound();
- void addSoundToQueue(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0);
- void addSoundToQueue2(int sound, int heOffset = 0, int heChannel = 0, int heFlags = 0);
- void processSound();
- void processSoundQueues();
-
- void playSound(int soundID);
- void startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle *handle = NULL);
- void stopTalkSound();
- bool isMouthSyncOff(uint pos);
- int isSoundRunning(int sound) const;
- bool isSoundInUse(int sound) const;
- void stopSound(int sound);
- void stopAllSounds();
- void soundKludge(int *list, int num);
- void talkSound(uint32 a, uint32 b, int mode, int channel = 0);
- void setupSound();
- void pauseSounds(bool pause);
-
- void startCDTimer();
- void stopCDTimer();
-
- void playCDTrack(int track, int numLoops, int startFrame, int duration);
- void stopCD();
- int pollCD() const;
- void updateCD();
- int getCurrentCDSound() const { return _currentCDSound; }
-
- // HE specific
- bool getHEMusicDetails(int id, int &musicOffs, int &musicSize);
- int findFreeSoundChannel();
- int isSoundCodeUsed(int sound);
- int getSoundPos(int sound);
- int getSoundVar(int sound, int var);
- void setSoundVar(int sound, int var, int val);
- void playHESound(int soundID, int heOffset, int heChannel, int heFlags);
- void processSoundCode();
- void processSoundOpcodes(int sound, byte *codePtr, int *soundVars);
- void setOverrideFreq(int freq);
- void setupHEMusicFile();
- void startHETalkSound(uint32 offset);
-
- // Used by the save/load system:
- void saveLoadWithSerializer(Serializer *ser);
-
-protected:
- ScummFile *openSfxFile();
- bool isSfxFinished() const;
- void processSfxQueues();
-
- bool isSoundInQueue(int sound) const;
-};
-
-/**
- * An audio stream to which additional data can be appended on-the-fly.
- * Used by SMUSH and iMuseDigital.
- */
-class AppendableAudioStream : public AudioStream {
-public:
- virtual void append(const byte *data, uint32 len) = 0;
- virtual void finish() = 0;
-};
-
-AppendableAudioStream *makeAppendableAudioStream(int rate, byte _flags, uint32 len);
-
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/sound_he.cpp b/scumm/sound_he.cpp
deleted file mode 100644
index 879e34a99e..0000000000
--- a/scumm/sound_he.cpp
+++ /dev/null
@@ -1,516 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/imuse.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-#include "common/config-manager.h"
-#include "common/timer.h"
-#include "common/util.h"
-
-#include "sound/adpcm.h"
-#include "sound/audiocd.h"
-#include "sound/flac.h"
-#include "sound/mididrv.h"
-#include "sound/mixer.h"
-#include "sound/mp3.h"
-#include "sound/voc.h"
-#include "sound/vorbis.h"
-#include "sound/wave.h"
-
-namespace Scumm {
-
-int Sound::findFreeSoundChannel() {
- int chan, min;
-
- min = _vm->VAR(_vm->VAR_RESERVED_SOUND_CHANNELS);
- if (min == 0) {
- _vm->VAR(_vm->VAR_RESERVED_SOUND_CHANNELS) = 8;
- return 1;
- }
-
- if (min < 8) {
- for (chan = min; chan < ARRAYSIZE(_heChannel); chan++) {
- if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[chan]) == 0)
- return chan;
- }
- } else {
- return 1;
- }
-
- return min;
-}
-
-int Sound::isSoundCodeUsed(int sound) {
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- return _heChannel[chan].sbngBlock;
- } else {
- return 0;
- }
-}
-
-int Sound::getSoundPos(int sound) {
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- int time = _vm->getHETimer(chan + 4) * 11025 / 1000;
- return time;
- } else {
- return 0;
- }
-}
-
-int Sound::getSoundVar(int sound, int var) {
- if (_vm->_heversion >= 90 && var == 26) {
- return isSoundCodeUsed(sound);
- }
-
- checkRange(25, 0, var, "Illegal sound variable %d");
-
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- debug(5, "getSoundVar: sound %d var %d result %d", sound, var, _heChannel[chan].soundVars[var]);
- return _heChannel[chan].soundVars[var];
- } else {
- return 0;
- }
-}
-
-void Sound::setSoundVar(int sound, int var, int val) {
- checkRange(25, 0, var, "Illegal sound variable %d");
-
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- debug(5, "setSoundVar: sound %d var %d val %d", sound, var, val);
- _heChannel[chan].soundVars[var] = val;
- }
-}
-
-void Sound::setOverrideFreq(int freq) {
- _overrideFreq = freq;
-}
-
-void Sound::setupHEMusicFile() {
- int i, total_size;
- char buf[32], buf1[128];
- Common::File musicFile;
-
- sprintf(buf, "%s.he4", _vm->getBaseName());
-
- if (_vm->_substResFileNameIndex > 0) {
- _vm->generateSubstResFileName(buf, buf1, sizeof(buf1));
- strcpy(buf, buf1);
- }
- if (musicFile.open(buf) == true) {
- musicFile.seek(4, SEEK_SET);
- total_size = musicFile.readUint32BE();
- musicFile.seek(16, SEEK_SET);
- _heMusicTracks = musicFile.readUint32LE();
- debug(5, "Total music tracks %d", _heMusicTracks);
-
- int musicStart = (_vm->_heversion >= 80) ? 56 : 20;
- musicFile.seek(musicStart, SEEK_SET);
-
- _heMusic = (HEMusic *)malloc((_heMusicTracks + 1) * sizeof(HEMusic));
- for (i = 0; i < _heMusicTracks; i++) {
- _heMusic[i].id = musicFile.readUint32LE();
- _heMusic[i].offset = musicFile.readUint32LE();
- _heMusic[i].size = musicFile.readUint32LE();
-
- if (_vm->_heversion >= 80) {
- musicFile.seek(+9, SEEK_CUR);
- } else {
- musicFile.seek(+13, SEEK_CUR);
- }
- }
-
- musicFile.close();
- }
-}
-
-bool Sound::getHEMusicDetails(int id, int &musicOffs, int &musicSize) {
- int i;
-
- for (i = 0; i < _heMusicTracks; i++) {
- if (_heMusic[i].id == id) {
- musicOffs = _heMusic[i].offset;
- musicSize = _heMusic[i].size;
- return 1;
- }
- }
-
- return 0;
-}
-
-void Sound::processSoundCode() {
- byte *codePtr;
- int chan, tmr, size, time;
-
- for (chan = 0; chan < ARRAYSIZE(_heChannel); chan++) {
- if (_heChannel[chan].sound == 0) {
- continue;
- }
-
- if (_heChannel[chan].codeOffs == -1) {
- continue;
- }
-
- tmr = _vm->getHETimer(chan + 4) * 11025 / 1000;
- tmr += _vm->VAR(_vm->VAR_SOUNDCODE_TMR);
- if (tmr < 0)
- tmr = 0;
-
- if (_heChannel[chan].sound > _vm->_numSounds) {
- codePtr = _vm->getResourceAddress(rtSpoolBuffer, chan);
- } else {
- codePtr = _vm->getResourceAddress(rtSound, _heChannel[chan].sound);
- }
- assert(codePtr);
- codePtr += _heChannel[chan].codeOffs;
-
- while(1) {
- size = READ_LE_UINT16(codePtr);
- time = READ_LE_UINT32(codePtr + 2);
-
- if (size == 0) {
- _heChannel[chan].codeOffs = -1;
- break;
- }
-
- debug(5, "Channel %d Timer %d Time %d", chan, tmr, time);
- if (time >= tmr)
- break;
-
- processSoundOpcodes(_heChannel[chan].sound, codePtr + 6, _heChannel[chan].soundVars);
-
- codePtr += size;
- _heChannel[chan].codeOffs += size;
- }
- }
-}
-
-void Sound::processSoundOpcodes(int sound, byte *codePtr, int *soundVars) {
- int arg, opcode, var, val;
-
- while(READ_LE_UINT16(codePtr) != 0) {
- codePtr += 2;
- opcode = READ_LE_UINT16(codePtr); codePtr += 2;
- opcode = (opcode & 0xFFF) >> 4;
- arg = opcode & 3;
- opcode &= ~3;
- debug(5, "processSoundOpcodes: sound %d opcode %d", sound, opcode);
- switch (opcode) {
- case 0: // Continue
- break;
- case 16: // Set talk state
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- setSoundVar(sound, 19, val);
- break;
- case 32: // Set var
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- setSoundVar(sound, var, val);
- break;
- case 48: // Add
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) + val;
- setSoundVar(sound, var, val);
- break;
- case 56: // Subtract
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) - val;
- setSoundVar(sound, var, val);
- break;
- case 64: // Multiple
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) * val;
- setSoundVar(sound, var, val);
- break;
- case 80: // Divide
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) / val;
- setSoundVar(sound, var, val);
- break;
- case 96: // Increment
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = getSoundVar(sound, var) + 1;
- setSoundVar(sound, var, val);
- break;
- case 104: // Decrement
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = getSoundVar(sound, var) - 1;
- setSoundVar(sound, var, val);
- break;
- default:
- error("Illegal sound %d opcode %d", sound, opcode);
- }
- }
-}
-
-void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
- byte *ptr, *spoolPtr;
- char *sound;
- int size = -1;
- int priority, rate;
- byte flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
-
- if (heChannel == -1)
- heChannel = (_vm->VAR_RESERVED_SOUND_CHANNELS != 0xFF) ? findFreeSoundChannel() : 1;
-
- debug(5,"playHESound: soundID %d heOffset %d heChannel %d heFlags %d", soundID, heOffset, heChannel, heFlags);
-
- if (soundID >= 10000) {
- // Special codes, used in pjgames
- return;
- }
-
- if (soundID > _vm->_numSounds) {
- int music_offs;
- char buf[32], buf1[128];
- Common::File musicFile;
-
- sprintf(buf, "%s.he4", _vm->getBaseName());
-
- if (_vm->_substResFileNameIndex > 0) {
- _vm->generateSubstResFileName(buf, buf1, sizeof(buf1));
- strcpy(buf, buf1);
- }
- if (musicFile.open(buf) == false) {
- warning("playSound: Can't open music file %s", buf);
- return;
- }
- if (!getHEMusicDetails(soundID, music_offs, size)) {
- debug(0, "playSound: musicID %d not found", soundID);
- return;
- }
-
- musicFile.seek(music_offs, SEEK_SET);
-
- if (_vm->_heversion == 70) {
- spoolPtr = (byte *)malloc(size);
- musicFile.read(spoolPtr, size);
- } else {
- spoolPtr = _vm->res.createResource(rtSpoolBuffer, heChannel, size);
- assert(spoolPtr);
- musicFile.read(spoolPtr, size);
- }
- musicFile.close();
-
- if (_vm->_heversion == 70) {
- _vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
- _vm->_mixer->playRaw(&_heSoundChannels[heChannel], spoolPtr, size, 11025, flags, soundID);
- return;
- }
- }
-
- if (soundID > _vm->_numSounds) {
- ptr = _vm->getResourceAddress(rtSpoolBuffer, heChannel);
- } else {
- ptr = _vm->getResourceAddress(rtSound, soundID);
- }
-
- if (!ptr) {
- return;
- }
-
- // TODO: Extra sound flags
- if (heFlags & 1) {
- flags |= Audio::Mixer::FLAG_LOOP;
- }
-
- // Support for sound in later Backyard sports games
- if (READ_UINT32(ptr) == MKID('RIFF') || READ_UINT32(ptr) == MKID('WSOU')) {
- uint16 type;
- int blockAlign;
-
- if (READ_UINT32(ptr) == MKID('WSOU'))
- ptr += 8;
-
- size = READ_LE_UINT32(ptr + 4);
- Common::MemoryReadStream stream(ptr, size);
-
- if (!loadWAVFromStream(stream, size, rate, flags, &type, &blockAlign)) {
- error("playSound: Not a valid WAV file");
- }
-
- if (type == 17) {
- AudioStream *voxStream = new ADPCMInputStream(&stream, size, kADPCMIma, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
-
- sound = (char *)malloc(size * 4);
- size = voxStream->readBuffer((int16*)sound, size * 2);
- size *= 2; // 16bits.
- delete voxStream;
- } else {
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + stream.pos(), size);
- }
- _vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
- _vm->_mixer->playRaw(&_heSoundChannels[heChannel], sound, size, rate, flags, soundID);
- }
- // Support for sound in Humongous Entertainment games
- else if (READ_UINT32(ptr) == MKID('DIGI') || READ_UINT32(ptr) == MKID('TALK')) {
- byte *sndPtr = ptr;
-
- priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18);
- rate = READ_LE_UINT16(ptr + 22);
- ptr += 8 + READ_BE_UINT32(ptr + 12);
-
- if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) {
- int curSnd = _heChannel[heChannel].sound;
- if (curSnd == 1 && soundID != 1)
- return;
- if (curSnd != 0 && curSnd != 1 && soundID != 1 && _heChannel[heChannel].priority > priority)
- return;
- }
-
- int codeOffs = -1;
- if (READ_UINT32(ptr) == MKID('SBNG')) {
- codeOffs = ptr - sndPtr + 8;
- ptr += READ_BE_UINT32(ptr + 4);
- }
-
- assert(READ_UINT32(ptr) == MKID('SDAT'));
- size = READ_BE_UINT32(ptr+4) - 8;
- if (heOffset < 0 || heOffset > size) {
- // Occurs when making fireworks in puttmoon
- debug(0, "playSound: Invalid sound offset (offset %d, size %d) in sound %d", heOffset, size, soundID);
- heOffset = 0;
- }
- size -= heOffset;
-
- if (_overrideFreq) {
- // Used by the piano in Fatty Bear's Birthday Surprise
- rate = _overrideFreq;
- _overrideFreq = 0;
- }
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + heOffset + 8, size);
- _vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
- _vm->_mixer->playRaw(&_heSoundChannels[heChannel], sound, size, rate, flags, soundID);
-
- _vm->setHETimer(heChannel + 4);
- _heChannel[heChannel].sound = soundID;
- _heChannel[heChannel].priority = priority;
- _heChannel[heChannel].sbngBlock = (codeOffs != -1) ? 1 : 0;
- _heChannel[heChannel].codeOffs = codeOffs;
- memset(_heChannel[heChannel].soundVars, 0, sizeof(_heChannel[heChannel].soundVars));
- }
- // Support for PCM music in 3DO versions of Humongous Entertainment games
- else if (READ_UINT32(ptr) == MKID('MRAW')) {
- priority = *(ptr + 18);
- rate = READ_LE_UINT16(ptr + 22);
- ptr += 8 + READ_BE_UINT32(ptr+12);
-
- assert(READ_UINT32(ptr) == MKID('SDAT'));
- size = READ_BE_UINT32(ptr+4) - 8;
-
- flags = Audio::Mixer::FLAG_AUTOFREE;
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + 8, size);
- _vm->_mixer->stopID(_currentMusic);
- _currentMusic = soundID;
- _vm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
- }
- else if (READ_UINT32(ptr) == MKID('MIDI')) {
- if (_vm->_musicEngine) {
- _vm->_musicEngine->startSound(soundID);
- }
- }
-}
-
-void Sound::startHETalkSound(uint32 offset) {
- byte *ptr;
- int32 size;
-
- if (ConfMan.getBool("speech_mute"))
- return;
-
- if (!_sfxFile->isOpen()) {
- error("startHETalkSound: Speech file is not open");
- return;
- }
-
- _sfxMode |= 2;
- _vm->res.nukeResource(rtSound, 1);
-
- _sfxFile->seek(offset + 4, SEEK_SET);
- size = _sfxFile->readUint32BE();
- _sfxFile->seek(offset, SEEK_SET);
-
- _vm->res.createResource(rtSound, 1, size);
- ptr = _vm->getResourceAddress(rtSound, 1);
- _sfxFile->read(ptr, size);
-
- int channel = (_vm->VAR_TALK_CHANNEL != 0xFF) ? _vm->VAR(_vm->VAR_TALK_CHANNEL) : 0;
- addSoundToQueue2(1, 0, channel, 0);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/sprite_he.cpp b/scumm/sprite_he.cpp
deleted file mode 100644
index a6065eb7be..0000000000
--- a/scumm/sprite_he.cpp
+++ /dev/null
@@ -1,1440 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/intern_he.h"
-#include "scumm/resource.h"
-#include "scumm/saveload.h"
-#include "scumm/scumm.h"
-#include "scumm/sprite_he.h"
-#include "scumm/usage_bits.h"
-#include "scumm/util.h"
-#include "scumm/wiz_he.h"
-
-namespace Scumm {
-
-Sprite::Sprite(ScummEngine_v90he *vm) : _vm(vm) {
-}
-
-Sprite::~Sprite() {
- free(_spriteGroups);
- free(_spriteTable);
- free(_activeSpritesTable);
-}
-
-void ScummEngine_v90he::allocateArrays() {
- ScummEngine::allocateArrays();
- _sprite->allocTables(_numSprites, MAX(64, _numSprites / 4), 64);
-}
-
-void Sprite::getSpriteBounds(int spriteId, bool checkGroup, Common::Rect &bound) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
- int32 spr_wiz_x, spr_wiz_y;
- int angle, scale, x1, y1;
- int32 w, h;
-
- SpriteInfo *spi = &_spriteTable[spriteId];
-
- _vm->_wiz->getWizImageSpot(spi->image, spi->imageState, spr_wiz_x, spr_wiz_y);
- if (checkGroup && spi->group) {
- SpriteGroup *spg = &_spriteGroups[spi->group];
-
- if (spg->scaling) {
- x1 = spi->tx * spg->scale_x_ratio_mul / spg->scale_x_ratio_div - spr_wiz_x + spg->tx;
- y1 = spi->ty * spg->scale_y_ratio_mul / spg->scale_y_ratio_div - spr_wiz_y + spg->ty;
- } else {
- x1 = spi->tx - spr_wiz_x + spg->tx;
- y1 = spi->ty - spr_wiz_y + spg->ty;
- }
- } else {
- x1 = spi->tx - spr_wiz_x;
- y1 = spi->ty - spr_wiz_y;
- }
-
- if (spi->image) {
- angle = spi->angle;
- scale = spi->scale;
- _vm->_wiz->getWizImageDim(spi->image, spi->imageState, w, h);
- if (spi->flags & (kSFScaled | kSFRotated)) {
- Common::Point pts[4];
- _vm->_wiz->polygonTransform(spi->image, spi->imageState, x1, y1, angle, scale, pts);
- _vm->_wiz->polygonCalcBoundBox(pts, 4, bound);
- } else {
- bound.left = x1;
- bound.top = y1;
- bound.right = x1 + w;
- bound.bottom = y1 + h;
- }
- } else {
- bound.left = 1234;
- bound.top = 1234;
- bound.right = -1234;
- bound.bottom = -1234;
- }
-}
-
-//
-// spriteInfoGet functions
-//
-int Sprite::findSpriteWithClassOf(int x_pos, int y_pos, int spriteGroupId, int type, int num, int *args) {
- debug(2, "findSprite: x %d, y %d, spriteGroup %d, type %d, num %d", x_pos, y_pos, spriteGroupId, type, num);
- Common::Point pos[1];
- bool cond;
- int code, classId;
-
- for (int i = (_numSpritesToProcess - 1); i >= 0; i--) {
- SpriteInfo *spi = _activeSpritesTable[i];
- if (!spi->curImage)
- continue;
-
- if (spriteGroupId && spi->group != spriteGroupId)
- continue;
-
- cond = true;
- for (int j = 0; j < num; j++) {
- code = classId = args[j];
- classId &= 0x7F;
- checkRange(32, 1, classId, "class %d out of range in statement");
- if (code & 0x80) {
- if (!(spi->classFlags & (1 << (classId - 1))))
- cond = 0;
- } else {
- if ((spi->classFlags & (1 << (classId - 1))))
- cond = 0;
- }
- }
- if (!cond)
- continue;
-
- if (type) {
- if (spi->bbox.left > spi->bbox.right)
- continue;
- if (spi->bbox.top > spi->bbox.bottom)
- continue;
- if (spi->bbox.left > x_pos)
- continue;
- if (spi->bbox.top > y_pos)
- continue;
- if (spi->bbox.right < x_pos)
- continue;
- if (spi->bbox.bottom < y_pos)
- continue;
- return spi->id;
- } else {
- int image, imageState, angle, scale;
- int32 w, h;
-
- image = spi->curImage;
- if (spi->maskImage) {
- int32 x1, x2, y1, y2;
-
- imageState = spi->curImageState % _vm->_wiz->getWizImageStates(spi->maskImage);
-
- pos[0].x = x_pos - spi->pos.x;
- pos[0].y = y_pos - spi->pos.y;
-
- _vm->_wiz->getWizImageSpot(spi->curImage, imageState, x1, y1);
- _vm->_wiz->getWizImageSpot(spi->maskImage, imageState, x2, y2);
-
- pos[0].x += (x2 - x1);
- pos[0].y += (y2 - y1);
- } else {
- if (spi->bbox.left > spi->bbox.right)
- continue;
- if (spi->bbox.top > spi->bbox.bottom)
- continue;
- if (spi->bbox.left > x_pos)
- continue;
- if (spi->bbox.top > y_pos)
- continue;
- if (spi->bbox.right < x_pos)
- continue;
- if (spi->bbox.bottom < y_pos)
- continue;
-
- pos[0].x = x_pos - spi->pos.x;
- pos[0].y = y_pos - spi->pos.y;
- imageState = spi->curImageState;
- }
-
- angle = spi->curAngle;
- scale = spi->curScale;
- if ((spi->flags & kSFScaled) || (spi->flags & kSFRotated)) {
- if (spi->flags & kSFScaled && scale) {
- pos[0].x = pos[0].x * 256 / scale;
- pos[0].y = pos[0].y * 256 / scale;
- }
- if (spi->flags & kSFRotated && angle) {
- angle = (360 - angle) % 360;
- _vm->_wiz->polygonRotatePoints(pos, 1, angle);
- }
-
- _vm->_wiz->getWizImageDim(image, imageState, w, h);
- pos[0].x += w / 2;
- pos[0].y += h / 2;
- }
-
- if (_vm->_wiz->isWizPixelNonTransparent(image, imageState, pos[0].x, pos[0].y, spi->curImgFlags))
- return spi->id;
- }
- }
-
- return 0;
-}
-
-int Sprite::getSpriteClass(int spriteId, int num, int *args) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
- int code, classId;
-
- if (num == 0)
- return _spriteTable[spriteId].classFlags;
-
- for (int i = 0; i < num; i++) {
- code = classId = args[i];
- classId &= 0x7F;
- checkRange(32, 1, classId, "class %d out of range in statement");
- if (code & 0x80) {
- if (!(_spriteTable[spriteId].classFlags & (1 << (classId - 1))))
- return 0;
- } else {
- if ((_spriteTable[spriteId].classFlags & (1 << (classId - 1))))
- return 0;
- }
- }
-
- return 1;
-}
-
-int Sprite::getSpriteFlagDoubleBuffered(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFDoubleBuffered) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagYFlipped(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFYFlipped) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagXFlipped(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFXFlipped) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagActive(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFActive) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagRemapPalette(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFRemapPalette) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagAutoAnim(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFAutoAnim) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagUpdateType(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFMarkDirty) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteFlagEraseType(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return ((_spriteTable[spriteId].flags & kSFImageless) != 0) ? 1 : 0;
-}
-
-int Sprite::getSpriteImage(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].image;
-}
-
-int Sprite::getSpriteImageState(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].imageState;
-}
-
-int Sprite::getSpriteGroup(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].group;
-}
-
-int Sprite::getSpritePalette(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].palette;
-}
-
-int Sprite::getSpritePriority(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].priority;
-}
-
-int Sprite::getSpriteDisplayX(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].group)
- return _spriteTable[spriteId].tx + _spriteGroups[_spriteTable[spriteId].group].tx;
- else
- return _spriteTable[spriteId].tx;
-}
-
-int Sprite::getSpriteDisplayY(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].group)
- return _spriteTable[spriteId].ty + _spriteGroups[_spriteTable[spriteId].group].ty;
- else
- return _spriteTable[spriteId].ty;
-}
-
-int Sprite::getSpriteUserValue(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].userValue;
-}
-
-int Sprite::getSpriteShadow(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].shadow;
-}
-
-int Sprite::getSpriteImageStateCount(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].imageStateCount;
-}
-
-int Sprite::getSpriteScale(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].scale;
-}
-
-int Sprite::getSpriteAnimSpeed(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].animSpeed;
-}
-
-int Sprite::getSpriteSourceImage(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].sourceImage;
-}
-
-int Sprite::getSpriteMaskImage(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- return _spriteTable[spriteId].maskImage;
-}
-
-int Sprite::getSpriteGeneralProperty(int spriteId, int type) {
- debug(0, "getSpriteGeneralProperty: spriteId %d type 0x%x", spriteId, type);
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- // XXX U32 related check
-
- switch(type) {
- case 0x7B:
- return _spriteTable[spriteId].imgFlags;
- case 0x7D:
- return _spriteTable[spriteId].field_90;
- case 0x7E:
- return _spriteTable[spriteId].animProgress;
- default:
- error("getSpriteGeneralProperty: Invalid type %d", type);
- }
-}
-
-void Sprite::getSpriteImageDim(int spriteId, int32 &w, int32 &h) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].image) {
- _vm->_wiz->getWizImageDim(_spriteTable[spriteId].image, _spriteTable[spriteId].imageState, w, h);
- } else {
- w = 0;
- h = 0;
- }
-}
-
-void Sprite::getSpritePosition(int spriteId, int32 &tx, int32 &ty) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- tx = _spriteTable[spriteId].tx;
- ty = _spriteTable[spriteId].ty;
-}
-
-void Sprite::getSpriteDist(int spriteId, int32 &dx, int32 &dy) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- dx = _spriteTable[spriteId].dx;
- dy = _spriteTable[spriteId].dy;
-}
-
-//
-// spriteGroupGet functions
-//
-int ScummEngine_v90he::getGroupSpriteArray(int spriteGroupId) {
- int i, numSprites = 0;
-
- checkRange(_sprite->_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (i = (_sprite->_varNumSprites - 1); i > 0; i--) {
- if (_sprite->_spriteTable[i].group == spriteGroupId)
- numSprites++;
- }
-
- if (!numSprites)
- return 0;
-
- writeVar(0, 0);
- defineArray(0, kDwordArray, 0, 0, 0, numSprites);
- writeArray(0, 0, 0, numSprites);
-
- numSprites = 1;
- for (i = (_sprite->_varNumSprites - 1); i > 0; i--) {
- if (_sprite->_spriteTable[i].group == spriteGroupId) {
- writeArray(0, 0, numSprites, i);
- numSprites++;
- }
- }
-
- return readVar(0);
-}
-
-int Sprite::getGroupPriority(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- return _spriteGroups[spriteGroupId].priority;
-}
-
-int Sprite::getGroupDstResNum(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- return _spriteGroups[spriteGroupId].image;
-}
-
-int Sprite::getGroupXMul(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- return _spriteGroups[spriteGroupId].scale_x_ratio_mul;
-}
-
-int Sprite::getGroupXDiv(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- return _spriteGroups[spriteGroupId].scale_x_ratio_div;
-}
-
-int Sprite::getGroupYMul(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- return _spriteGroups[spriteGroupId].scale_y_ratio_mul;
-}
-
-int Sprite::getGroupYDiv(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- return _spriteGroups[spriteGroupId].scale_y_ratio_div;
-}
-
-void Sprite::getGroupPosition(int spriteGroupId, int32 &tx, int32 &ty) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- tx = _spriteGroups[spriteGroupId].tx;
- ty = _spriteGroups[spriteGroupId].ty;
-}
-
-//
-// spriteInfoSet functions
-//
-void Sprite::setSpritePalette(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].palette != value) {
- _spriteTable[spriteId].palette = value;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- }
-}
-
-void Sprite::setSpriteSourceImage(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].sourceImage != value) {
- _spriteTable[spriteId].sourceImage = value;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- }
-}
-
-void Sprite::setSpriteMaskImage(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].maskImage = value;
-}
-
-void Sprite::setSpriteImageState(int spriteId, int state) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].image) {
- int imageStateCount = _spriteTable[spriteId].imageStateCount - 1;
- state = MAX(0, state);
- state = MIN(state, imageStateCount);
-
- if (_spriteTable[spriteId].imageState != state) {
- _spriteTable[spriteId].imageState = state;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- }
- }
-}
-
-void Sprite::setSpritePosition(int spriteId, int tx, int ty) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (_spriteTable[spriteId].tx != tx || _spriteTable[spriteId].ty != ty) {
- _spriteTable[spriteId].tx = tx;
- _spriteTable[spriteId].ty = ty;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- }
-}
-
-void Sprite::setSpriteGroup(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
- checkRange(_varNumSpriteGroups, 0, value, "Invalid sprite group %d");
-
- _spriteTable[spriteId].group = value;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteDist(int spriteId, int value1, int value2) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].dx = value1;
- _spriteTable[spriteId].dy = value2;
-}
-
-void Sprite::setSpriteShadow(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].shadow = value;
- if (_spriteTable[spriteId].image)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteUserValue(int spriteId, int value1, int value2) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].userValue = value2;
-}
-
-void Sprite::setSpritePriority(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].priority = value;
-}
-
-void Sprite::moveSprite(int spriteId, int value1, int value2) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].tx += value1;
- _spriteTable[spriteId].ty += value2;
-
- if (value1 || value2)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteScale(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].flags |= kSFScaled;
-
- if (_spriteTable[spriteId].scale != value) {
- _spriteTable[spriteId].scale = value;
-
- if (_spriteTable[spriteId].image)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- }
-}
-
-void Sprite::setSpriteAngle(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].flags |= kSFRotated;
-
- if (_spriteTable[spriteId].angle != value) {
- _spriteTable[spriteId].angle = value;
-
- if (_spriteTable[spriteId].image)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- }
-}
-
-void Sprite::setSpriteFlagDoubleBuffered(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- int oldFlags = _spriteTable[spriteId].flags;
- if (value)
- _spriteTable[spriteId].flags |= kSFDoubleBuffered;
- else
- _spriteTable[spriteId].flags &= ~kSFDoubleBuffered;
-
- if (_spriteTable[spriteId].image && _spriteTable[spriteId].flags != oldFlags)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteFlagYFlipped(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- int oldFlags = _spriteTable[spriteId].flags;
- if (value)
- _spriteTable[spriteId].flags |= kSFYFlipped;
- else
- _spriteTable[spriteId].flags &= ~kSFYFlipped;
-
- if (_spriteTable[spriteId].image && _spriteTable[spriteId].flags != oldFlags)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteFlagXFlipped(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- int oldFlags = _spriteTable[spriteId].flags;
- if (value)
- _spriteTable[spriteId].flags |= kSFXFlipped;
- else
- _spriteTable[spriteId].flags &= ~kSFXFlipped;
-
- if (_spriteTable[spriteId].image && _spriteTable[spriteId].flags != oldFlags)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteFlagActive(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (value)
- _spriteTable[spriteId].flags |= kSFActive;
- else
- _spriteTable[spriteId].flags &= ~kSFActive;
-}
-
-void Sprite::setSpriteFlagRemapPalette(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- int oldFlags = _spriteTable[spriteId].flags;
- if (value)
- _spriteTable[spriteId].flags |= kSFRemapPalette;
- else
- _spriteTable[spriteId].flags &= ~kSFRemapPalette;
-
- if (_spriteTable[spriteId].image && _spriteTable[spriteId].flags != oldFlags)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
-}
-
-void Sprite::setSpriteFlagAutoAnim(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- if (value)
- _spriteTable[spriteId].flags |= kSFAutoAnim;
- else
- _spriteTable[spriteId].flags &= ~kSFAutoAnim;
-}
-
-void Sprite::setSpriteFlagUpdateType(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- switch(value) {
- case 2:
- _spriteTable[spriteId].flags &= ~(kSFMarkDirty);
- _spriteTable[spriteId].flags |= kSFBlitDirectly;
- break;
- case 1:
- _spriteTable[spriteId].flags |= kSFMarkDirty | kSFBlitDirectly;
- break;
- case 0:
- _spriteTable[spriteId].flags &= ~(kSFMarkDirty | kSFBlitDirectly);
- break;
- default:
- error("setSpriteFlagUpdateType: Invalid value %d", value);
- }
-}
-
-void Sprite::setSpriteFlagEraseType(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- // Note that condition is inverted
- if (!value)
- _spriteTable[spriteId].flags |= kSFImageless;
- else
- _spriteTable[spriteId].flags &= ~kSFImageless;
-}
-
-void Sprite::setSpriteAnimSpeed(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].animSpeed = value;
- _spriteTable[spriteId].animProgress = value;
-}
-
-void Sprite::setSpriteSetClass(int spriteId, int classId, int toggle) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
- checkRange(32, 1, classId, "class %d out of range in statement");
-
- if (toggle) {
- _spriteTable[spriteId].classFlags |= (1 << (classId - 1));
- } else {
- _spriteTable[spriteId].classFlags &= ~(1 << (classId - 1));
- }
-}
-
-void Sprite::setSpriteResetClass(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].classFlags = 0;
-}
-
-void Sprite::setSpriteField84(int spriteId, int value) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].field_84 = value;
-}
-
-void Sprite::setSpriteGeneralProperty(int spriteId, int type, int value) {
- debug(0, "setSpriteGeneralProperty: spriteId %d type 0x%x", spriteId, type);
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
- int32 delay;
-
- // XXX U32 related check
-
- switch(type) {
- case 0x7B:
- _spriteTable[spriteId].imgFlags = value;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- break;
- case 0x7D:
- _spriteTable[spriteId].field_90 = value;
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- break;
- case 0x7E:
- delay = MAX(0, value);
- delay = MIN(delay, _spriteTable[spriteId].animSpeed);
-
- _spriteTable[spriteId].animProgress = delay;
- break;
- default:
- error("setSpriteGeneralProperty: Invalid value %d", type);
- }
-}
-
-void Sprite::resetSprite(int spriteId) {
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- _spriteTable[spriteId].angle = 0;
- _spriteTable[spriteId].scale = 0;
-
- setSpriteImage(spriteId, 0);
-
- _spriteTable[spriteId].shadow = 0;
- _spriteTable[spriteId].tx = 0;
- _spriteTable[spriteId].ty = 0;
-
- _spriteTable[spriteId].flags &= ~(kSFYFlipped | kSFXFlipped);
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- _spriteTable[spriteId].dx = 0;
- _spriteTable[spriteId].dy = 0;
- _spriteTable[spriteId].userValue = 0;
- _spriteTable[spriteId].group = 0;
- _spriteTable[spriteId].animSpeed = 0;
- _spriteTable[spriteId].animProgress = 0;
- _spriteTable[spriteId].classFlags = 0;
- _spriteTable[spriteId].palette = 0;
- _spriteTable[spriteId].sourceImage = 0;
- _spriteTable[spriteId].maskImage = 0;
- _spriteTable[spriteId].priority = 0;
- _spriteTable[spriteId].field_84 = 0;
- _spriteTable[spriteId].imgFlags = 0;
- _spriteTable[spriteId].field_90 = 0;
-}
-
-void Sprite::setSpriteImage(int spriteId, int imageNum) {
- int origResId, origResWizStates;
-
- checkRange(_varNumSprites, 1, spriteId, "Invalid sprite %d");
-
- origResId = _spriteTable[spriteId].image;
- origResWizStates = _spriteTable[spriteId].imageStateCount;
-
- _spriteTable[spriteId].image = imageNum;
- _spriteTable[spriteId].field_74 = 0;
- _spriteTable[spriteId].imageState = 0;
-
- if (_spriteTable[spriteId].image) {
- _spriteTable[spriteId].imageStateCount = _vm->_wiz->getWizImageStates(_spriteTable[spriteId].image);
- _spriteTable[spriteId].flags |= kSFActive | kSFAutoAnim | kSFMarkDirty | kSFBlitDirectly;
-
- if (_spriteTable[spriteId].image != origResId || _spriteTable[spriteId].imageStateCount != origResWizStates)
- _spriteTable[spriteId].flags |= kSFChanged | kSFNeedRedraw;
- } else {
- if (_spriteTable[spriteId].flags & kSFImageless)
- _spriteTable[spriteId].flags = 0;
- else
- _spriteTable[spriteId].flags = kSFChanged | kSFBlitDirectly;
- _spriteTable[spriteId].curImage = 0;
- _spriteTable[spriteId].curImageState = 0;
- _spriteTable[spriteId].imageStateCount = 0;
- }
-}
-
-//
-// spriteGroupSet functions
-//
-void Sprite::redrawSpriteGroup(int spriteGroupId) {
- for (int i = 0; i < _numSpritesToProcess; ++i) {
- SpriteInfo *spi = _activeSpritesTable[i];
- if (spi->group == spriteGroupId) {
- spi->flags |= kSFChanged | kSFNeedRedraw;
- }
- }
-}
-
-void Sprite::moveGroupMembers(int spriteGroupId, int value1, int value2) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId) {
- _spriteTable[i].tx += value1;
- _spriteTable[i].ty += value2;
-
- if (value1 || value2)
- _spriteTable[i].flags |= kSFChanged | kSFNeedRedraw;
- }
- }
-}
-
-void Sprite::setGroupMembersPriority(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId)
- _spriteTable[i].priority = value;
- }
-}
-
-void Sprite::setGroupMembersGroup(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId) {
- _spriteTable[i].group = value;
- _spriteTable[i].flags |= kSFChanged | kSFNeedRedraw;
- }
- }
-}
-
-void Sprite::setGroupMembersUpdateType(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId)
- setSpriteFlagUpdateType(i, value);
- }
-}
-
-void Sprite::setGroupMembersResetSprite(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId)
- resetSprite(i);
- }
-}
-
-void Sprite::setGroupMembersAnimationSpeed(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId) {
- _spriteTable[i].animSpeed = value;
- _spriteTable[i].animProgress = value;
- }
- }
-}
-
-void Sprite::setGroupMembersAutoAnimFlag(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId) {
- if (value)
- _spriteTable[i].flags |= kSFAutoAnim;
- else
- _spriteTable[i].flags &= ~kSFAutoAnim;
- }
- }
-}
-
-void Sprite::setGroupMembersShadow(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- for (int i = 1; i < _varNumSprites; i++) {
- if (_spriteTable[i].group == spriteGroupId) {
- _spriteTable[i].shadow = value;
- if (_spriteTable[i].image)
- _spriteTable[i].flags |= kSFChanged | kSFNeedRedraw;
- }
- }
-}
-
-void Sprite::setGroupBounds(int spriteGroupId, int x1, int y1, int x2, int y2) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- _spriteGroups[spriteGroupId].flags |= kSGFClipBox;
- _spriteGroups[spriteGroupId].bbox.left = x1;
- _spriteGroups[spriteGroupId].bbox.top = y1;
- _spriteGroups[spriteGroupId].bbox.right = x2;
- _spriteGroups[spriteGroupId].bbox.bottom = y2;
-
- redrawSpriteGroup(spriteGroupId);
-}
-
-void Sprite::setGroupPriority(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (_spriteGroups[spriteGroupId].priority != value) {
- _spriteGroups[spriteGroupId].priority = value;
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::setGroupPosition(int spriteGroupId, int value1, int value2) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (_spriteGroups[spriteGroupId].tx != value1 || _spriteGroups[spriteGroupId].ty != value2) {
- _spriteGroups[spriteGroupId].tx = value1;
- _spriteGroups[spriteGroupId].ty = value2;
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::moveGroup(int spriteGroupId, int value1, int value2) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (value1 || value2) {
- _spriteGroups[spriteGroupId].tx += value1;
- _spriteGroups[spriteGroupId].ty += value2;
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::setGroupImage(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (_spriteGroups[spriteGroupId].image != value) {
- _spriteGroups[spriteGroupId].image = value;
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::setGroupScaling(int spriteGroupId) {
- if ((_spriteGroups[spriteGroupId].scale_x_ratio_mul != _spriteGroups[spriteGroupId].scale_x_ratio_div) || (_spriteGroups[spriteGroupId].scale_y_ratio_mul != _spriteGroups[spriteGroupId].scale_y_ratio_div))
- _spriteGroups[spriteGroupId].scaling = 1;
- else
- _spriteGroups[spriteGroupId].scaling = 0;
-
-}
-
-void Sprite::setGroupXMul(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (_spriteGroups[spriteGroupId].scale_x_ratio_mul != value) {
- _spriteGroups[spriteGroupId].scale_x_ratio_mul = value;
- setGroupScaling(spriteGroupId);
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::setGroupXDiv(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (value == 0)
- error("setGroupXDiv: Divisor must not be 0");
-
- if (_spriteGroups[spriteGroupId].scale_x_ratio_div != value) {
- _spriteGroups[spriteGroupId].scale_x_ratio_div = value;
- setGroupScaling(spriteGroupId);
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::setGroupYMul(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (_spriteGroups[spriteGroupId].scale_y_ratio_mul != value) {
- _spriteGroups[spriteGroupId].scale_y_ratio_mul = value;
- setGroupScaling(spriteGroupId);
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::setGroupYDiv(int spriteGroupId, int value) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- if (value == 0)
- error("setGroupYDiv: Divisor must not be 0");
-
- if (_spriteGroups[spriteGroupId].scale_y_ratio_div != value) {
- _spriteGroups[spriteGroupId].scale_y_ratio_div = value;
- setGroupScaling(spriteGroupId);
- redrawSpriteGroup(spriteGroupId);
- }
-}
-
-void Sprite::resetGroupBounds(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
-
- _spriteGroups[spriteGroupId].flags &= ~(kSGFClipBox);
- redrawSpriteGroup(spriteGroupId);
-}
-
-void Sprite::allocTables(int numSprites, int numGroups, int numMaxSprites) {
- _varNumSpriteGroups = numGroups;
- _numSpritesToProcess = 0;
- _varNumSprites = numSprites;
- _varMaxSprites = numMaxSprites;
- _spriteGroups = (SpriteGroup *)malloc((_varNumSpriteGroups + 1) * sizeof(SpriteGroup));
- _spriteTable = (SpriteInfo *)malloc((_varNumSprites + 1) * sizeof(SpriteInfo));
- _activeSpritesTable = (SpriteInfo **)malloc((_varNumSprites + 1) * sizeof(SpriteInfo *));
-}
-
-void Sprite::resetGroup(int spriteGroupId) {
- checkRange(_varNumSpriteGroups, 1, spriteGroupId, "Invalid sprite group %d");
- SpriteGroup *spg = &_spriteGroups[spriteGroupId];
-
- spg->priority = 0;
- spg->tx = spg->ty = 0;
-
- spg->flags &= ~kSGFClipBox;
- redrawSpriteGroup(spriteGroupId);
-
- spg->image = 0;
- spg->scaling = 0;
- spg->scale_x_ratio_mul = 1;
- spg->scale_x_ratio_div = 1;
- spg->scale_y_ratio_mul = 1;
- spg->scale_y_ratio_div = 1;
-}
-
-void Sprite::resetTables(bool refreshScreen) {
- memset(_spriteTable, 0, (_varNumSprites + 1) * sizeof(SpriteInfo));
- memset(_spriteGroups, 0, (_varNumSpriteGroups + 1) * sizeof(SpriteGroup));
- for (int curGrp = 1; curGrp < _varNumSpriteGroups; ++curGrp)
- resetGroup(curGrp);
-
- if (refreshScreen) {
- _vm->gdi.copyVirtScreenBuffers(Common::Rect(_vm->_screenWidth, _vm->_screenHeight));
- }
- _numSpritesToProcess = 0;
-}
-
-void Sprite::resetBackground() {
- int xmin, xmax, ymin, ymax;
- xmin = ymin = 1234;
- xmax = ymax = -1234;
- bool firstLoop = true;
- bool refreshScreen = false;
-
- for (int i = 0; i < _numSpritesToProcess; ++i) {
- SpriteInfo *spi = _activeSpritesTable[i];
- if (!(spi->flags & kSFImageless) && (spi->flags & kSFChanged)) {
- spi->flags &= ~kSFChanged;
- if (spi->bbox.left <= spi->bbox.right && spi->bbox.top <= spi->bbox.bottom) {
- if (spi->flags & kSFBlitDirectly) {
- _vm->gdi.copyVirtScreenBuffers(spi->bbox, USAGE_BIT_RESTORED);
- } else if (firstLoop) {
- xmin = spi->bbox.left;
- ymin = spi->bbox.top;
- xmax = spi->bbox.right;
- ymax = spi->bbox.bottom;
- firstLoop = false;
- refreshScreen = true;
- } else {
- if (xmin > spi->bbox.left) {
- xmin = spi->bbox.left;
- }
- if (ymin > spi->bbox.top) {
- ymin = spi->bbox.top;
- }
- if (xmax < spi->bbox.right) {
- xmax = spi->bbox.right;
- }
- if (ymax < spi->bbox.bottom) {
- ymax = spi->bbox.bottom;
- }
- refreshScreen = true;
- }
- if (!(spi->flags & kSFNeedRedraw) && spi->image)
- spi->flags |= kSFNeedRedraw;
- }
- }
- }
- if (refreshScreen) {
- _vm->gdi.copyVirtScreenBuffers(Common::Rect(xmin, ymin, xmax, ymax), USAGE_BIT_RESTORED);
- }
-}
-
-void Sprite::setRedrawFlags(bool checkZOrder) {
- VirtScreen *vs = &_vm->virtscr[kMainVirtScreen];
- for (int i = 0; i < _numSpritesToProcess; ++i) {
- SpriteInfo *spi = _activeSpritesTable[i];
- if (!(spi->flags & kSFNeedRedraw)) {
- if ((!checkZOrder || spi->priority >= 0) && (spi->flags & kSFMarkDirty)) {
- int lp = spi->bbox.left / 8;
- lp = MAX(0, lp);
- lp = MIN(lp, 79);
- int rp = (spi->bbox.right + 7) / 8;
- rp = MAX(0, rp);
- rp = MIN(rp, 79);
- for (; lp <= rp; ++lp) {
- if (vs->tdirty[lp] < vs->h && spi->bbox.bottom >= vs->tdirty[lp] && spi->bbox.top <= vs->bdirty[lp]) {
- spi->flags |= kSFNeedRedraw;
- break;
- }
- }
- }
- }
- }
-}
-
-void Sprite::updateImages() {
- for (int i = 0; i < _numSpritesToProcess; ++i) {
- SpriteInfo *spi = _activeSpritesTable[i];
- if (spi->dx || spi->dy) {
- int tx = spi->tx;
- int ty = spi->ty;
- spi->tx += spi->dx;
- spi->ty += spi->dy;
- if (tx != spi->tx || ty != spi->ty) {
- spi->flags |= kSFChanged | kSFNeedRedraw;
- }
- }
- if (spi->flags & kSFAutoAnim) {
- if (spi->animSpeed) {
- --spi->animProgress;
- if (spi->animProgress)
- continue;
-
- spi->animProgress = spi->animSpeed;
- }
- int imageState = spi->imageState;
- ++spi->imageState;
- if (spi->imageState >= spi->imageStateCount) {
- spi->imageState = 0;
- if (imageState == 0)
- continue;
- }
- spi->flags |= kSFChanged | kSFNeedRedraw;
- }
- }
-}
-
-static int compareSprTable(const void *a, const void *b) {
- const SpriteInfo *spr1 = *(const SpriteInfo *const*)a;
- const SpriteInfo *spr2 = *(const SpriteInfo *const*)b;
-
- if (spr1->zorder > spr2->zorder)
- return 1;
-
- if (spr1->zorder < spr2->zorder)
- return -1;
-
- return 0;
-}
-
-void Sprite::sortActiveSprites() {
- int groupZorder;
-
- _numSpritesToProcess = 0;
-
- if (_varNumSprites <= 1)
- return;
-
- for (int i = 1; i < _varNumSprites; i++) {
- SpriteInfo *spi = &_spriteTable[i];
-
- if (spi->flags & kSFActive) {
- if (!(spi->flags & kSFMarkDirty)) {
- spi->flags |= kSFNeedRedraw;
- if (!(spi->flags & kSFImageless))
- spi->flags |= kSFChanged;
- }
- if (spi->group)
- groupZorder = _spriteGroups[spi->group].priority;
- else
- groupZorder = 0;
-
- spi->id = i;
- spi->zorder = spi->priority + groupZorder;
-
- _activeSpritesTable[_numSpritesToProcess++] = spi;
- }
- }
-
- if (_numSpritesToProcess < 2)
- return;
-
- qsort(_activeSpritesTable, _numSpritesToProcess, sizeof(SpriteInfo *), compareSprTable);
-}
-
-void Sprite::processImages(bool arg) {
- int spr_flags;
- int32 spr_wiz_x, spr_wiz_y;
- int image, imageState;
- Common::Rect *bboxPtr;
- int angle, scale;
- int32 w, h;
- WizParameters wiz;
-
- for (int i = 0; i < _numSpritesToProcess; i++) {
- SpriteInfo *spi = _activeSpritesTable[i];
-
- if (!(spi->flags & kSFNeedRedraw))
- continue;
-
- spr_flags = spi->flags;
-
- if (arg) {
- if (spi->zorder >= 0)
- return;
- } else {
- if (spi->zorder < 0)
- continue;
- }
-
- spi->flags &= ~kSFNeedRedraw;
- image = spi->image;
- imageState = spi->imageState;
- _vm->_wiz->getWizImageSpot(spi->image, spi->imageState, spr_wiz_x, spr_wiz_y);
-
- if (spi->group) {
- SpriteGroup *spg = &_spriteGroups[spi->group];
-
- if (spg->scaling) {
- wiz.img.x1 = spi->tx * spg->scale_x_ratio_mul / spg->scale_x_ratio_div - spr_wiz_x + spg->tx;
- wiz.img.y1 = spi->ty * spg->scale_y_ratio_mul / spg->scale_y_ratio_div - spr_wiz_y + spg->ty;
- } else {
- wiz.img.x1 = spi->tx - spr_wiz_x + spg->tx;
- wiz.img.y1 = spi->ty - spr_wiz_y + spg->ty;
- }
- } else {
- wiz.img.x1 = spi->tx - spr_wiz_x;
- wiz.img.y1 = spi->ty - spr_wiz_y;
- }
-
- wiz.spriteId = spi->id;
- wiz.spriteGroup = spi->group;
- wiz.field_23EA = spi->field_90;
- spi->curImageState = wiz.img.state = imageState;
- spi->curImage = wiz.img.resNum = image;
- wiz.processFlags = kWPFNewState | kWPFSetPos;
- spi->curAngle = spi->angle;
- spi->curScale = spi->scale;
- spi->pos.x = wiz.img.x1;
- spi->pos.y = wiz.img.y1;
- bboxPtr = &spi->bbox;
- if (image) {
- angle = spi->angle;
- scale = spi->scale;
- _vm->_wiz->getWizImageDim(image, imageState, w, h);
- if (spi->flags & (kSFScaled | kSFRotated)) {
- Common::Point pts[4];
- _vm->_wiz->polygonTransform(image, imageState, wiz.img.x1, wiz.img.y1, angle, scale, pts);
- _vm->_wiz->polygonCalcBoundBox(pts, 4, spi->bbox);
- } else {
- bboxPtr->left = wiz.img.x1;
- bboxPtr->top = wiz.img.y1;
- bboxPtr->right = wiz.img.x1 + w;
- bboxPtr->bottom = wiz.img.y1 + h;
- }
- } else {
- bboxPtr->left = 1234;
- bboxPtr->top = 1234;
- bboxPtr->right = -1234;
- bboxPtr->bottom = -1234;
- }
-
- wiz.img.flags = kWIFMarkBufferDirty;
- wiz.img.zorder = 0;
- if (spr_flags & kSFXFlipped)
- wiz.img.flags |= kWIFFlipX;
- if (spr_flags & kSFYFlipped)
- wiz.img.flags |= kWIFFlipY;
- if (spr_flags & kSFDoubleBuffered) {
- wiz.img.flags &= ~kWIFMarkBufferDirty;
- wiz.img.flags |= kWIFBlitToFrontVideoBuffer;
- }
- if (spi->shadow) {
- wiz.img.flags |= 0x200;
- wiz.processFlags |= kWPFShadow;
- wiz.img.shadow = spi->shadow;
- }
- if (spr_flags & kSFRemapPalette)
- wiz.img.flags |= kWIFRemapPalette;
- if (spi->field_84) {
- wiz.processFlags |= 0x200000;
- wiz.img.field_390 = spi->field_84;
- wiz.img.zorder = spi->priority;
- }
- if (spi->sourceImage) {
- wiz.processFlags |= kWPFMaskImg;
- wiz.sourceImage = spi->sourceImage;
- }
- wiz.processFlags |= kWPFNewFlags;
- wiz.img.flags |= spi->imgFlags;
-
- if (spr_flags & kSFRotated) {
- wiz.processFlags |= kWPFRotate;
- wiz.angle = spi->angle;
- }
- if (spr_flags & kSFScaled) {
- wiz.processFlags |= kWPFScaled;
- wiz.scale = spi->scale;
- }
- spi->curImgFlags = wiz.img.flags;
-
- if (spi->group && (_spriteGroups[spi->group].flags & kSGFClipBox)) {
- Common::Rect &spgBbox = _spriteGroups[spi->group].bbox;
- if (spgBbox.isValidRect() && spi->bbox.intersects(spgBbox)) {
- spi->bbox.clip(spgBbox);
- wiz.processFlags |= kWPFClipBox;
- wiz.box = spi->bbox;
- } else {
- bboxPtr->left = 1234;
- bboxPtr->top = 1234;
- bboxPtr->right = -1234;
- bboxPtr->bottom = -1234;
- continue;
- }
- }
- if (spi->palette) {
- wiz.processFlags |= kWPFPaletteNum;
- wiz.img.palette = spi->palette;
- }
- if (spi->image && spi->group && _spriteGroups[spi->group].image) {
- wiz.processFlags |= kWPFDstResNum;
- wiz.dstResNum = _spriteGroups[spi->group].image;
- }
- _vm->_wiz->displayWizComplexImage(&wiz);
- }
-}
-
-void Sprite::saveOrLoadSpriteData(Serializer *s) {
- static const SaveLoadEntry spriteEntries[] = {
- MKLINE(SpriteInfo, id, sleInt32, VER(48)),
- MKLINE(SpriteInfo, zorder, sleInt32, VER(48)),
- MKLINE(SpriteInfo, flags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, image, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imageState, sleInt32, VER(48)),
- MKLINE(SpriteInfo, group, sleInt32, VER(48)),
- MKLINE(SpriteInfo, palette, sleInt32, VER(48)),
- MKLINE(SpriteInfo, priority, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.left, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.top, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.right, sleInt32, VER(48)),
- MKLINE(SpriteInfo, bbox.bottom, sleInt32, VER(48)),
- MKLINE(SpriteInfo, dx, sleInt32, VER(48)),
- MKLINE(SpriteInfo, dy, sleInt32, VER(48)),
- MKLINE(SpriteInfo, pos.x, sleInt32, VER(48)),
- MKLINE(SpriteInfo, pos.y, sleInt32, VER(48)),
- MKLINE(SpriteInfo, tx, sleInt32, VER(48)),
- MKLINE(SpriteInfo, ty, sleInt32, VER(48)),
- MKLINE(SpriteInfo, userValue, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curImageState, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imglistNum, sleInt32, VER(48)),
- MKLINE(SpriteInfo, shadow, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imageStateCount, sleInt32, VER(48)),
- MKLINE(SpriteInfo, angle, sleInt32, VER(48)),
- MKLINE(SpriteInfo, scale, sleInt32, VER(48)),
- MKLINE(SpriteInfo, animProgress, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curAngle, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curScale, sleInt32, VER(48)),
- MKLINE(SpriteInfo, curImgFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, field_74, sleInt32, VER(48)),
- MKLINE(SpriteInfo, animSpeed, sleInt32, VER(48)),
- MKLINE(SpriteInfo, sourceImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, maskImage, sleInt32, VER(48)),
- MKLINE(SpriteInfo, field_84, sleInt32, VER(48)),
- MKLINE(SpriteInfo, classFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, imgFlags, sleInt32, VER(48)),
- MKLINE(SpriteInfo, field_90, sleInt32, VER(48)),
- MKEND()
- };
-
- static const SaveLoadEntry spriteGroupEntries[] = {
- MKLINE(SpriteGroup, bbox.left, sleInt32, VER(48)),
- MKLINE(SpriteGroup, bbox.top, sleInt32, VER(48)),
- MKLINE(SpriteGroup, bbox.right, sleInt32, VER(48)),
- MKLINE(SpriteGroup, bbox.bottom, sleInt32, VER(48)),
- MKLINE(SpriteGroup, priority, sleInt32, VER(48)),
- MKLINE(SpriteGroup, flags, sleInt32, VER(48)),
- MKLINE(SpriteGroup, tx, sleInt32, VER(48)),
- MKLINE(SpriteGroup, ty, sleInt32, VER(48)),
- MKLINE(SpriteGroup, image, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scaling, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_x_ratio_mul, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_x_ratio_div, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_y_ratio_mul, sleInt32, VER(48)),
- MKLINE(SpriteGroup, scale_y_ratio_div, sleInt32, VER(48)),
- MKEND()
- };
-
- if (s->getVersion() >= VER(64)) {
- s->saveLoadArrayOf(_spriteTable, _varNumSprites + 1, sizeof(_spriteTable[0]), spriteEntries);
- s->saveLoadArrayOf(_spriteGroups, _varNumSpriteGroups + 1, sizeof(_spriteGroups[0]), spriteGroupEntries);
- } else {
- s->saveLoadArrayOf(_activeSpritesTable, _varNumSprites, sizeof(_activeSpritesTable[0]), spriteEntries);
- s->saveLoadArrayOf(_spriteTable, _varNumSprites, sizeof(_spriteTable[0]), spriteEntries);
- s->saveLoadArrayOf(_spriteGroups, _varNumSpriteGroups, sizeof(_spriteGroups[0]), spriteGroupEntries);
- }
-
- // Reset active sprite table
- if (s->isLoading())
- _numSpritesToProcess = 0;
-
-}
-
-} // End of namespace Scumm
diff --git a/scumm/sprite_he.h b/scumm/sprite_he.h
deleted file mode 100644
index 5396c1fed4..0000000000
--- a/scumm/sprite_he.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(SPRITE_HE_H) && !defined(DISABLE_HE)
-#define SPRITE_HE_H
-
-namespace Scumm {
-
-enum SpriteFlags {
- kSFChanged = 0x1,
- kSFNeedRedraw = 0x2,
- kSFScaled = 0x10,
- kSFRotated = 0x20,
- kSFDoubleBuffered = 0x1000,
- kSFYFlipped = 0x2000,
- kSFXFlipped = 0x4000,
- kSFActive = 0x8000,
- kSFRemapPalette = 0x80000,
- kSFAutoAnim = 0x200000,
- kSFMarkDirty = 0x400000,
- kSFBlitDirectly = 0x2000000,
- kSFImageless = 0x40000000
-};
-
-enum SpriteGroupFlags {
- kSGFClipBox = (1 << 0)
-};
-
-struct SpriteInfo {
- int32 id;
- int32 zorder;
- int32 flags;
- int32 image;
- int32 imageState;
- int32 group;
- int32 palette;
- int32 priority;
- Common::Rect bbox;
- int32 dx;
- int32 dy;
- Common::Point pos;
- int32 tx;
- int32 ty;
- int32 userValue;
- int32 curImageState;
- int32 curImage;
- int32 imglistNum;
- int32 shadow;
- int32 imageStateCount;
- int32 angle;
- int32 scale;
- int32 animProgress;
- int32 curAngle;
- int32 curScale;
- int32 curImgFlags;
- int32 field_74;
- int32 animSpeed;
- int32 sourceImage;
- int32 maskImage;
- int32 field_84;
- int32 classFlags;
- int32 imgFlags;
- int32 field_90;
-};
-
-struct SpriteGroup {
- Common::Rect bbox;
- int32 priority;
- int32 flags;
- int32 tx;
- int32 ty;
- int32 image;
- int32 scaling;
- int32 scale_x_ratio_mul;
- int32 scale_x_ratio_div;
- int32 scale_y_ratio_mul;
- int32 scale_y_ratio_div;
-};
-
-class ScummEngine_v90he;
-
-class Sprite {
-public:
- Sprite(ScummEngine_v90he *vm);
- virtual ~Sprite();
-
- SpriteInfo *_spriteTable;
- SpriteGroup *_spriteGroups;
- SpriteInfo **_activeSpritesTable;
-
- int32 _numSpritesToProcess;
- int32 _varNumSpriteGroups;
- int32 _varNumSprites;
- int32 _varMaxSprites;
-
- void saveOrLoadSpriteData(Serializer *s);
- void resetBackground();
- void setRedrawFlags(bool checkZOrder);
- void sortActiveSprites();
- void processImages(bool arg);
- void updateImages();
-
- int findSpriteWithClassOf(int x, int y, int spriteGroupId, int d, int num, int *args);
- int getSpriteClass(int spriteId, int num, int *args);
- int getSpriteFlagDoubleBuffered(int spriteId);
- int getSpriteFlagYFlipped(int spriteId);
- int getSpriteFlagXFlipped(int spriteId);
- int getSpriteFlagActive(int spriteId);
- int getSpriteFlagRemapPalette(int spriteId);
- int getSpriteFlagAutoAnim(int spriteId);
- int getSpriteFlagUpdateType(int spriteId);
- int getSpriteFlagEraseType(int spriteId);
- int getSpriteImage(int spriteId);
- int getSpriteImageState(int spriteId);
- int getSpriteGroup(int spriteId);
- int getSpritePalette(int spriteId);
- int getSpritePriority(int spriteId);
- int getSpriteDisplayX(int spriteId);
- int getSpriteDisplayY(int spriteId);
- int getSpriteUserValue(int spriteId);
- int getSpriteShadow(int spriteId);
- int getSpriteImageStateCount(int spriteId);
- int getSpriteScale(int spriteId);
- int getSpriteAnimSpeed(int spriteId);
- int getSpriteSourceImage(int spriteId);
- int getSpriteMaskImage(int spriteId);
- int getSpriteGeneralProperty(int spriteId, int type);
- void getSpriteBounds(int spriteId, bool checkGroup, Common::Rect &bound);
- void getSpriteImageDim(int spriteId, int32 &w, int32 &h);
- void getSpritePosition(int spriteId, int32 &tx, int32 &ty);
- void getSpriteDist(int spriteId, int32 &dx, int32 &dy);
-
- int getGroupPriority(int spriteGroupId);
- int getGroupDstResNum(int spriteGroupId);
- int getGroupXMul(int spriteGroupId);
- int getGroupXDiv(int spriteGroupId);
- int getGroupYMul(int spriteGroupId);
- int getGroupYDiv(int spriteGroupId);
- void getGroupPosition(int spriteGroupId, int32 &tx, int32 &ty);
-
- void setSpritePalette(int spriteId, int value);
- void setSpriteSourceImage(int spriteId, int value);
- void setSpriteMaskImage(int spriteId, int value);
- void resetSprite(int spriteId);
- void setSpriteImageState(int spriteId, int value);
- void setSpritePosition(int spriteId, int value1, int value2);
- void setSpriteGroup(int spriteId, int value);
- void setSpriteDist(int spriteId, int value1, int value2);
- void setSpriteShadow(int spriteId, int value);
- void setSpriteUserValue(int spriteId, int value1, int value2);
- void setSpritePriority(int spriteId, int value);
- void moveSprite(int spriteId, int value1, int value2);
- void setSpriteScale(int spriteId, int value);
- void setSpriteAngle(int spriteId, int value);
- void setSpriteFlagDoubleBuffered(int spriteId, int value);
- void setSpriteFlagYFlipped(int spriteId, int value);
- void setSpriteFlagXFlipped(int spriteId, int value);
- void setSpriteFlagActive(int spriteId, int value);
- void setSpriteFlagRemapPalette(int spriteId, int value);
- void setSpriteFlagAutoAnim(int spriteId, int value);
- void setSpriteFlagUpdateType(int spriteId, int value);
- void setSpriteFlagEraseType(int spriteId, int value);
- void setSpriteAnimSpeed(int spriteId, int value);
- void setSpriteSetClass(int spriteId, int classId, int toggle);
- void setSpriteResetClass(int spriteId);
- void setSpriteField84(int spriteId, int value);
- void setSpriteGeneralProperty(int spriteId, int type, int value);
-
- void moveGroupMembers(int spriteGroupId, int value1, int value2);
- void redrawSpriteGroup(int spriteGroupId);
- void setGroupMembersPriority(int spriteGroupId, int value);
- void setGroupMembersGroup(int spriteGroupId, int value);
- void setGroupMembersUpdateType(int spriteGroupId, int value);
- void setGroupMembersResetSprite(int spriteGroupId);
- void setGroupMembersAnimationSpeed(int spriteGroupId, int value);
- void setGroupMembersAutoAnimFlag(int spriteGroupId, int value);
- void setGroupMembersShadow(int spriteGroupId, int value);
-
- void moveGroup(int spriteGroupId, int value1, int value2);
- void setGroupBounds(int spriteGroupId, int x1, int y1, int x2, int y2);
- void setGroupPriority(int spriteGroupId, int value);
- void setGroupPosition(int spriteGroupId, int value1, int value2);
- void setGroupImage(int spriteGroupId, int value);
- void setGroupScaling(int spriteGroupId);
- void setGroupXMul(int spriteGroupId, int value);
- void setGroupXDiv(int spriteGroupId, int value);
- void setGroupYMul(int spriteGroupId, int value);
- void setGroupYDiv(int spriteGroupId, int value);
- void resetGroupBounds(int spriteGroupId);
-
- void allocTables(int numSprites, int numGroups, int numMaxSprites);
- void resetGroup(int spriteGroupId);
- void resetTables(bool refreshScreen);
- void setSpriteImage(int spriteId, int imageNum);
-private:
- ScummEngine_v90he *_vm;
-};
-
-} // End of namespace Scumm
-
-#endif
-
diff --git a/scumm/string.cpp b/scumm/string.cpp
deleted file mode 100644
index c32413542d..0000000000
--- a/scumm/string.cpp
+++ /dev/null
@@ -1,1247 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "common/config-manager.h"
-
-#include "scumm/scumm.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/dialogs.h"
-#include "scumm/imuse_digi/dimuse.h"
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/verbs.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-namespace Scumm {
-
-
-
-#pragma mark -
-#pragma mark --- "High level" message code ---
-#pragma mark -
-
-
-void ScummEngine::printString(int m, const byte *msg) {
- switch (m) {
- case 0:
- actorTalk(msg);
- break;
- case 1:
- drawString(1, msg);
- break;
- case 2:
- debugMessage(msg);
- break;
- case 3:
- showMessageDialog(msg);
- break;
- }
-}
-
-
-void ScummEngine::debugMessage(const byte *msg) {
- byte buffer[500];
- convertMessageToString(msg, buffer, sizeof(buffer));
-
-// if ((_gameId == GID_CMI) && _debugMode) { // In CMI, debugMessage is used for printDebug output
- if ((buffer[0] != 0xFF) && _debugMode) {
- debug(0, "DEBUG: %s", buffer);
- return;
- }
-
- if (buffer[0] == 0xFF && buffer[1] == 10) {
- uint32 a, b;
- int channel = 0;
-
- a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
- b = buffer[10] | (buffer[11] << 8) | (buffer[14] << 16) | (buffer[15] << 24);
-
- // Sam and Max uses a caching system, printing empty messages
- // and setting VAR_V6_SOUNDMODE beforehand. See patch 609791.
- if (_gameId == GID_SAMNMAX)
- channel = VAR(VAR_V6_SOUNDMODE);
-
- if (channel != 2)
- _sound->talkSound(a, b, 1, channel);
- }
-}
-
-void ScummEngine::showMessageDialog(const byte *msg) {
- // Original COMI used different code at this point.
- // Seemed to use blastText for the messages
- byte buf[500];
-
- convertMessageToString(msg, buf, sizeof(buf));
-
- if (_string[3].color == 0)
- _string[3].color = 4;
-
- InfoDialog dialog(this, (char*)buf);
- VAR(VAR_KEYPRESS) = runDialog(dialog);
-}
-
-
-#pragma mark -
-#pragma mark --- V6 blast text queue code ---
-#pragma mark -
-
-
-void ScummEngine_v6::enqueueText(const byte *text, int x, int y, byte color, byte charset, bool center) {
- BlastText &bt = _blastTextQueue[_blastTextQueuePos++];
- assert(_blastTextQueuePos <= ARRAYSIZE(_blastTextQueue));
-
- convertMessageToString(text, bt.text, sizeof(bt.text));
- bt.xpos = x;
- bt.ypos = y;
- bt.color = color;
- bt.charset = charset;
- bt.center = center;
-}
-
-void ScummEngine_v6::drawBlastTexts() {
- byte *buf;
- int c;
- int i;
-
- for (i = 0; i < _blastTextQueuePos; i++) {
-
- buf = _blastTextQueue[i].text;
-
- _charset->_top = _blastTextQueue[i].ypos + _screenTop;
- _charset->_right = _screenWidth - 1;
- _charset->_center = _blastTextQueue[i].center;
- _charset->setColor(_blastTextQueue[i].color);
- _charset->_disableOffsX = _charset->_firstChar = true;
- _charset->setCurID(_blastTextQueue[i].charset);
-
- do {
- _charset->_left = _blastTextQueue[i].xpos;
-
- // Center text if necessary
- if (_charset->_center) {
- _charset->_left -= _charset->getStringWidth(0, buf) / 2;
- if (_charset->_left < 0)
- _charset->_left = 0;
- }
-
- do {
- c = *buf++;
-
- // FIXME: This is a workaround for bugs #864030 and #1399843:
- // In COMI, some text contains ASCII character 11 = 0xB. It's
- // not quite clear what it is good for; so for now we just ignore
- // it, which seems to match the original engine (BTW, traditionally,
- // this is a 'vertical tab').
- if (c == 0x0B)
- continue;
-
- if (c != 0 && c != 0xFF && c != '\n') {
- if (c & 0x80 && _useCJKMode) {
- if (_language == Common::JA_JPN && !checkSJISCode(c)) {
- c = 0x20; //not in S-JIS
- } else {
- c += *buf++ * 256;
- }
- }
- _charset->printChar(c, true);
- }
- } while (c && c != '\n');
-
- _charset->_top += _charset->getFontHeight();
- } while (c);
-
- _blastTextQueue[i].rect = _charset->_str;
- }
-}
-
-void ScummEngine_v6::removeBlastTexts() {
- int i;
-
- for (i = 0; i < _blastTextQueuePos; i++) {
- restoreBG(_blastTextQueue[i].rect);
- }
- _blastTextQueuePos = 0;
-}
-
-
-#pragma mark -
-#pragma mark --- V7 subtitle queue code ---
-#pragma mark -
-
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::processSubtitleQueue() {
- for (int i = 0; i < _subtitleQueuePos; ++i) {
- SubtitleText *st = &_subtitleQueue[i];
- if (!ConfMan.getBool("subtitles") || VAR(VAR_VOICE_MODE) == 0)
- // subtitles are disabled, don't display the text
- continue;
- if (!ConfMan.getBool("subtitles") && (!st->actorSpeechMsg || _mixer->isSoundHandleActive(_sound->_talkChannelHandle)))
- // no subtitles and there's a speech variant of the message, don't display the text
- continue;
- enqueueText(st->text, st->xpos, st->ypos, st->color, st->charset, false);
- }
-}
-
-void ScummEngine_v7::addSubtitleToQueue(const byte *text, const Common::Point &pos, byte color, byte charset) {
- if (text[0] && strcmp((const char *)text, " ") != 0) {
- assert(_subtitleQueuePos < ARRAYSIZE(_subtitleQueue));
- SubtitleText *st = &_subtitleQueue[_subtitleQueuePos];
- int i = 0;
- while (1) {
- st->text[i] = text[i];
- if (!text[i])
- break;
- ++i;
- }
- st->xpos = pos.x;
- st->ypos = pos.y;
- st->color = color;
- st->charset = charset;
- st->actorSpeechMsg = _haveActorSpeechMsg;
- ++_subtitleQueuePos;
- }
-}
-
-void ScummEngine_v7::clearSubtitleQueue() {
- memset(_subtitleQueue, 0, sizeof(_subtitleQueue));
- _subtitleQueuePos = 0;
-}
-#endif
-
-
-
-#pragma mark -
-#pragma mark --- Core message/subtitle code ---
-#pragma mark -
-
-
-bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
- uint32 talk_sound_a = 0;
- uint32 talk_sound_b = 0;
- int color, frme, c = 0, oldy;
- bool endLoop = false;
- byte *buffer = _charsetBuffer + _charsetBufPos;
- while (!endLoop) {
- c = *buffer++;
- if (!(c == 0xFF || (_version <= 6 && c == 0xFE))) {
- break;
- }
- c = *buffer++;
- switch (c) {
- case 1:
- c = 13; // new line
- endLoop = true;
- break;
- case 2:
- _haveMsg = 0;
- _keepText = true;
- endLoop = true;
- break;
- case 3:
- _haveMsg = (_version >= 7) ? 1 : 0xFF;
- _keepText = false;
- endLoop = true;
- break;
- case 8:
- // Ignore this code here. Occurs e.g. in MI2 when you
- // talk to the carpenter on scabb island. It works like
- // code 1 (=newline) in verb texts, but is ignored in
- // spoken text (i.e. here). Used for very long verb
- // sentences.
- break;
- case 9:
- frme = buffer[0] | (buffer[1] << 8);
- buffer += 2;
- if (a)
- a->startAnimActor(frme);
- break;
- case 10:
- // Note the similarity to the code in debugMessage()
- talk_sound_a = buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24);
- talk_sound_b = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24);
- buffer += 14;
- if (_heversion >= 60) {
- _sound->startHETalkSound(talk_sound_a);
- } else {
- _sound->talkSound(talk_sound_a, talk_sound_b, 2);
- }
- _haveActorSpeechMsg = false;
- break;
- case 12:
- color = buffer[0] | (buffer[1] << 8);
- buffer += 2;
- if (color == 0xFF)
- _charset->setColor(_charsetColor);
- else
- _charset->setColor(color);
- break;
- case 13:
- debug(0, "handleNextCharsetCode: Unknown opcode 13 %d", READ_LE_UINT16(buffer));
- buffer += 2;
- break;
- case 14:
- oldy = _charset->getFontHeight();
- _charset->setCurID(*buffer++);
- buffer += 2;
- memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4);
- _charset->_nextTop -= _charset->getFontHeight() - oldy;
- break;
- default:
- error("handleNextCharsetCode: invalid code %d", c);
- }
- }
- _charsetBufPos = buffer - _charsetBuffer;
- *code = c;
- return (c != 2 && c != 3);
-}
-
-#ifndef DISABLE_HE
-bool ScummEngine_v72he::handleNextCharsetCode(Actor *a, int *code) {
- const int charsetCode = (_heversion >= 80) ? 127 : 64;
- uint32 talk_sound_a = 0;
- uint32 talk_sound_b = 0;
- int i, c = 0;
- char value[32];
- bool endLoop = false;
- bool endText = false;
- byte *buffer = _charsetBuffer + _charsetBufPos;
- while (!endLoop) {
- c = *buffer++;
- if (c != charsetCode) {
- break;
- }
- c = *buffer++;
- switch (c) {
- case 84:
- i = 0;
- c = *buffer++;
- while (c != 44) {
- value[i] = c;
- c = *buffer++;
- i++;
- }
- value[i] = 0;
- talk_sound_a = atoi(value);
- i = 0;
- c = *buffer++;
- while (c != charsetCode) {
- value[i] = c;
- c = *buffer++;
- i++;
- }
- value[i] = 0;
- talk_sound_b = atoi(value);
- _sound->startHETalkSound(talk_sound_a);
- break;
- case 104:
- _haveMsg = 0;
- _keepText = true;
- endLoop = endText = true;
- break;
- case 110:
- c = 13; // new line
- endLoop = true;
- break;
- case 116:
- i = 0;
- memset(value, 0, sizeof(value));
- c = *buffer++;
- while (c != charsetCode) {
- value[i] = c;
- c = *buffer++;
- i++;
- }
- value[i] = 0;
- talk_sound_a = atoi(value);
- talk_sound_b = 0;
- _sound->startHETalkSound(talk_sound_a);
- break;
- case 119:
- _haveMsg = 0xFF;
- _keepText = false;
- endLoop = endText = true;
- break;
- default:
- error("handleNextCharsetCode: invalid code %d", c);
- }
- }
- _charsetBufPos = buffer - _charsetBuffer;
- *code = c;
- return (endText == 0);
-}
-#endif
-
-void ScummEngine::CHARSET_1() {
- Actor *a;
- int t, c = 0;
-#ifndef DISABLE_SCUMM_7_8
- byte subtitleBuffer[200];
- byte *subtitleLine = subtitleBuffer;
- Common::Point subtitlePos;
-
- if (_version >= 7) {
- ((ScummEngine_v7 *)this)->processSubtitleQueue();
- }
-#endif
-
- if (!_haveMsg)
- return;
-
- if (!(_features & GF_NEW_CAMERA) && !(_gameId == GID_ZAK && (_platform == Common::kPlatformFMTowns) && getTalkingActor() == 0xFF)) {
- if ((camera._dest.x / 8) != (camera._cur.x / 8) || camera._cur.x != camera._last.x)
- return;
- }
-
- a = NULL;
- if (getTalkingActor() != 0xFF)
- a = derefActorSafe(getTalkingActor(), "CHARSET_1");
-
- if (a && _string[0].overhead != 0) {
- int s;
-
- _string[0].xpos = a->_pos.x - virtscr[0].xstart;
- _string[0].ypos = a->_pos.y - a->getElevation() - _screenTop;
-
- if (_version <= 5) {
-
- if (VAR(VAR_V5_TALK_STRING_Y) < 0) {
- s = (a->_scaley * (int)VAR(VAR_V5_TALK_STRING_Y)) / 0xFF;
- _string[0].ypos += (int)(((VAR(VAR_V5_TALK_STRING_Y) - s) / 2) + s);
- } else {
- _string[0].ypos = (int)VAR(VAR_V5_TALK_STRING_Y);
- }
-
- } else {
- s = a->_scalex * a->_talkPosX / 0xFF;
- _string[0].xpos += ((a->_talkPosX - s) / 2) + s;
-
- s = a->_scaley * a->_talkPosY / 0xFF;
- _string[0].ypos += ((a->_talkPosY - s) / 2) + s;
-
- if (_string[0].ypos > _screenHeight - 40)
- _string[0].ypos = _screenHeight - 40;
- }
-
- if (_string[0].ypos < 1)
- _string[0].ypos = 1;
-
- if (_string[0].xpos < 80)
- _string[0].xpos = 80;
- if (_string[0].xpos > _screenWidth - 80)
- _string[0].xpos = _screenWidth - 80;
- }
-
- _charset->_top = _string[0].ypos + _screenTop;
- _charset->_startLeft = _charset->_left = _string[0].xpos;
- _charset->_right = _string[0].right;
- _charset->_center = _string[0].center;
- _charset->setColor(_charsetColor);
-
- if (a && a->_charset)
- _charset->setCurID(a->_charset);
- else
- _charset->setCurID(_string[0].charset);
-
- if (_version >= 5)
- memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4);
-
- if (_talkDelay)
- return;
-
- if ((_version <= 6 && _haveMsg == 1) || (_version == 7 && _haveMsg != 1) || (_version == 8 && VAR(VAR_HAVE_MSG))) {
- if ((_sound->_sfxMode & 2) == 0)
- stopTalk();
- return;
- }
-
- if (a && !_string[0].no_talk_anim) {
- a->runActorTalkScript(a->_talkStartFrame);
- _useTalkAnims = true;
- }
-
- _talkDelay = (VAR_DEFAULT_TALK_DELAY != 0xFF) ? VAR(VAR_DEFAULT_TALK_DELAY) : 60;
-
- if (!_keepText) {
- if (_version >= 7) {
-#ifndef DISABLE_SCUMM_7_8
- ((ScummEngine_v7 *)this)->clearSubtitleQueue();
- _charset->_nextLeft = _string[0].xpos;
- _charset->_nextTop = _string[0].ypos;
-#endif
- } else {
- _charset->restoreCharsetBg();
- }
- }
-
- t = _charset->_right - _string[0].xpos - 1;
- if (_charset->_center) {
- if (t > _charset->_nextLeft)
- t = _charset->_nextLeft;
- t *= 2;
- }
-
- if (_version > 3)
- _charset->addLinebreaks(0, _charsetBuffer + _charsetBufPos, 0, t);
-
- if (_charset->_center) {
- _charset->_nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2;
- if (_charset->_nextLeft < 0)
- _charset->_nextLeft = 0;
- }
-
- _charset->_disableOffsX = _charset->_firstChar = !_keepText;
-
- while (handleNextCharsetCode(a, &c)) {
- if (c == 0) {
- // End of text reached, set _haveMsg accordingly
- _haveMsg = (_version >= 7) ? 2 : 1;
- _keepText = false;
- break;
- }
-
- if (c == 13) {
- newLine:;
- _charset->_nextLeft = _string[0].xpos;
-#ifndef DISABLE_SCUMM_7_8
- if (_version >= 7 && subtitleLine != subtitleBuffer) {
- ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
- subtitleLine = subtitleBuffer;
- }
-#endif
- if (_charset->_center) {
- _charset->_nextLeft -= _charset->getStringWidth(0, _charsetBuffer + _charsetBufPos) / 2;
- }
-
- if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
- break;
- } else if (!(_platform == Common::kPlatformFMTowns) && _string[0].height) {
- _charset->_nextTop += _string[0].height;
- } else {
- _charset->_nextTop += _charset->getFontHeight();
- }
- if (_version > 3) {
- // FIXME - is this really needed?
- _charset->_disableOffsX = true;
- }
- continue;
- }
-
- _charset->_left = _charset->_nextLeft;
- _charset->_top = _charset->_nextTop;
-
- if (_version >= 7) {
-#ifndef DISABLE_SCUMM_7_8
- if (subtitleLine == subtitleBuffer) {
- subtitlePos.x = _charset->_left;
- subtitlePos.y = _charset->_top;
- }
- *subtitleLine++ = c;
- *subtitleLine = '\0';
-#endif
- } else {
- if (c & 0x80 && _useCJKMode) {
- if (_language == Common::JA_JPN && !checkSJISCode(c)) {
- c = 0x20; //not in S-JIS
- } else {
- byte *buffer = _charsetBuffer + _charsetBufPos;
- c += *buffer++ * 256; //LE
- _charsetBufPos = buffer - _charsetBuffer;
- }
- }
- if (_version <= 3) {
- _charset->printChar(c, false);
- } else {
- if (_features & GF_HE_NOSUBTITLES) {
- // HE games which use sprites for subtitles
- } else if (_heversion >= 60 && !ConfMan.getBool("subtitles") && _sound->isSoundRunning(1)) {
- // Special case for HE games
- } else if (_gameId == GID_LOOM && !ConfMan.getBool("subtitles") && (_sound->pollCD())) {
- // Special case for Loom (CD), since it only uses CD audio.for sound
- } else if (!ConfMan.getBool("subtitles") && (!_haveActorSpeechMsg || _mixer->isSoundHandleActive(_sound->_talkChannelHandle))) {
- // Subtitles are turned off, and there is a voice version
- // of this message -> don't print it.
- } else {
- _charset->printChar(c, false);
- }
- }
- _charset->_nextLeft = _charset->_left;
- _charset->_nextTop = _charset->_top;
- }
-
- if (_version <= 2) {
- _talkDelay += _defaultTalkDelay;
- VAR(VAR_CHARCOUNT)++;
- } else {
- _talkDelay += (int)VAR(VAR_CHARINC);
- }
- // Handle line overflow for V3
- if (_version == 3 && _charset->_nextLeft > _screenWidth) {
- _charset->_nextLeft = _screenWidth;
- }
- // Handle line breaks for V1-V2
- if (_version <= 2 && _charset->_nextLeft > _screenWidth) {
- goto newLine;
- }
- }
-
-#ifndef DISABLE_SCUMM_7_8
- if (_version >= 7 && subtitleLine != subtitleBuffer) {
- ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
- }
-#endif
-}
-
-void ScummEngine::drawString(int a, const byte *msg) {
- byte buf[270];
- byte *space;
- int i, c;
- byte fontHeight = 0;
- uint color;
- int code = (_heversion >= 80) ? 127 : 64;
-
- bool cmi_pos_hack = false;
-
- convertMessageToString(msg, buf, sizeof(buf));
-
- if (_version >= 7) {
- // I recently disabled charset mask related code for V7+ games, thinking
- // that it should never be needed there. Well, I missed on case: In this
- // method, it could potentially still be used. Now the question is:
- // Does this actually ever happen? Basically, drawString is called from
- // two spots: First off, from drawVerb, which I *think* is not used for
- // V7+ games (but I am not 100% sure), and secondly from printString().
- // The latter is much harder to predict. Maybe in some obscure place it
- // is used after all?
- //
- // Hence I am adding this error message, hoping that either somebody
- // triggers it (at which point I can investigate), or, if nobody ever
- // triggers it, we can assume that it's safe to keep this error even
- // after the release.
- //
- // TODO/FIXME: Remove or update this hack before the next release!
- error("drawString(%d, '%s') -- please inform Fingolfin about this crash!", a, buf);
- }
-
- _charset->_top = _string[a].ypos + _screenTop;
- _charset->_startLeft = _charset->_left = _string[a].xpos;
- _charset->_right = _string[a].right;
- _charset->_center = _string[a].center;
- _charset->setColor(_string[a].color);
- _charset->_disableOffsX = _charset->_firstChar = true;
- _charset->setCurID(_string[a].charset);
-
- if (_version >= 5)
- memcpy(_charsetColorMap, _charsetData[_charset->getCurID()], 4);
-
- fontHeight = _charset->getFontHeight();
-
- // trim from the right
- byte *tmp = buf;
- space = NULL;
- while (*tmp) {
- if (*tmp == ' ') {
- if (!space)
- space = tmp;
- } else {
- space = NULL;
- }
- tmp++;
- }
- if (space)
- *space = '\0';
- if (_charset->_center) {
- _charset->_left -= _charset->getStringWidth(a, buf) / 2;
- }
-
- const bool ignoreCharsetMask = (_version < 7);
-
- if (!buf[0]) {
- buf[0] = ' ';
- buf[1] = 0;
- }
-
- for (i = 0; (c = buf[i++]) != 0;) {
- if (_heversion >= 72 && c == code) {
- c = buf[i++];
- switch (c) {
- case 110:
- if (_charset->_center) {
- _charset->_left = _charset->_startLeft - _charset->getStringWidth(a, buf + i);
- } else {
- _charset->_left = _charset->_startLeft;
- }
- _charset->_top += fontHeight;
- break;
- }
- } else if (c == 0xFF || (_version <= 6 && c == 0xFE)) {
- c = buf[i++];
- switch (c) {
- case 9:
- case 10:
- case 13:
- case 14:
- i += 2;
- break;
- case 1:
- case 8:
- if (_charset->_center) {
- _charset->_left = _charset->_startLeft - _charset->getStringWidth(a, buf + i);
- } else {
- _charset->_left = _charset->_startLeft;
- }
- if (!(_platform == Common::kPlatformFMTowns) && _string[0].height) {
- _charset->_nextTop += _string[0].height;
- } else {
- _charset->_top += fontHeight;
- }
- break;
- case 12:
- color = buf[i] + (buf[i + 1] << 8);
- i += 2;
- if (color == 0xFF)
- _charset->setColor(_string[a].color);
- else
- _charset->setColor(color);
- break;
- }
- } else {
- if (a == 1 && _version >= 6) {
- // FIXME: The following code is a bit nasty. It is used for the
- // Highway surfing game in Sam&Max; there, _blitAlso is set to
- // true when writing the highscore numbers. It is also in DOTT
- // for parts the intro and for drawing newspaper headlines. It
- // is also used for scores in bowling mini game in fbear and
- // for names in load/save screen of all HE games. Maybe it is
- // also being used in other places.
- //
- // A better name for _blitAlso might be _imprintOnBackground
-
- if (_string[a].no_talk_anim == false) {
- //debug(0, "Would have set _charset->_blitAlso = true (wanted to print '%c' = %d)", c, c);
- _charset->_blitAlso = true;
- }
- }
- if (c & 0x80 && _useCJKMode) {
- if (_language == Common::JA_JPN && !checkSJISCode(c)) {
- c = 0x20; //not in S-JIS
- } else {
- c += buf[i++] * 256;
- if (_gameId == GID_CMI) {
- cmi_pos_hack = true;
- _charset->_top += 6;
- }
- }
- }
- _charset->printChar(c, ignoreCharsetMask);
- _charset->_blitAlso = false;
-
- if (cmi_pos_hack) {
- cmi_pos_hack = false;
- _charset->_top -= 6;
- }
- }
- }
-
- if (a == 0) {
- _charset->_nextLeft = _charset->_left;
- _charset->_nextTop = _charset->_top;
- }
-
- _string[a].xpos = _charset->_str.right + 8; // Indy3: Fixes Grail Diary text positioning
-}
-
-int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) {
- uint num = 0;
- uint32 val;
- byte chr;
- const byte *src;
- byte *end;
- byte transBuf[384];
-
- assert(dst);
- end = dst + dstSize;
-
- if (msg == NULL) {
- debug(0, "Bad message in convertMessageToString, ignoring");
- return 0;
- }
-
- if (_version >= 7) {
- translateText(msg, transBuf);
- src = transBuf;
- } else {
- src = msg;
- }
-
- num = 0;
-
- while (1) {
- chr = src[num++];
- if (_heversion >= 80 && (src[num - 1] == '(' && src[num] == 'P' && src[num + 1] == 'U')) {
- while (src[num++] != ')');
- continue;
- }
- if ((_features & GF_HE_LOCALIZED) && chr == '[') {
- while (src[num++] != ']');
- continue;
- }
-
- if (chr == 0)
- break;
- if (chr == 0xFF) {
- chr = src[num++];
-
- // WORKAROUND for bug #985948, a script bug in Indy3. Apparently,
- // a german 'sz' was encoded incorrectly as 0xFF2E. We replace
- // this by the correct encoding here. See also ScummEngine::resStrLen().
- if (_gameId == GID_INDY3 && chr == 0x2E) {
- *dst++ = 0xE1;
- continue;
- }
-
- if (chr == 1 || chr == 2 || chr == 3 || chr == 8) {
- // Simply copy these special codes
- *dst++ = 0xFF;
- *dst++ = chr;
- } else {
- val = (_version == 8) ? READ_LE_UINT32(src + num) : READ_LE_UINT16(src + num);
- switch (chr) {
- case 4:
- dst += convertIntMessage(dst, end - dst, val);
- break;
- case 5:
- dst += convertVerbMessage(dst, end - dst, val);
- break;
- case 6:
- dst += convertNameMessage(dst, end - dst, val);
- break;
- case 7:
- dst += convertStringMessage(dst, end - dst, val);
- break;
- case 9:
- case 10:
- case 12:
- case 13:
- case 14:
- // Simply copy these special codes
- *dst++ = 0xFF;
- *dst++ = chr;
- *dst++ = src[num+0];
- *dst++ = src[num+1];
- if (_version == 8) {
- *dst++ = src[num+2];
- *dst++ = src[num+3];
- }
- break;
- default:
- error("convertMessageToString(): string escape sequence %d unknown", chr);
- }
- num += (_version == 8) ? 4 : 2;
- }
- } else {
- if (!(chr == '@' && _heversion <= 71)) {
- *dst++ = chr;
- }
- }
-
- // Check for a buffer overflow
- if (dst >= end)
- error("convertMessageToString: buffer overflow!");
- }
- *dst = 0;
-
- return dstSize - (end - dst);
-}
-
-int ScummEngine::convertIntMessage(byte *dst, int dstSize, int var) {
- int num;
-
- num = readVar(var);
- return snprintf((char *)dst, dstSize, "%d", num);
-}
-
-int ScummEngine::convertVerbMessage(byte *dst, int dstSize, int var) {
- int num, k;
-
- num = readVar(var);
- if (num) {
- for (k = 1; k < _numVerbs; k++) {
- if (num == _verbs[k].verbid && !_verbs[k].type && !_verbs[k].saveid) {
- const byte *ptr = getResourceAddress(rtVerb, k);
- return convertMessageToString(ptr, dst, dstSize);
- }
- }
- }
- return 0;
-}
-
-int ScummEngine::convertNameMessage(byte *dst, int dstSize, int var) {
- int num;
-
- num = readVar(var);
- if (num) {
- const byte *ptr = getObjOrActorName(num);
- if (ptr) {
- return convertMessageToString(ptr, dst, dstSize);
- }
- }
- return 0;
-}
-
-int ScummEngine::convertStringMessage(byte *dst, int dstSize, int var) {
- const byte *ptr;
-
- if (_version <= 2) {
- byte chr;
- int i = 0;
- while ((chr = (byte)_scummVars[var++])) {
- if (chr != '@') {
- *dst++ = chr;
- i++;
- }
- }
-
- return i;
- }
-
- if (_version == 3 || (_version >= 6 && _heversion < 72))
- var = readVar(var);
-
- if (var) {
- ptr = getStringAddress(var);
- if (ptr) {
- return convertMessageToString(ptr, dst, dstSize);
- }
- }
- return 0;
-}
-
-
-#pragma mark -
-#pragma mark --- Charset initialisation ---
-#pragma mark -
-
-
-#ifndef DISABLE_HE
-void ScummEngine_v80he::initCharset(int charsetno) {
- ScummEngine::initCharset(charsetno);
- VAR(VAR_CURRENT_CHARSET) = charsetno;
-}
-#endif
-
-void ScummEngine::initCharset(int charsetno) {
- if (_gameId == GID_FT) {
- if (!res.isResourceLoaded(rtCharset, charsetno))
- loadCharset(charsetno);
- } else {
- if (!getResourceAddress(rtCharset, charsetno))
- loadCharset(charsetno);
- }
-
- _string[0]._default.charset = charsetno;
- _string[1]._default.charset = charsetno;
-
- memcpy(_charsetColorMap, _charsetData[charsetno], sizeof(_charsetColorMap));
-}
-
-
-#pragma mark -
-#pragma mark --- Translation/localization code ---
-#pragma mark -
-
-
-#ifndef DISABLE_SCUMM_7_8
-static int indexCompare(const void *p1, const void *p2) {
- const ScummEngine_v7::LangIndexNode *i1 = (const ScummEngine_v7::LangIndexNode *) p1;
- const ScummEngine_v7::LangIndexNode *i2 = (const ScummEngine_v7::LangIndexNode *) p2;
-
- return strcmp(i1->tag, i2->tag);
-}
-
-// Create an index of the language file.
-void ScummEngine_v7::loadLanguageBundle() {
- ScummFile file;
- int32 size;
-
- if (_gameId == GID_DIG) {
- openFile(file, "language.bnd");
- } else if (_gameId == GID_CMI) {
- openFile(file, "language.tab");
- } else {
- return;
- }
- if (file.isOpen() == false) {
- _existLanguageFile = false;
- return;
- }
-
- _existLanguageFile = true;
-
- size = file.size();
- _languageBuffer = (char *)calloc(1, size+1);
- file.read(_languageBuffer, size);
- file.close();
-
- int32 i;
- char *ptr = _languageBuffer;
-
- // Count the number of lines in the language file.
- for (_languageIndexSize = 0; ; _languageIndexSize++) {
- ptr = strpbrk(ptr, "\n\r");
- if (ptr == NULL)
- break;
- while (*ptr == '\n' || *ptr == '\r')
- ptr++;
- }
-
- // Fill the language file index. This is just an array of
- // tags and offsets. I did consider using a balanced tree
- // instead, but the extra overhead in the node structure would
- // easily have doubled the memory consumption of the index.
- // And anyway, using qsort + bsearch gives us the exact same
- // O(log(n)) access time anyway ;-).
-
- _languageIndex = (LangIndexNode *)calloc(_languageIndexSize, sizeof(LangIndexNode));
-
- ptr = _languageBuffer;
-
- if (_gameId == GID_DIG) {
- int lineCount = _languageIndexSize;
- const char *baseTag = "";
- byte enc = 0; // Initially assume the language file is not encoded
-
- // We'll determine the real index size as we go.
- _languageIndexSize = 0;
- for (i = 0; i < lineCount; i++) {
- if (*ptr == '!') {
- // Don't know what a line with '!' means, just ignore it
- } else if (*ptr == 'h') {
- // File contains Korean text (Hangul). just ignore it
- } else if (*ptr == 'e') {
- // File is encoded!
- enc = 0x13;
- } else if (*ptr == '@') {
- // A new 'base tag'
- baseTag = ptr + 1;
- } else if (*ptr == '#') {
- // Number of subtags following a given basetag. We don't need that
- // information so we just skip it
- } else if (isdigit(*ptr)) {
- int idx = 0;
- // A number (up to three digits)...
- while (isdigit(*ptr)) {
- idx = idx * 10 + (*ptr - '0');
- ptr++;
- }
-
- // ...followed by a slash...
- assert(*ptr == '/');
- ptr++;
-
- // ...and then the translated message, possibly encoded
- _languageIndex[_languageIndexSize].offset = ptr - _languageBuffer;
-
- // Decode string if necessary.
- if (enc) {
- while (*ptr != '\n' && *ptr != '\r')
- *ptr++ ^= enc;
- }
-
- // The tag is the basetag, followed by a dot and then the index
- sprintf(_languageIndex[_languageIndexSize].tag, "%s.%03d", baseTag, idx);
-
- // That was another index entry
- _languageIndexSize++;
- } else {
- error("Unknwon languag.bnd entry found: '%s'\n", ptr);
- }
-
- // Skip over newlines (and turn them into null bytes)
- ptr = strpbrk(ptr, "\n\r");
- if (ptr == NULL)
- break;
- while (*ptr == '\n' || *ptr == '\r')
- *ptr++ = 0;
- }
- } else {
- for (i = 0; i < _languageIndexSize; i++) {
- // First 8 chars in the line give the string ID / 'tag'
- int j;
- for (j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
- _languageIndex[i].tag[j] = toupper(*ptr);
- _languageIndex[i].tag[j] = 0;
-
- // After that follows a single space which we skip
- assert(isspace(*ptr));
- ptr++;
-
- // Then comes the translated string: we record an offset to that.
- _languageIndex[i].offset = ptr - _languageBuffer;
-
- // Skip over newlines (and turn them into null bytes)
- ptr = strpbrk(ptr, "\n\r");
- if (ptr == NULL)
- break;
- while (*ptr == '\n' || *ptr == '\r')
- *ptr++ = 0;
-
- // Convert '\n' code to a newline. See also bug #902415.
- char *src, *dst;
- src = dst = _languageBuffer + _languageIndex[i].offset;
- while (*src) {
- if (src[0] == '\\' && src[1] == 'n') {
- *dst++ = '\n';
- src += 2;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
- }
- }
-
- // Sort the index nodes. We'll later use bsearch on it, which is just as efficient
- // as using a binary tree, speed wise.
- qsort(_languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare);
-}
-
-void ScummEngine_v7::playSpeech(const byte *ptr) {
- if ((_gameId == GID_DIG || _gameId == GID_CMI) && ptr[0]) {
- char pointer[20];
- strcpy(pointer, (const char *)ptr);
-
- // Play speech
- if (!(_features & GF_DEMO) && (_gameId == GID_CMI)) // CMI demo does not have .IMX for voice
- strcat(pointer, ".IMX");
-
- _sound->stopTalkSound();
- _imuseDigital->stopSound(kTalkSoundID);
- _imuseDigital->startVoice(kTalkSoundID, pointer);
- _sound->talkSound(0, 0, 2);
- }
-}
-
-void ScummEngine_v7::translateText(const byte *text, byte *trans_buff) {
- LangIndexNode target;
- LangIndexNode *found = NULL;
- int i;
-
- trans_buff[0] = 0;
- _lastStringTag[0] = 0;
-
- // WORKAROUND for bug #1172655.
- if (_gameId == GID_DIG && text[0] != '/') {
- if (!strcmp((const char *)text, "faint light"))
- text = (const byte *)"/NEW.007/faint light";
- else if (!strcmp((const char *)text, "glowing crystal"))
- text = (const byte *)"/NEW.008/glowing crystal";
- else if (!strcmp((const char *)text, "glowing crystals"))
- text = (const byte *)"/NEW.009/glowing crystals";
- else if (!strcmp((const char *)text, "pit"))
- text = (const byte *)"/NEW.010/pit";
- else if (!strcmp((const char *)text, "You wish."))
- text = (const byte *)"/NEW.011/You wish.";
- else if (!strcmp((const char *)text, "In your dreams."))
- text = (const byte *)"/NEW.012/In your dreams";
- else if (!strcmp((const char *)text, "left"))
- text = (const byte *)"/CATHPLAT.068/left";
- else if (!strcmp((const char *)text, "right"))
- text = (const byte *)"/CATHPLAT.070/right";
- else if (!strcmp((const char *)text, "right"))
- text = (const byte *)"/CATHPLAT.067/top";
- else if (!strcmp((const char *)text, "exit"))
- text = (const byte *)"/SKY.008/exit";
- else if (!strcmp((const char *)text, "unattached lens"))
- text = (const byte *)"/NEW.013/unattached lens";
- else if (!strcmp((const char *)text, "lens slot"))
- text = (const byte *)"/NEW.014/lens slot";
- }
-
-
- if (_version >= 7 && text[0] == '/') {
- // Extract the string tag from the text: /..../
- for (i = 0; (i < 12) && (text[i + 1] != '/'); i++)
- _lastStringTag[i] = target.tag[i] = toupper(text[i + 1]);
- _lastStringTag[i] = target.tag[i] = 0;
- text += i + 2;
-
- // If a language file was loaded, try to find a translated version
- // by doing a lookup on the string tag.
- if (_existLanguageFile) {
- // HACK: These are used for the object line in COMI when
- // using one object on another. I don't know if the
- // text in the language file is a placeholder or if
- // we're supposed to use it, but at least in the
- // English version things will work so much better if
- // we can't find translations for these.
-
- if (*text && strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0)
- found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageIndexSize, sizeof(LangIndexNode), indexCompare);
- }
- }
-
- if (found != NULL) {
- strcpy((char *)trans_buff, _languageBuffer + found->offset);
-
- if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) {
- // Replace any '%___' by the corresponding special codes in the source text
- const byte *src = text;
- char *dst = (char *)trans_buff;
-
- while ((dst = strstr(dst, "%___"))) {
- // Search for a special code in the message.
- while (*src && *src != 0xFF) {
- src++;
- }
-
- // Replace the %___ by the special code. Luckily, we can do
- // that in-place.
- if (*src == 0xFF) {
- memcpy(dst, src, 4);
- src += 4;
- dst += 4;
- } else
- break;
- }
- }
- } else {
- // Default: just copy the string
- memcpy(trans_buff, text, resStrLen(text) + 1);
- }
-}
-
-#endif
-
-void ScummEngine::translateText(const byte *text, byte *trans_buff) {
- // Default: just copy the string
- memcpy(trans_buff, text, resStrLen(text) + 1);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/thumbnail.cpp b/scumm/thumbnail.cpp
deleted file mode 100644
index eefc34286a..0000000000
--- a/scumm/thumbnail.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed file the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/system.h"
-#include "common/savefile.h"
-#include "common/scaler.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-#define THMB_VERSION 1
-
-#if !defined(__GNUC__)
- #pragma START_PACK_STRUCTS
-#endif
-
-struct ThumbnailHeader {
- uint32 type;
- uint32 size;
- byte version;
- uint16 width, height;
- byte bpp;
-} GCC_PACK;
-
-#if !defined(__GNUC__)
- #pragma END_PACK_STRUCTS
-#endif
-
-
-inline void colorToRGB(uint16 color, uint8 &r, uint8 &g, uint8 &b) {
- r = (((color >> 11) & 0x1F) << 3);
- g = (((color >> 5) & 0x3F) << 2);
- b = ((color&0x1F) << 3);
-}
-
-Graphics::Surface *ScummEngine::loadThumbnail(Common::InSaveFile *file) {
- ThumbnailHeader header;
- file->read(&header.type, 4);
- // We also accept the bad 'BMHT' header here, for the sake of compatibility
- // with some older savegames which were written incorrectly due to a bug in
- // ScummVM which wrote the thumb header type incorrectly on LE systems.
- if (header.type != MKID('THMB') && header.type != MKID('BMHT'))
- return 0;
-
- header.size = file->readUint32BE();
- header.version = file->readByte();
-
- if (header.version > THMB_VERSION) {
- file->skip(header.size - 9);
- warning("Loading a newer thumbnail version");
- return 0;
- }
-
- header.width = file->readUint16BE();
- header.height = file->readUint16BE();
- header.bpp = file->readByte();
-
- // TODO: support other bpp values than 2
- if (header.bpp != 2) {
- file->skip(header.size - 14);
- return 0;
- }
-
- Graphics::Surface *thumb = new Graphics::Surface();
- thumb->create(header.width, header.height, sizeof(uint16));
-
- uint16* pixels = (uint16 *)thumb->pixels;
-
- for (int y = 0; y < thumb->h; ++y) {
- for (int x = 0; x < thumb->w; ++x) {
- uint8 r, g, b;
- colorToRGB(file->readUint16BE(), r, g, b);
-
- // converting to current OSystem Color
- *pixels++ = _system->RGBToColor(r, g, b);
- }
- }
-
- return thumb;
-}
-
-void ScummEngine::saveThumbnail(Common::OutSaveFile *file) {
- Graphics::Surface thumb;
-
-#ifndef PALMOS_68K
- if (!createThumbnailFromScreen(&thumb))
-#endif
- thumb.create(kThumbnailWidth, kThumbnailHeight2, sizeof(uint16));
-
- ThumbnailHeader header;
- header.type = MKID('THMB');
-#if defined(PALMOS_ARM) || defined(__GP32__)
- // sizeof(header) is hardcoded here, because the compiler add padding to
- // have a 4byte aligned struct and there is no easy way to pack it.
- header.size = 14 + thumb.w*thumb.h*thumb.bytesPerPixel;
-#else
- header.size = sizeof(header) + thumb.w*thumb.h*thumb.bytesPerPixel;
-#endif
- header.version = THMB_VERSION;
- header.width = thumb.w;
- header.height = thumb.h;
- header.bpp = thumb.bytesPerPixel;
-
- file->write(&header.type, 4);
- file->writeUint32BE(header.size);
- file->writeByte(header.version);
- file->writeUint16BE(header.width);
- file->writeUint16BE(header.height);
- file->writeByte(header.bpp);
-
- // TODO: for later this shouldn't be casted to uint16...
- uint16* pixels = (uint16 *)thumb.pixels;
- for (uint16 p = 0; p < thumb.w*thumb.h; ++p, ++pixels)
- file->writeUint16BE(*pixels);
-
- thumb.free();
-}
-
-} // end of namespace Scumm
diff --git a/scumm/usage_bits.cpp b/scumm/usage_bits.cpp
deleted file mode 100644
index 3fd90311fd..0000000000
--- a/scumm/usage_bits.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/scumm.h"
-#include "scumm/usage_bits.h"
-
-namespace Scumm {
-
-void ScummEngine::upgradeGfxUsageBits() {
- int i;
-
- for (i = 409; i >= 0; i--) {
- bool dirty_bit = ((gfxUsageBits[i] & 0x80000000) != 0);
- bool restored_bit = ((gfxUsageBits[i] & 0x40000000) != 0);
-
- gfxUsageBits[3 * i] = gfxUsageBits[i] & 0x3FFFFFFF;
- if (dirty_bit)
- setGfxUsageBit(i, USAGE_BIT_DIRTY);
- if (restored_bit)
- setGfxUsageBit(i, USAGE_BIT_RESTORED);
- }
-}
-
-void ScummEngine::setGfxUsageBit(int strip, int bit) {
- assert(strip >= 0 && strip < ARRAYSIZE(gfxUsageBits) / 3);
- assert(1 <= bit && bit <= 96);
- bit--;
- gfxUsageBits[3 * strip + bit / 32] |= (1 << (bit % 32));
-}
-
-void ScummEngine::clearGfxUsageBit(int strip, int bit) {
- assert(strip >= 0 && strip < ARRAYSIZE(gfxUsageBits) / 3);
- assert(1 <= bit && bit <= 96);
- bit--;
- gfxUsageBits[3 * strip + bit / 32] &= ~(1 << (bit % 32));
-}
-
-bool ScummEngine::testGfxUsageBit(int strip, int bit) {
- assert(strip >= 0 && strip < ARRAYSIZE(gfxUsageBits) / 3);
- assert(1 <= bit && bit <= 96);
- bit--;
- return (gfxUsageBits[3 * strip + bit / 32] & (1 << (bit % 32))) != 0;
-}
-
-bool ScummEngine::testGfxAnyUsageBits(int strip) {
- // Exclude the DIRTY and RESTORED bits from the test
- uint32 bitmask[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0x3FFFFFFF };
- int i;
-
- assert(strip >= 0 && strip < ARRAYSIZE(gfxUsageBits) / 3);
- for (i = 0; i < 3; i++)
- if (gfxUsageBits[3 * strip + i] & bitmask[i])
- return true;
-
- return false;
-}
-
-bool ScummEngine::testGfxOtherUsageBits(int strip, int bit) {
- // Don't exclude the DIRTY and RESTORED bits from the test
- uint32 bitmask[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- int i;
-
- assert(strip >= 0 && strip < ARRAYSIZE(gfxUsageBits) / 3);
- assert(1 <= bit && bit <= 96);
- bit--;
- bitmask[bit / 32] &= ~(1 << (bit % 32));
-
- for (i = 0; i < 3; i++)
- if (gfxUsageBits[3 * strip + i] & bitmask[i])
- return true;
-
- return false;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/usage_bits.h b/scumm/usage_bits.h
deleted file mode 100644
index 36fd7cc610..0000000000
--- a/scumm/usage_bits.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef USAGE_BITS_H
-#define USAGE_BITS_H
-
-namespace Scumm {
-
-enum {
- USAGE_BIT_DIRTY = 96,
- USAGE_BIT_RESTORED = 95
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/util.cpp b/scumm/util.cpp
deleted file mode 100644
index 70e3a3e467..0000000000
--- a/scumm/util.cpp
+++ /dev/null
@@ -1,1818 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "scumm/util.h"
-#include "common/util.h"
-#include "common/md5.h"
-
-using Common::File;
-
-namespace Scumm {
-
-#pragma mark -
-#pragma mark --- ScummFile ---
-#pragma mark -
-
-ScummFile::ScummFile() : _encbyte(0), _subFileStart(0), _subFileLen(0) {
-}
-
-void ScummFile::setEnc(byte value) {
- _encbyte = value;
-}
-
-void ScummFile::setSubfileRange(uint32 start, uint32 len) {
- // TODO: Add sanity checks
- const uint32 fileSize = File::size();
- assert(start <= fileSize);
- assert(start + len <= fileSize);
- _subFileStart = start;
- _subFileLen = len;
- seek(0, SEEK_SET);
-}
-
-void ScummFile::resetSubfile() {
- _subFileStart = 0;
- _subFileLen = 0;
- seek(0, SEEK_SET);
-}
-
-bool ScummFile::open(const char *filename, AccessMode mode) {
- if (File::open(filename, mode)) {
- resetSubfile();
- return true;
- } else {
- return false;
- }
-}
-
-bool ScummFile::openSubFile(const char *filename) {
- assert(isOpen());
-
- // Disable the XOR encryption and reset any current subfile range
- setEnc(0);
- resetSubfile();
-
- // Read in the filename table and look for the specified file
-
- unsigned long file_off, file_len;
- char file_name[0x20+1];
- unsigned long i;
-
- // Get the length of the data file to use for consistency checks
- const uint32 data_file_len = size();
-
- // Read offset and length to the file records */
- const uint32 file_record_off = readUint32BE();
- const uint32 file_record_len = readUint32BE();
-
- // Do a quick check to make sure the offset and length are good
- if (file_record_off + file_record_len > data_file_len) {
- return false;
- }
-
- // Do a little consistancy check on file_record_length
- if (file_record_len % 0x28) {
- return false;
- }
-
- // Scan through the files
- for (i = 0; i < file_record_len; i += 0x28) {
- // read a file record
- seek(file_record_off + i, SEEK_SET);
- file_off = readUint32BE();
- file_len = readUint32BE();
- read(file_name, 0x20);
- file_name[0x20] = 0;
-
- assert(file_name[0]);
- //debug(7, " extracting \'%s\'", file_name);
-
- // Consistency check. make sure the file data is in the file
- if (file_off + file_len > data_file_len) {
- return false;
- }
-
- if (scumm_stricmp(file_name, filename) == 0) {
- // We got a match!
- setSubfileRange(file_off, file_len);
- return true;
- }
- }
-
- return false;
-}
-
-
-bool ScummFile::eof() {
- return _subFileLen ? (pos() >= _subFileLen) : File::eof();
-}
-
-uint32 ScummFile::pos() {
- return File::pos() - _subFileStart;
-}
-
-uint32 ScummFile::size() {
- return _subFileLen ? _subFileLen : File::size();
-}
-
-void ScummFile::seek(int32 offs, int whence) {
- if (_subFileLen) {
- // Constrain the seek to the subfile
- switch (whence) {
- case SEEK_END:
- offs = _subFileStart + _subFileLen - offs;
- break;
- case SEEK_SET:
- offs += _subFileStart;
- break;
- case SEEK_CUR:
- offs += File::pos();
- break;
- }
- assert((int32)_subFileStart <= offs && offs <= (int32)(_subFileStart + _subFileLen));
- whence = SEEK_SET;
- }
- File::seek(offs, whence);
-}
-
-uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
- uint32 realLen;
-
- if (_subFileLen) {
- // Limit the amount we read by the subfile boundaries.
- const uint32 curPos = pos();
- assert(_subFileLen >= curPos);
- uint32 newPos = curPos + dataSize;
- if (newPos > _subFileLen) {
- dataSize = _subFileLen - curPos;
- _ioFailed = true;
- }
- }
-
- realLen = File::read(dataPtr, dataSize);
-
-
- // If an encryption byte was specified, XOR the data we just read by it.
- // This simple kind of "encryption" was used by some of the older SCUMM
- // games.
- if (_encbyte) {
- byte *p = (byte *)dataPtr;
- byte *end = p + realLen;
- while (p < end)
- *p++ ^= _encbyte;
- }
-
- return realLen;
-}
-
-uint32 ScummFile::write(const void *, uint32) {
- error("ScummFile does not support writing!");
- return 0;
-}
-
-#pragma mark -
-#pragma mark --- Utilities ---
-#pragma mark -
-
-void checkRange(int max, int min, int no, const char *str) {
- if (no < min || no > max) {
- char buf[256];
- snprintf(buf, sizeof(buf), str, no);
- error("Value %d is out of bounds (%d,%d) (%s)", no, min, max, buf);
- }
-}
-
-/**
- * Convert an old style direction to a new style one (angle),
- */
-int newDirToOldDir(int dir) {
- if (dir >= 71 && dir <= 109)
- return 1;
- if (dir >= 109 && dir <= 251)
- return 2;
- if (dir >= 251 && dir <= 289)
- return 0;
- return 3;
-}
-
-/**
- * Convert an new style (angle) direction to an old style one.
- */
-int oldDirToNewDir(int dir) {
- assert(0 <= dir && dir <= 3);
- const int new_dir_table[4] = { 270, 90, 180, 0 };
- return new_dir_table[dir];
-}
-
-/**
- * Convert an angle to a simple direction.
- */
-int toSimpleDir(int dirType, int dir) {
- if (dirType) {
- const int16 directions[] = { 22, 72, 107, 157, 202, 252, 287, 337 };
- for (int i = 0; i < 7; i++)
- if (dir >= directions[i] && dir <= directions[i+1])
- return i+1;
- } else {
- const int16 directions[] = { 71, 109, 251, 289 };
- for (int i = 0; i < 3; i++)
- if (dir >= directions[i] && dir <= directions[i+1])
- return i+1;
- }
-
- return 0;
-}
-
-/**
- * Convert a simple direction to an angle.
- */
-int fromSimpleDir(int dirType, int dir) {
- if (dirType)
- return dir * 45;
- else
- return dir * 90;
-}
-
-/**
- * Normalize the given angle - that means, ensure it is positive, and
- * change it to the closest multiple of 45 degree by abusing toSimpleDir.
- */
-int normalizeAngle(int angle) {
- int temp;
-
- temp = (angle + 360) % 360;
-
- return toSimpleDir(1, temp) * 45;
-}
-
-const char *tag2str(uint32 tag) {
- static char str[5];
- str[0] = (char)(tag >> 24);
- str[1] = (char)(tag >> 16);
- str[2] = (char)(tag >> 8);
- str[3] = (char)tag;
- str[4] = '\0';
- return str;
-}
-
-#pragma mark -
-#pragma mark --- ScummNESFile ---
-#pragma mark -
-
-enum ResType {
- NES_UNKNOWN,
- NES_GLOBDATA,
- NES_ROOM,
- NES_SCRIPT,
- NES_SOUND,
- NES_COSTUME,
- NES_ROOMGFX,
- NES_COSTUMEGFX,
- NES_SPRPALS,
- NES_SPRDESC,
- NES_SPRLENS,
- NES_SPROFFS,
- NES_SPRDATA,
- NES_CHARSET,
- NES_PREPLIST
-};
-
-struct ScummNESFile::Resource {
- uint32 offset;
- uint16 length;
- ResType type;
-};
-
-ScummNESFile::ScummNESFile() : _stream(0), _buf(0), _ROMset(kROMsetNum) {
-}
-
-uint32 ScummNESFile::write(const void *, uint32) {
- error("ScummNESFile does not support writing!");
- return 0;
-}
-
-void ScummNESFile::setEnc(byte enc) {
- _stream->setEnc(enc);
-}
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_roomgfx_usa;
-static ScummNESFile::Resource *res_roomgfx_eur;
-static ScummNESFile::Resource *res_roomgfx_swe;
-static ScummNESFile::Resource *res_roomgfx_fra;
-static ScummNESFile::Resource *res_roomgfx_ger;
-#else
-static ScummNESFile::Resource res_roomgfx_usa[40] = {
- { 0x04001, 0x03C9, NES_ROOMGFX }, { 0x043CA, 0x069E, NES_ROOMGFX }, { 0x04A68, 0x0327, NES_ROOMGFX }, { 0x04D8F, 0x053B, NES_ROOMGFX }, { 0x052CA, 0x06BE, NES_ROOMGFX },
- { 0x05988, 0x0682, NES_ROOMGFX }, { 0x0600A, 0x0778, NES_ROOMGFX }, { 0x06782, 0x0517, NES_ROOMGFX }, { 0x06C99, 0x07FB, NES_ROOMGFX }, { 0x07494, 0x07BE, NES_ROOMGFX },
- { 0x08001, 0x07A5, NES_ROOMGFX }, { 0x087A6, 0x06DD, NES_ROOMGFX }, { 0x08E83, 0x04EA, NES_ROOMGFX }, { 0x0936D, 0x0846, NES_ROOMGFX }, { 0x09BB3, 0x08C8, NES_ROOMGFX },
- { 0x0A47B, 0x0844, NES_ROOMGFX }, { 0x0ACBF, 0x0515, NES_ROOMGFX }, { 0x0B1D4, 0x0799, NES_ROOMGFX }, { 0x0B96D, 0x04BB, NES_ROOMGFX }, { 0x07C52, 0x0319, NES_ROOMGFX },
- { 0x0C001, 0x0464, NES_ROOMGFX }, { 0x0C465, 0x076D, NES_ROOMGFX }, { 0x0CBD2, 0x0827, NES_ROOMGFX }, { 0x0D3F9, 0x0515, NES_ROOMGFX }, { 0x0D90E, 0x064E, NES_ROOMGFX },
- { 0x0DF5C, 0x0775, NES_ROOMGFX }, { 0x0E6D1, 0x06DD, NES_ROOMGFX }, { 0x0EDAE, 0x0376, NES_ROOMGFX }, { 0x0F124, 0x05F7, NES_ROOMGFX }, { 0x0F71B, 0x0787, NES_ROOMGFX },
- { 0x10001, 0x02D6, NES_ROOMGFX }, { 0x102D7, 0x06A3, NES_ROOMGFX }, { 0x1097A, 0x099F, NES_ROOMGFX }, { 0x11319, 0x0361, NES_ROOMGFX }, { 0x1167A, 0x0489, NES_ROOMGFX },
- { 0x11B03, 0x0437, NES_ROOMGFX }, { 0x11F3A, 0x084D, NES_ROOMGFX }, { 0x0BE28, 0x0199, NES_ROOMGFX }, { 0x12787, 0x09A7, NES_ROOMGFX }, { 0x1312E, 0x037A, NES_ROOMGFX }
-};
-static ScummNESFile::Resource res_roomgfx_eur[40] = {
- { 0x04001, 0x03B9, NES_ROOMGFX }, { 0x043BA, 0x069E, NES_ROOMGFX }, { 0x04A58, 0x0327, NES_ROOMGFX }, { 0x04D7F, 0x053B, NES_ROOMGFX }, { 0x052BA, 0x06BE, NES_ROOMGFX },
- { 0x05978, 0x0682, NES_ROOMGFX }, { 0x05FFA, 0x0778, NES_ROOMGFX }, { 0x06772, 0x0517, NES_ROOMGFX }, { 0x06C89, 0x07FB, NES_ROOMGFX }, { 0x07484, 0x07BE, NES_ROOMGFX },
- { 0x08001, 0x07A5, NES_ROOMGFX }, { 0x087A6, 0x06DD, NES_ROOMGFX }, { 0x08E83, 0x04EA, NES_ROOMGFX }, { 0x0936D, 0x0846, NES_ROOMGFX }, { 0x09BB3, 0x08C8, NES_ROOMGFX },
- { 0x0A47B, 0x0844, NES_ROOMGFX }, { 0x0ACBF, 0x0515, NES_ROOMGFX }, { 0x0B1D4, 0x0799, NES_ROOMGFX }, { 0x0B96D, 0x04BB, NES_ROOMGFX }, { 0x07C42, 0x0319, NES_ROOMGFX },
- { 0x0C001, 0x0464, NES_ROOMGFX }, { 0x0C465, 0x076D, NES_ROOMGFX }, { 0x0CBD2, 0x0827, NES_ROOMGFX }, { 0x0D3F9, 0x0515, NES_ROOMGFX }, { 0x0D90E, 0x064E, NES_ROOMGFX },
- { 0x0DF5C, 0x0775, NES_ROOMGFX }, { 0x0E6D1, 0x06DD, NES_ROOMGFX }, { 0x0EDAE, 0x0376, NES_ROOMGFX }, { 0x0F124, 0x05F7, NES_ROOMGFX }, { 0x0F71B, 0x0787, NES_ROOMGFX },
- { 0x10001, 0x02D6, NES_ROOMGFX }, { 0x102D7, 0x06A3, NES_ROOMGFX }, { 0x1097A, 0x099F, NES_ROOMGFX }, { 0x11319, 0x0361, NES_ROOMGFX }, { 0x1167A, 0x0489, NES_ROOMGFX },
- { 0x11B03, 0x0437, NES_ROOMGFX }, { 0x11F3A, 0x084D, NES_ROOMGFX }, { 0x12787, 0x0199, NES_ROOMGFX }, { 0x12920, 0x09A7, NES_ROOMGFX }, { 0x132C7, 0x037A, NES_ROOMGFX }
-};
-static ScummNESFile::Resource res_roomgfx_swe[40] = {
- { 0x04001, 0x03F0, NES_ROOMGFX }, { 0x043F1, 0x069E, NES_ROOMGFX }, { 0x04A8F, 0x0327, NES_ROOMGFX }, { 0x04DB6, 0x053B, NES_ROOMGFX }, { 0x052F1, 0x06BE, NES_ROOMGFX },
- { 0x059AF, 0x0682, NES_ROOMGFX }, { 0x06031, 0x0778, NES_ROOMGFX }, { 0x067A9, 0x0517, NES_ROOMGFX }, { 0x06CC0, 0x07FB, NES_ROOMGFX }, { 0x074BB, 0x07BE, NES_ROOMGFX },
- { 0x08001, 0x07A5, NES_ROOMGFX }, { 0x087A6, 0x06DD, NES_ROOMGFX }, { 0x08E83, 0x04EA, NES_ROOMGFX }, { 0x0936D, 0x07E2, NES_ROOMGFX }, { 0x09B4F, 0x0791, NES_ROOMGFX },
- { 0x0A2E0, 0x07B5, NES_ROOMGFX }, { 0x0AA95, 0x0515, NES_ROOMGFX }, { 0x0AFAA, 0x0799, NES_ROOMGFX }, { 0x0B743, 0x04BF, NES_ROOMGFX }, { 0x0BC02, 0x0319, NES_ROOMGFX },
- { 0x0C001, 0x0464, NES_ROOMGFX }, { 0x0C465, 0x072C, NES_ROOMGFX }, { 0x0CB91, 0x0827, NES_ROOMGFX }, { 0x0D3B8, 0x0515, NES_ROOMGFX }, { 0x0D8CD, 0x064E, NES_ROOMGFX },
- { 0x0DF1B, 0x0775, NES_ROOMGFX }, { 0x0E690, 0x06DD, NES_ROOMGFX }, { 0x0ED6D, 0x0376, NES_ROOMGFX }, { 0x0F0E3, 0x05F7, NES_ROOMGFX }, { 0x0F6DA, 0x0791, NES_ROOMGFX },
- { 0x07C79, 0x02D6, NES_ROOMGFX }, { 0x10001, 0x06A3, NES_ROOMGFX }, { 0x106A4, 0x0921, NES_ROOMGFX }, { 0x10FC5, 0x0361, NES_ROOMGFX }, { 0x11326, 0x0489, NES_ROOMGFX },
- { 0x117AF, 0x0437, NES_ROOMGFX }, { 0x11BE6, 0x084F, NES_ROOMGFX }, { 0x12435, 0x0199, NES_ROOMGFX }, { 0x125CE, 0x0947, NES_ROOMGFX }, { 0x12F15, 0x037A, NES_ROOMGFX }
-};
-static ScummNESFile::Resource res_roomgfx_fra[40] = {
- { 0x04001, 0x0426, NES_ROOMGFX }, { 0x04427, 0x069E, NES_ROOMGFX }, { 0x04AC5, 0x0327, NES_ROOMGFX }, { 0x04DEC, 0x053B, NES_ROOMGFX }, { 0x05327, 0x06BE, NES_ROOMGFX },
- { 0x059E5, 0x0682, NES_ROOMGFX }, { 0x06067, 0x0778, NES_ROOMGFX }, { 0x067DF, 0x0517, NES_ROOMGFX }, { 0x06CF6, 0x07FB, NES_ROOMGFX }, { 0x074F1, 0x07BE, NES_ROOMGFX },
- { 0x08001, 0x07A5, NES_ROOMGFX }, { 0x087A6, 0x06DD, NES_ROOMGFX }, { 0x08E83, 0x04EA, NES_ROOMGFX }, { 0x0936D, 0x07E2, NES_ROOMGFX }, { 0x09B4F, 0x0791, NES_ROOMGFX },
- { 0x0A2E0, 0x07B5, NES_ROOMGFX }, { 0x0AA95, 0x0515, NES_ROOMGFX }, { 0x0AFAA, 0x0799, NES_ROOMGFX }, { 0x0B743, 0x04BB, NES_ROOMGFX }, { 0x0BBFE, 0x0319, NES_ROOMGFX },
- { 0x0C001, 0x0464, NES_ROOMGFX }, { 0x0C465, 0x072C, NES_ROOMGFX }, { 0x0CB91, 0x0827, NES_ROOMGFX }, { 0x0D3B8, 0x0515, NES_ROOMGFX }, { 0x0D8CD, 0x064E, NES_ROOMGFX },
- { 0x0DF1B, 0x0775, NES_ROOMGFX }, { 0x0E690, 0x06DD, NES_ROOMGFX }, { 0x0ED6D, 0x0376, NES_ROOMGFX }, { 0x0F0E3, 0x05F7, NES_ROOMGFX }, { 0x0F6DA, 0x0787, NES_ROOMGFX },
- { 0x10001, 0x02D6, NES_ROOMGFX }, { 0x102D7, 0x06A3, NES_ROOMGFX }, { 0x1097A, 0x0921, NES_ROOMGFX }, { 0x1129B, 0x0361, NES_ROOMGFX }, { 0x115FC, 0x0489, NES_ROOMGFX },
- { 0x11A85, 0x0437, NES_ROOMGFX }, { 0x11EBC, 0x070D, NES_ROOMGFX }, { 0x07CAF, 0x0199, NES_ROOMGFX }, { 0x125C9, 0x0947, NES_ROOMGFX }, { 0x12F10, 0x037A, NES_ROOMGFX }
-};
-static ScummNESFile::Resource res_roomgfx_ger[40] = {
- { 0x04001, 0x0406, NES_ROOMGFX }, { 0x04407, 0x069E, NES_ROOMGFX }, { 0x04AA5, 0x0327, NES_ROOMGFX }, { 0x04DCC, 0x053B, NES_ROOMGFX }, { 0x05307, 0x06BE, NES_ROOMGFX },
- { 0x059C5, 0x0682, NES_ROOMGFX }, { 0x06047, 0x0778, NES_ROOMGFX }, { 0x067BF, 0x0517, NES_ROOMGFX }, { 0x06CD6, 0x07FB, NES_ROOMGFX }, { 0x074D1, 0x07BE, NES_ROOMGFX },
- { 0x08001, 0x07A5, NES_ROOMGFX }, { 0x087A6, 0x06DD, NES_ROOMGFX }, { 0x08E83, 0x04EA, NES_ROOMGFX }, { 0x0936D, 0x07E2, NES_ROOMGFX }, { 0x09B4F, 0x0791, NES_ROOMGFX },
- { 0x0A2E0, 0x07B5, NES_ROOMGFX }, { 0x0AA95, 0x0515, NES_ROOMGFX }, { 0x0AFAA, 0x0799, NES_ROOMGFX }, { 0x0B743, 0x04BB, NES_ROOMGFX }, { 0x0BBFE, 0x0319, NES_ROOMGFX },
- { 0x0C001, 0x0464, NES_ROOMGFX }, { 0x0C465, 0x072C, NES_ROOMGFX }, { 0x0CB91, 0x0827, NES_ROOMGFX }, { 0x0D3B8, 0x0515, NES_ROOMGFX }, { 0x0D8CD, 0x064E, NES_ROOMGFX },
- { 0x0DF1B, 0x0775, NES_ROOMGFX }, { 0x0E690, 0x06DD, NES_ROOMGFX }, { 0x0ED6D, 0x0376, NES_ROOMGFX }, { 0x0F0E3, 0x05F7, NES_ROOMGFX }, { 0x0F6DA, 0x0787, NES_ROOMGFX },
- { 0x07C8F, 0x02D6, NES_ROOMGFX }, { 0x10001, 0x06A3, NES_ROOMGFX }, { 0x106A4, 0x0921, NES_ROOMGFX }, { 0x10FC5, 0x0361, NES_ROOMGFX }, { 0x11326, 0x0489, NES_ROOMGFX },
- { 0x117AF, 0x0437, NES_ROOMGFX }, { 0x11BE6, 0x07A0, NES_ROOMGFX }, { 0x12386, 0x0199, NES_ROOMGFX }, { 0x1251F, 0x0947, NES_ROOMGFX }, { 0x12E66, 0x037A, NES_ROOMGFX }
-};
-#endif
-static ScummNESFile::Resource *res_roomgfx[ScummNESFile::kROMsetNum] = {
- res_roomgfx_usa,
- res_roomgfx_eur,
- res_roomgfx_swe,
- res_roomgfx_fra,
- res_roomgfx_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_costumegfx_usa;
-static ScummNESFile::Resource *res_costumegfx_eur;
-static ScummNESFile::Resource *res_costumegfx_swe;
-static ScummNESFile::Resource *res_costumegfx_fra;
-static ScummNESFile::Resource *res_costumegfx_ger;
-#else
-static ScummNESFile::Resource res_costumegfx_usa[2] = { { 0x30001, 0x0EB8, NES_COSTUMEGFX }, { 0x2F9F1, 0x0340, NES_COSTUMEGFX } };
-static ScummNESFile::Resource res_costumegfx_eur[2] = { { 0x30001, 0x0EB8, NES_COSTUMEGFX }, { 0x2F9F1, 0x0340, NES_COSTUMEGFX } };
-static ScummNESFile::Resource res_costumegfx_swe[2] = { { 0x2EFE1, 0x0EB8, NES_COSTUMEGFX }, { 0x30001, 0x0340, NES_COSTUMEGFX } };
-static ScummNESFile::Resource res_costumegfx_fra[2] = { { 0x30001, 0x0EB8, NES_COSTUMEGFX }, { 0x2F608, 0x0340, NES_COSTUMEGFX } };
-static ScummNESFile::Resource res_costumegfx_ger[2] = { { 0x30001, 0x0EB8, NES_COSTUMEGFX }, { 0x2F4CE, 0x0340, NES_COSTUMEGFX } };
-#endif
-static ScummNESFile::Resource *res_costumegfx[ScummNESFile::kROMsetNum] = {
- res_costumegfx_usa,
- res_costumegfx_eur,
- res_costumegfx_swe,
- res_costumegfx_fra,
- res_costumegfx_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_rooms_usa;
-static ScummNESFile::Resource *res_rooms_eur;
-static ScummNESFile::Resource *res_rooms_swe;
-static ScummNESFile::Resource *res_rooms_fra;
-static ScummNESFile::Resource *res_rooms_ger;
-#else
-static ScummNESFile::Resource res_rooms_usa[55] = {
- { 0x00000, 0x0000, NES_ROOM }, { 0x14001, 0x0D0C, NES_ROOM }, { 0x134A8, 0x04B3, NES_ROOM }, { 0x15397, 0x0849, NES_ROOM }, { 0x15C68, 0x0685, NES_ROOM },
- { 0x16381, 0x0715, NES_ROOM }, { 0x1395B, 0x04E7, NES_ROOM }, { 0x16CE8, 0x0AC0, NES_ROOM }, { 0x18001, 0x06BA, NES_ROOM }, { 0x17AED, 0x03CB, NES_ROOM },
- { 0x18BE7, 0x0663, NES_ROOM }, { 0x192A6, 0x0580, NES_ROOM }, { 0x19A44, 0x0443, NES_ROOM }, { 0x1A106, 0x0563, NES_ROOM }, { 0x1A669, 0x0446, NES_ROOM },
- { 0x1AAAF, 0x03A7, NES_ROOM }, { 0x1AE56, 0x07E3, NES_ROOM }, { 0x1B699, 0x0692, NES_ROOM }, { 0x1C001, 0x0B49, NES_ROOM }, { 0x1CD09, 0x04C6, NES_ROOM },
- { 0x1D4C2, 0x0568, NES_ROOM }, { 0x1DF6C, 0x0514, NES_ROOM }, { 0x1E8FA, 0x05CC, NES_ROOM }, { 0x1EF83, 0x0389, NES_ROOM }, { 0x1F5E4, 0x0723, NES_ROOM },
- { 0x20001, 0x049A, NES_ROOM }, { 0x20511, 0x04F8, NES_ROOM }, { 0x21666, 0x05CB, NES_ROOM }, { 0x21DD6, 0x046B, NES_ROOM }, { 0x222F0, 0x0460, NES_ROOM },
- { 0x227B6, 0x0909, NES_ROOM }, { 0x24001, 0x0366, NES_ROOM }, { 0x23BDF, 0x03CA, NES_ROOM }, { 0x247DB, 0x050D, NES_ROOM }, { 0x25ACF, 0x0346, NES_ROOM },
- { 0x1BDBD, 0x01CA, NES_ROOM }, { 0x25E15, 0x0457, NES_ROOM }, { 0x2626C, 0x0547, NES_ROOM }, { 0x267B3, 0x064A, NES_ROOM }, { 0x1FD72, 0x024B, NES_ROOM },
- { 0x2739A, 0x01FA, NES_ROOM }, { 0x2766D, 0x0219, NES_ROOM }, { 0x28001, 0x02F4, NES_ROOM }, { 0x284D6, 0x045C, NES_ROOM }, { 0x289A3, 0x09CF, NES_ROOM },
- { 0x293C6, 0x05A0, NES_ROOM }, { 0x27B65, 0x0201, NES_ROOM }, { 0x2ADD1, 0x0325, NES_ROOM }, { 0x2B339, 0x01FC, NES_ROOM }, { 0x2B535, 0x02A9, NES_ROOM },
- { 0x2B7DE, 0x02DE, NES_ROOM }, { 0x2C001, 0x03CE, NES_ROOM }, { 0x2BBC0, 0x0205, NES_ROOM }, { 0x2C53A, 0x0170, NES_ROOM }, { 0x13E42, 0x0169, NES_ROOM }
-};
-static ScummNESFile::Resource res_rooms_eur[55] = {
- { 0x00000, 0x0000, NES_ROOM }, { 0x14001, 0x0D0C, NES_ROOM }, { 0x13641, 0x04B3, NES_ROOM }, { 0x15397, 0x0849, NES_ROOM }, { 0x15C68, 0x0685, NES_ROOM },
- { 0x16381, 0x0715, NES_ROOM }, { 0x16CE8, 0x04E7, NES_ROOM }, { 0x18001, 0x0ABF, NES_ROOM }, { 0x171CF, 0x06BA, NES_ROOM }, { 0x13AF4, 0x03D2, NES_ROOM },
- { 0x18E1A, 0x0663, NES_ROOM }, { 0x194D9, 0x04A9, NES_ROOM }, { 0x19BA0, 0x0443, NES_ROOM }, { 0x1A262, 0x047C, NES_ROOM }, { 0x1A6DE, 0x0446, NES_ROOM },
- { 0x1AB24, 0x03A7, NES_ROOM }, { 0x1AECB, 0x07E3, NES_ROOM }, { 0x1B70E, 0x0692, NES_ROOM }, { 0x1C001, 0x0ACA, NES_ROOM }, { 0x1CC8A, 0x04C6, NES_ROOM },
- { 0x1D443, 0x0568, NES_ROOM }, { 0x1DEED, 0x0514, NES_ROOM }, { 0x1E87B, 0x05CC, NES_ROOM }, { 0x1EF04, 0x0389, NES_ROOM }, { 0x1F565, 0x0723, NES_ROOM },
- { 0x20001, 0x049A, NES_ROOM }, { 0x20511, 0x04F8, NES_ROOM }, { 0x21666, 0x05D5, NES_ROOM }, { 0x21DE0, 0x046B, NES_ROOM }, { 0x222FA, 0x0460, NES_ROOM },
- { 0x227C0, 0x0909, NES_ROOM }, { 0x24001, 0x0366, NES_ROOM }, { 0x247DB, 0x03CA, NES_ROOM }, { 0x24BA5, 0x050D, NES_ROOM }, { 0x23BE9, 0x0346, NES_ROOM },
- { 0x17DB5, 0x01CA, NES_ROOM }, { 0x25E99, 0x0457, NES_ROOM }, { 0x262F0, 0x0547, NES_ROOM }, { 0x26837, 0x064A, NES_ROOM }, { 0x1FCF3, 0x024B, NES_ROOM },
- { 0x2741E, 0x01FA, NES_ROOM }, { 0x276F1, 0x0219, NES_ROOM }, { 0x28001, 0x02F4, NES_ROOM }, { 0x284D6, 0x045C, NES_ROOM }, { 0x289A3, 0x09CF, NES_ROOM },
- { 0x293C6, 0x05A0, NES_ROOM }, { 0x27BE9, 0x0201, NES_ROOM }, { 0x2ADE3, 0x0325, NES_ROOM }, { 0x2B34B, 0x01FC, NES_ROOM }, { 0x2B547, 0x02A9, NES_ROOM },
- { 0x2B7F0, 0x02DE, NES_ROOM }, { 0x2C001, 0x03CE, NES_ROOM }, { 0x2BBD2, 0x0205, NES_ROOM }, { 0x2C53A, 0x0170, NES_ROOM }, { 0x2BDD7, 0x0169, NES_ROOM }
-};
-static ScummNESFile::Resource res_rooms_swe[55] = {
- { 0x00000, 0x0000, NES_ROOM }, { 0x14001, 0x0D12, NES_ROOM }, { 0x1328F, 0x04B3, NES_ROOM }, { 0x15367, 0x0859, NES_ROOM }, { 0x13742, 0x0694, NES_ROOM },
- { 0x15C45, 0x0707, NES_ROOM }, { 0x1658F, 0x04E0, NES_ROOM }, { 0x16A6F, 0x0AC8, NES_ROOM }, { 0x18001, 0x06C7, NES_ROOM }, { 0x1789C, 0x03EA, NES_ROOM },
- { 0x18C09, 0x0649, NES_ROOM }, { 0x192AE, 0x04AB, NES_ROOM }, { 0x19982, 0x0447, NES_ROOM }, { 0x1A04D, 0x047E, NES_ROOM }, { 0x1A4CB, 0x0444, NES_ROOM },
- { 0x1A90F, 0x03B9, NES_ROOM }, { 0x1ACC8, 0x07E9, NES_ROOM }, { 0x1B511, 0x06A4, NES_ROOM }, { 0x1C001, 0x0B1A, NES_ROOM }, { 0x1CCFD, 0x0486, NES_ROOM },
- { 0x1D482, 0x0579, NES_ROOM }, { 0x1DF61, 0x051E, NES_ROOM }, { 0x1E8EC, 0x05CF, NES_ROOM }, { 0x1EF73, 0x0398, NES_ROOM }, { 0x1F5F0, 0x071A, NES_ROOM },
- { 0x20001, 0x049C, NES_ROOM }, { 0x2051E, 0x051E, NES_ROOM }, { 0x21725, 0x05D5, NES_ROOM }, { 0x21EA5, 0x047F, NES_ROOM }, { 0x223D1, 0x0460, NES_ROOM },
- { 0x22897, 0x090D, NES_ROOM }, { 0x24001, 0x0378, NES_ROOM }, { 0x247C9, 0x03CA, NES_ROOM }, { 0x24B93, 0x050D, NES_ROOM }, { 0x25267, 0x0346, NES_ROOM },
- { 0x17CD0, 0x01CA, NES_ROOM }, { 0x255AD, 0x0453, NES_ROOM }, { 0x25A00, 0x053E, NES_ROOM }, { 0x25F3E, 0x0647, NES_ROOM }, { 0x1BC49, 0x024B, NES_ROOM },
- { 0x26B58, 0x01FA, NES_ROOM }, { 0x26E27, 0x0217, NES_ROOM }, { 0x27345, 0x02F4, NES_ROOM }, { 0x27829, 0x045C, NES_ROOM }, { 0x28001, 0x098A, NES_ROOM },
- { 0x289DF, 0x05A1, NES_ROOM }, { 0x2A442, 0x0201, NES_ROOM }, { 0x2A6E9, 0x0325, NES_ROOM }, { 0x1FD75, 0x01FC, NES_ROOM }, { 0x2AC64, 0x02A9, NES_ROOM },
- { 0x2AF0D, 0x02D1, NES_ROOM }, { 0x2B2E6, 0x03CC, NES_ROOM }, { 0x23D61, 0x0205, NES_ROOM }, { 0x2B818, 0x0168, NES_ROOM }, { 0x27CF6, 0x0169, NES_ROOM }
-};
-static ScummNESFile::Resource res_rooms_fra[55] = {
- { 0x00000, 0x0000, NES_ROOM }, { 0x14001, 0x0D76, NES_ROOM }, { 0x1328A, 0x04C6, NES_ROOM }, { 0x15451, 0x0885, NES_ROOM }, { 0x13750, 0x0693, NES_ROOM },
- { 0x15D68, 0x0709, NES_ROOM }, { 0x166D4, 0x0528, NES_ROOM }, { 0x16BFC, 0x0ACC, NES_ROOM }, { 0x18001, 0x06E2, NES_ROOM }, { 0x17A63, 0x03E5, NES_ROOM },
- { 0x18C3B, 0x066A, NES_ROOM }, { 0x19301, 0x049E, NES_ROOM }, { 0x199C8, 0x044B, NES_ROOM }, { 0x1A0B1, 0x0478, NES_ROOM }, { 0x1A529, 0x043F, NES_ROOM },
- { 0x1A968, 0x03C8, NES_ROOM }, { 0x1AD30, 0x086F, NES_ROOM }, { 0x1B5FF, 0x069B, NES_ROOM }, { 0x1C001, 0x0AA9, NES_ROOM }, { 0x1CC97, 0x049E, NES_ROOM },
- { 0x1D42C, 0x05A8, NES_ROOM }, { 0x1DF71, 0x054E, NES_ROOM }, { 0x1E9D1, 0x0606, NES_ROOM }, { 0x1F0A2, 0x039A, NES_ROOM }, { 0x1F74E, 0x071C, NES_ROOM },
- { 0x20001, 0x04B5, NES_ROOM }, { 0x2052E, 0x04FF, NES_ROOM }, { 0x2172E, 0x05DB, NES_ROOM }, { 0x21EAD, 0x0489, NES_ROOM }, { 0x223E1, 0x0465, NES_ROOM },
- { 0x228AC, 0x0957, NES_ROOM }, { 0x24001, 0x037E, NES_ROOM }, { 0x2481A, 0x03CA, NES_ROOM }, { 0x24BE4, 0x050D, NES_ROOM }, { 0x252C0, 0x0346, NES_ROOM },
- { 0x1BD30, 0x01CA, NES_ROOM }, { 0x25606, 0x046D, NES_ROOM }, { 0x25A73, 0x055A, NES_ROOM }, { 0x25FCD, 0x0654, NES_ROOM }, { 0x26C98, 0x024B, NES_ROOM },
- { 0x26EE3, 0x01FA, NES_ROOM }, { 0x271DD, 0x0217, NES_ROOM }, { 0x27713, 0x02F4, NES_ROOM }, { 0x28001, 0x045C, NES_ROOM }, { 0x284CE, 0x0975, NES_ROOM },
- { 0x28E97, 0x05E6, NES_ROOM }, { 0x27C3A, 0x0201, NES_ROOM }, { 0x2A9D6, 0x0325, NES_ROOM }, { 0x2AF88, 0x01FC, NES_ROOM }, { 0x2B184, 0x02A9, NES_ROOM },
- { 0x2B42D, 0x02DF, NES_ROOM }, { 0x2B818, 0x03EC, NES_ROOM }, { 0x2BD67, 0x0209, NES_ROOM }, { 0x2C001, 0x0168, NES_ROOM }, { 0x2C4BF, 0x0169, NES_ROOM }
-};
-static ScummNESFile::Resource res_rooms_ger[55] = {
- { 0x00000, 0x0000, NES_ROOM }, { 0x14001, 0x0D63, NES_ROOM }, { 0x131E0, 0x04A9, NES_ROOM }, { 0x13689, 0x086B, NES_ROOM }, { 0x15421, 0x06A8, NES_ROOM },
- { 0x15B5D, 0x0731, NES_ROOM }, { 0x16507, 0x0501, NES_ROOM }, { 0x16A08, 0x0AE9, NES_ROOM }, { 0x18001, 0x06DA, NES_ROOM }, { 0x17880, 0x03D0, NES_ROOM },
- { 0x18C7B, 0x0651, NES_ROOM }, { 0x19328, 0x04A7, NES_ROOM }, { 0x199FE, 0x0447, NES_ROOM }, { 0x1A0F1, 0x0486, NES_ROOM }, { 0x1A577, 0x045D, NES_ROOM },
- { 0x1A9D4, 0x03AE, NES_ROOM }, { 0x1AD82, 0x0840, NES_ROOM }, { 0x1B622, 0x06C3, NES_ROOM }, { 0x1C001, 0x0B07, NES_ROOM }, { 0x1CD05, 0x0494, NES_ROOM },
- { 0x1D4A5, 0x05AC, NES_ROOM }, { 0x1DFD6, 0x0524, NES_ROOM }, { 0x1E9C0, 0x05F7, NES_ROOM }, { 0x1F09A, 0x038E, NES_ROOM }, { 0x1F75F, 0x0733, NES_ROOM },
- { 0x20001, 0x04A9, NES_ROOM }, { 0x2052A, 0x052E, NES_ROOM }, { 0x2177C, 0x0621, NES_ROOM }, { 0x21F57, 0x0495, NES_ROOM }, { 0x2249A, 0x045E, NES_ROOM },
- { 0x2295E, 0x0951, NES_ROOM }, { 0x24001, 0x036E, NES_ROOM }, { 0x247F9, 0x03CA, NES_ROOM }, { 0x24BC3, 0x050D, NES_ROOM }, { 0x252A8, 0x0346, NES_ROOM },
- { 0x17CA2, 0x01CA, NES_ROOM }, { 0x255EE, 0x046F, NES_ROOM }, { 0x25A5D, 0x054D, NES_ROOM }, { 0x25FAA, 0x064B, NES_ROOM }, { 0x26BE2, 0x024B, NES_ROOM },
- { 0x26E2D, 0x01FA, NES_ROOM }, { 0x2710F, 0x0217, NES_ROOM }, { 0x27663, 0x02F4, NES_ROOM }, { 0x28001, 0x045C, NES_ROOM }, { 0x284CE, 0x0A8F, NES_ROOM },
- { 0x28FB1, 0x05FF, NES_ROOM }, { 0x27B69, 0x0201, NES_ROOM }, { 0x2AAA9, 0x0325, NES_ROOM }, { 0x1BD7C, 0x01FC, NES_ROOM }, { 0x2B031, 0x02A9, NES_ROOM },
- { 0x2B2DA, 0x02D8, NES_ROOM }, { 0x2B6D2, 0x03D2, NES_ROOM }, { 0x2BC0D, 0x020D, NES_ROOM }, { 0x2C001, 0x0168, NES_ROOM }, { 0x27E11, 0x0169, NES_ROOM }
-};
-#endif
-static ScummNESFile::Resource *res_rooms[ScummNESFile::kROMsetNum] = {
- res_rooms_usa,
- res_rooms_eur,
- res_rooms_swe,
- res_rooms_fra,
- res_rooms_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_scripts_usa;
-static ScummNESFile::Resource *res_scripts_eur;
-static ScummNESFile::Resource *res_scripts_swe;
-static ScummNESFile::Resource *res_scripts_fra;
-static ScummNESFile::Resource *res_scripts_ger;
-#else
-static ScummNESFile::Resource res_scripts_usa[179] = {
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x29966, 0x044D, NES_SCRIPT }, { 0x29DB3, 0x0207, NES_SCRIPT }, { 0x29FBA, 0x009F, NES_SCRIPT }, { 0x2A059, 0x03F4, NES_SCRIPT },
- { 0x2A44D, 0x01A1, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A5EE, 0x004A, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A638, 0x0005, NES_SCRIPT },
- { 0x2C6AA, 0x000D, NES_SCRIPT }, { 0x2C6B7, 0x000D, NES_SCRIPT }, { 0x186BB, 0x0040, NES_SCRIPT }, { 0x186FB, 0x0016, NES_SCRIPT }, { 0x1B639, 0x0046, NES_SCRIPT },
- { 0x1EEC6, 0x00BD, NES_SCRIPT }, { 0x21C31, 0x0055, NES_SCRIPT }, { 0x177A8, 0x0027, NES_SCRIPT }, { 0x1FD07, 0x0027, NES_SCRIPT }, { 0x1FD2E, 0x0027, NES_SCRIPT },
- { 0x1BD2B, 0x0022, NES_SCRIPT }, { 0x15BE0, 0x0088, NES_SCRIPT }, { 0x22241, 0x0020, NES_SCRIPT }, { 0x22261, 0x008F, NES_SCRIPT }, { 0x1924A, 0x002B, NES_SCRIPT },
- { 0x1CB4A, 0x0061, NES_SCRIPT }, { 0x1CBAB, 0x003C, NES_SCRIPT }, { 0x1CBE7, 0x0042, NES_SCRIPT }, { 0x1CC29, 0x004F, NES_SCRIPT }, { 0x2049B, 0x0076, NES_SCRIPT },
- { 0x16A96, 0x0035, NES_SCRIPT }, { 0x16ACB, 0x001C, NES_SCRIPT }, { 0x16AE7, 0x0014, NES_SCRIPT }, { 0x16AFB, 0x001C, NES_SCRIPT }, { 0x16B17, 0x0027, NES_SCRIPT },
- { 0x16B3E, 0x01AA, NES_SCRIPT }, { 0x1D1CF, 0x0096, NES_SCRIPT }, { 0x1D265, 0x010E, NES_SCRIPT }, { 0x1D373, 0x001C, NES_SCRIPT }, { 0x1D38F, 0x0056, NES_SCRIPT },
- { 0x1D3E5, 0x0072, NES_SCRIPT }, { 0x1E480, 0x0028, NES_SCRIPT }, { 0x1E4A8, 0x017D, NES_SCRIPT }, { 0x1E625, 0x0229, NES_SCRIPT }, { 0x28932, 0x0071, NES_SCRIPT },
- { 0x17EB8, 0x004D, NES_SCRIPT }, { 0x162ED, 0x0039, NES_SCRIPT }, { 0x18711, 0x028B, NES_SCRIPT }, { 0x1899C, 0x00BB, NES_SCRIPT }, { 0x18A57, 0x018B, NES_SCRIPT },
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x19E87, 0x00ED, NES_SCRIPT }, { 0x21C86, 0x00F6, NES_SCRIPT }, { 0x1E84E, 0x009B, NES_SCRIPT }, { 0x21D7C, 0x0047, NES_SCRIPT },
- { 0x2C6C4, 0x004D, NES_SCRIPT }, { 0x16326, 0x0024, NES_SCRIPT }, { 0x14D0D, 0x0014, NES_SCRIPT }, { 0x177CF, 0x0059, NES_SCRIPT }, { 0x17828, 0x0109, NES_SCRIPT },
- { 0x17931, 0x0009, NES_SCRIPT }, { 0x14D21, 0x01B6, NES_SCRIPT }, { 0x2B0F6, 0x0243, NES_SCRIPT }, { 0x230BF, 0x067F, NES_SCRIPT }, { 0x2C711, 0x001C, NES_SCRIPT },
- { 0x2C72D, 0x001A, NES_SCRIPT }, { 0x2C747, 0x0021, NES_SCRIPT }, { 0x2C768, 0x0024, NES_SCRIPT }, { 0x2C78C, 0x0017, NES_SCRIPT }, { 0x2C7A3, 0x0017, NES_SCRIPT },
- { 0x2C7BA, 0x0014, NES_SCRIPT }, { 0x2C7CE, 0x0024, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2C7F2, 0x0011, NES_SCRIPT }, { 0x1793A, 0x009D, NES_SCRIPT },
- { 0x22750, 0x0066, NES_SCRIPT }, { 0x14ED7, 0x0075, NES_SCRIPT }, { 0x1F30C, 0x0120, NES_SCRIPT }, { 0x1FD55, 0x001D, NES_SCRIPT }, { 0x1F42C, 0x008F, NES_SCRIPT },
- { 0x1F4BB, 0x0097, NES_SCRIPT }, { 0x179D7, 0x006A, NES_SCRIPT }, { 0x17A41, 0x0030, NES_SCRIPT }, { 0x1F552, 0x0092, NES_SCRIPT }, { 0x2C803, 0x00CC, NES_SCRIPT },
- { 0x2C8CF, 0x00BA, NES_SCRIPT }, { 0x2C989, 0x0088, NES_SCRIPT }, { 0x20A09, 0x01B0, NES_SCRIPT }, { 0x20BB9, 0x0168, NES_SCRIPT }, { 0x20D21, 0x006C, NES_SCRIPT },
- { 0x20D8D, 0x0037, NES_SCRIPT }, { 0x20DC4, 0x00E4, NES_SCRIPT }, { 0x20EA8, 0x0045, NES_SCRIPT }, { 0x20EED, 0x00E1, NES_SCRIPT }, { 0x20FCE, 0x00F6, NES_SCRIPT },
- { 0x210C4, 0x0141, NES_SCRIPT }, { 0x21205, 0x0183, NES_SCRIPT }, { 0x21388, 0x0034, NES_SCRIPT }, { 0x213BC, 0x00A9, NES_SCRIPT }, { 0x24367, 0x011B, NES_SCRIPT },
- { 0x1BD4D, 0x0070, NES_SCRIPT }, { 0x1CC78, 0x0091, NES_SCRIPT }, { 0x29372, 0x0054, NES_SCRIPT }, { 0x19F74, 0x00CE, NES_SCRIPT }, { 0x1A042, 0x0077, NES_SCRIPT },
- { 0x14F4C, 0x0057, NES_SCRIPT }, { 0x27886, 0x02DF, NES_SCRIPT }, { 0x1DA2A, 0x0219, NES_SCRIPT }, { 0x1DC43, 0x00F9, NES_SCRIPT }, { 0x1DD3C, 0x0056, NES_SCRIPT },
- { 0x1DD92, 0x01C2, NES_SCRIPT }, { 0x14FA3, 0x004D, NES_SCRIPT }, { 0x27594, 0x00D9, NES_SCRIPT }, { 0x21DC3, 0x0013, NES_SCRIPT }, { 0x2A63D, 0x00F0, NES_SCRIPT },
- { 0x24482, 0x00E7, NES_SCRIPT }, { 0x21465, 0x00F2, NES_SCRIPT }, { 0x24569, 0x002B, NES_SCRIPT }, { 0x2C3CF, 0x010F, NES_SCRIPT }, { 0x24594, 0x00AA, NES_SCRIPT },
- { 0x24CE8, 0x0DAB, NES_SCRIPT }, { 0x1B67F, 0x000D, NES_SCRIPT }, { 0x1B68C, 0x000D, NES_SCRIPT }, { 0x2373E, 0x017C, NES_SCRIPT }, { 0x282F5, 0x01E1, NES_SCRIPT },
- { 0x238BA, 0x0153, NES_SCRIPT }, { 0x23A0D, 0x019C, NES_SCRIPT }, { 0x23BA9, 0x0016, NES_SCRIPT }, { 0x2C4DE, 0x005C, NES_SCRIPT }, { 0x23BBF, 0x0020, NES_SCRIPT },
- { 0x27D66, 0x00A5, NES_SCRIPT }, { 0x2A72D, 0x034D, NES_SCRIPT }, { 0x14FF0, 0x00E3, NES_SCRIPT }, { 0x2BABC, 0x005F, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT },
- { 0x25A93, 0x003C, NES_SCRIPT }, { 0x1E8E9, 0x0011, NES_SCRIPT }, { 0x1634A, 0x0018, NES_SCRIPT }, { 0x26DFD, 0x001F, NES_SCRIPT }, { 0x26E1C, 0x0054, NES_SCRIPT },
- { 0x26E70, 0x0149, NES_SCRIPT }, { 0x26FB9, 0x004B, NES_SCRIPT }, { 0x27004, 0x017D, NES_SCRIPT }, { 0x27181, 0x0027, NES_SCRIPT }, { 0x271A8, 0x0041, NES_SCRIPT },
- { 0x271E9, 0x01B1, NES_SCRIPT }, { 0x16362, 0x001F, NES_SCRIPT }, { 0x2463E, 0x002A, NES_SCRIPT }, { 0x150D3, 0x019E, NES_SCRIPT }, { 0x19275, 0x0031, NES_SCRIPT },
- { 0x17A71, 0x007C, NES_SCRIPT }, { 0x21557, 0x00DC, NES_SCRIPT }, { 0x1D457, 0x0018, NES_SCRIPT }, { 0x1D46F, 0x0053, NES_SCRIPT }, { 0x18BE2, 0x0005, NES_SCRIPT },
- { 0x15271, 0x011B, NES_SCRIPT }, { 0x1538C, 0x000B, NES_SCRIPT }, { 0x24668, 0x0138, NES_SCRIPT }, { 0x247A0, 0x0014, NES_SCRIPT }, { 0x1DF54, 0x0018, NES_SCRIPT },
- { 0x247B4, 0x0027, NES_SCRIPT }, { 0x1A0B9, 0x004D, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2BB1B, 0x00A5, NES_SCRIPT }, { 0x2AA7A, 0x00C1, NES_SCRIPT },
- { 0x2AB3B, 0x0140, NES_SCRIPT }, { 0x19826, 0x00BF, NES_SCRIPT }, { 0x198E5, 0x014D, NES_SCRIPT }, { 0x19A32, 0x0012, NES_SCRIPT }, { 0x2AC7B, 0x0005, NES_SCRIPT },
- { 0x2AC80, 0x0005, NES_SCRIPT }, { 0x2AC85, 0x0005, NES_SCRIPT }, { 0x2AC8A, 0x0005, NES_SCRIPT }, { 0x2AC8F, 0x0005, NES_SCRIPT }, { 0x21633, 0x0033, NES_SCRIPT },
- { 0x2AC94, 0x0005, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2AC99, 0x009C, NES_SCRIPT }, { 0x2AD35, 0x009C, NES_SCRIPT }
-};
-static ScummNESFile::Resource res_scripts_eur[179] = {
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x29966, 0x044D, NES_SCRIPT }, { 0x29DB3, 0x0207, NES_SCRIPT }, { 0x29FBA, 0x009F, NES_SCRIPT }, { 0x2A059, 0x03F4, NES_SCRIPT },
- { 0x2A44D, 0x01A1, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A5EE, 0x005C, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A64A, 0x0005, NES_SCRIPT },
- { 0x2C6AA, 0x000D, NES_SCRIPT }, { 0x2C6B7, 0x000D, NES_SCRIPT }, { 0x17889, 0x0040, NES_SCRIPT }, { 0x178C9, 0x0016, NES_SCRIPT }, { 0x1B6AE, 0x0046, NES_SCRIPT },
- { 0x1EE47, 0x00BD, NES_SCRIPT }, { 0x21C3B, 0x0055, NES_SCRIPT }, { 0x18AC0, 0x0027, NES_SCRIPT }, { 0x1FC88, 0x0027, NES_SCRIPT }, { 0x1FCAF, 0x0027, NES_SCRIPT },
- { 0x1BDA0, 0x0022, NES_SCRIPT }, { 0x15BE0, 0x0088, NES_SCRIPT }, { 0x2224B, 0x0020, NES_SCRIPT }, { 0x2226B, 0x008F, NES_SCRIPT }, { 0x1947D, 0x002B, NES_SCRIPT },
- { 0x1CACB, 0x0061, NES_SCRIPT }, { 0x1CB2C, 0x003C, NES_SCRIPT }, { 0x1CB68, 0x0042, NES_SCRIPT }, { 0x1CBAA, 0x004F, NES_SCRIPT }, { 0x2049B, 0x0076, NES_SCRIPT },
- { 0x16A96, 0x0035, NES_SCRIPT }, { 0x16ACB, 0x001C, NES_SCRIPT }, { 0x16AE7, 0x0014, NES_SCRIPT }, { 0x16AFB, 0x001C, NES_SCRIPT }, { 0x16B17, 0x0027, NES_SCRIPT },
- { 0x16B3E, 0x01AA, NES_SCRIPT }, { 0x1D150, 0x0096, NES_SCRIPT }, { 0x1D1E6, 0x010E, NES_SCRIPT }, { 0x1D2F4, 0x001C, NES_SCRIPT }, { 0x1D310, 0x0056, NES_SCRIPT },
- { 0x1D366, 0x0072, NES_SCRIPT }, { 0x1E401, 0x0028, NES_SCRIPT }, { 0x1E429, 0x017D, NES_SCRIPT }, { 0x1E5A6, 0x0229, NES_SCRIPT }, { 0x28932, 0x0071, NES_SCRIPT },
- { 0x13EC6, 0x004D, NES_SCRIPT }, { 0x162ED, 0x0039, NES_SCRIPT }, { 0x178DF, 0x028B, NES_SCRIPT }, { 0x17B6A, 0x00BB, NES_SCRIPT }, { 0x17C25, 0x018B, NES_SCRIPT },
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x19FE3, 0x00ED, NES_SCRIPT }, { 0x21C90, 0x00F6, NES_SCRIPT }, { 0x1E7CF, 0x009B, NES_SCRIPT }, { 0x21D86, 0x0047, NES_SCRIPT },
- { 0x2C6C4, 0x004D, NES_SCRIPT }, { 0x16326, 0x0024, NES_SCRIPT }, { 0x14D0D, 0x0014, NES_SCRIPT }, { 0x18AE7, 0x0059, NES_SCRIPT }, { 0x18B40, 0x011E, NES_SCRIPT },
- { 0x18C5E, 0x0009, NES_SCRIPT }, { 0x14D21, 0x01B6, NES_SCRIPT }, { 0x2B108, 0x0243, NES_SCRIPT }, { 0x230C9, 0x067F, NES_SCRIPT }, { 0x2C711, 0x001C, NES_SCRIPT },
- { 0x2C72D, 0x001A, NES_SCRIPT }, { 0x2C747, 0x0021, NES_SCRIPT }, { 0x2C768, 0x0024, NES_SCRIPT }, { 0x2C78C, 0x0017, NES_SCRIPT }, { 0x2C7A3, 0x0017, NES_SCRIPT },
- { 0x2C7BA, 0x0014, NES_SCRIPT }, { 0x2C7CE, 0x0024, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2C7F2, 0x0011, NES_SCRIPT }, { 0x18C67, 0x009D, NES_SCRIPT },
- { 0x2275A, 0x0066, NES_SCRIPT }, { 0x14ED7, 0x0075, NES_SCRIPT }, { 0x1F28D, 0x0120, NES_SCRIPT }, { 0x1FCD6, 0x001D, NES_SCRIPT }, { 0x1F3AD, 0x008F, NES_SCRIPT },
- { 0x1F43C, 0x0097, NES_SCRIPT }, { 0x18D04, 0x006A, NES_SCRIPT }, { 0x18D6E, 0x0030, NES_SCRIPT }, { 0x1F4D3, 0x0092, NES_SCRIPT }, { 0x2C803, 0x00CC, NES_SCRIPT },
- { 0x2C8CF, 0x00BA, NES_SCRIPT }, { 0x2C989, 0x0088, NES_SCRIPT }, { 0x20A09, 0x01B0, NES_SCRIPT }, { 0x20BB9, 0x0168, NES_SCRIPT }, { 0x20D21, 0x006C, NES_SCRIPT },
- { 0x20D8D, 0x0037, NES_SCRIPT }, { 0x20DC4, 0x00E4, NES_SCRIPT }, { 0x20EA8, 0x0045, NES_SCRIPT }, { 0x20EED, 0x00E1, NES_SCRIPT }, { 0x20FCE, 0x00F6, NES_SCRIPT },
- { 0x210C4, 0x0141, NES_SCRIPT }, { 0x21205, 0x0183, NES_SCRIPT }, { 0x21388, 0x0034, NES_SCRIPT }, { 0x213BC, 0x00A9, NES_SCRIPT }, { 0x24367, 0x011B, NES_SCRIPT },
- { 0x1BDC2, 0x0070, NES_SCRIPT }, { 0x1CBF9, 0x0091, NES_SCRIPT }, { 0x29372, 0x0054, NES_SCRIPT }, { 0x1A0D0, 0x00CE, NES_SCRIPT }, { 0x1A19E, 0x0077, NES_SCRIPT },
- { 0x14F4C, 0x0057, NES_SCRIPT }, { 0x2790A, 0x02DF, NES_SCRIPT }, { 0x1D9AB, 0x0219, NES_SCRIPT }, { 0x1DBC4, 0x00F9, NES_SCRIPT }, { 0x1DCBD, 0x0056, NES_SCRIPT },
- { 0x1DD13, 0x01C2, NES_SCRIPT }, { 0x14FA3, 0x004D, NES_SCRIPT }, { 0x27618, 0x00D9, NES_SCRIPT }, { 0x21DCD, 0x0013, NES_SCRIPT }, { 0x2A64F, 0x00F0, NES_SCRIPT },
- { 0x24482, 0x00E7, NES_SCRIPT }, { 0x21465, 0x00F2, NES_SCRIPT }, { 0x24569, 0x002B, NES_SCRIPT }, { 0x2C3CF, 0x010F, NES_SCRIPT }, { 0x24594, 0x00AA, NES_SCRIPT },
- { 0x250B2, 0x0DAB, NES_SCRIPT }, { 0x1B6F4, 0x000D, NES_SCRIPT }, { 0x1B701, 0x000D, NES_SCRIPT }, { 0x23748, 0x017C, NES_SCRIPT }, { 0x282F5, 0x01E1, NES_SCRIPT },
- { 0x238C4, 0x0153, NES_SCRIPT }, { 0x23A17, 0x019C, NES_SCRIPT }, { 0x23BB3, 0x0016, NES_SCRIPT }, { 0x2C4DE, 0x005C, NES_SCRIPT }, { 0x23BC9, 0x0020, NES_SCRIPT },
- { 0x27DEA, 0x00A5, NES_SCRIPT }, { 0x2A73F, 0x034D, NES_SCRIPT }, { 0x14FF0, 0x00E3, NES_SCRIPT }, { 0x2BACE, 0x005F, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT },
- { 0x25E5D, 0x003C, NES_SCRIPT }, { 0x1E86A, 0x0011, NES_SCRIPT }, { 0x1634A, 0x0018, NES_SCRIPT }, { 0x26E81, 0x001F, NES_SCRIPT }, { 0x26EA0, 0x0054, NES_SCRIPT },
- { 0x26EF4, 0x0149, NES_SCRIPT }, { 0x2703D, 0x004B, NES_SCRIPT }, { 0x27088, 0x017D, NES_SCRIPT }, { 0x27205, 0x0027, NES_SCRIPT }, { 0x2722C, 0x0041, NES_SCRIPT },
- { 0x2726D, 0x01B1, NES_SCRIPT }, { 0x16362, 0x001F, NES_SCRIPT }, { 0x2463E, 0x002A, NES_SCRIPT }, { 0x150D3, 0x019E, NES_SCRIPT }, { 0x194A8, 0x0031, NES_SCRIPT },
- { 0x18D9E, 0x007C, NES_SCRIPT }, { 0x21557, 0x00DC, NES_SCRIPT }, { 0x1D3D8, 0x0018, NES_SCRIPT }, { 0x1D3F0, 0x0053, NES_SCRIPT }, { 0x17DB0, 0x0005, NES_SCRIPT },
- { 0x15271, 0x011B, NES_SCRIPT }, { 0x1538C, 0x000B, NES_SCRIPT }, { 0x24668, 0x0138, NES_SCRIPT }, { 0x247A0, 0x0014, NES_SCRIPT }, { 0x1DED5, 0x0018, NES_SCRIPT },
- { 0x247B4, 0x0027, NES_SCRIPT }, { 0x1A215, 0x004D, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2BB2D, 0x00A5, NES_SCRIPT }, { 0x2AA8C, 0x00C1, NES_SCRIPT },
- { 0x2AB4D, 0x0140, NES_SCRIPT }, { 0x19982, 0x00BF, NES_SCRIPT }, { 0x19A41, 0x014D, NES_SCRIPT }, { 0x19B8E, 0x0012, NES_SCRIPT }, { 0x2AC8D, 0x0005, NES_SCRIPT },
- { 0x2AC92, 0x0005, NES_SCRIPT }, { 0x2AC97, 0x0005, NES_SCRIPT }, { 0x2AC9C, 0x0005, NES_SCRIPT }, { 0x2ACA1, 0x0005, NES_SCRIPT }, { 0x21633, 0x0033, NES_SCRIPT },
- { 0x2ACA6, 0x0005, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2ACAB, 0x009C, NES_SCRIPT }, { 0x2AD47, 0x009C, NES_SCRIPT }
-};
-static ScummNESFile::Resource res_scripts_swe[179] = {
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x28F80, 0x043B, NES_SCRIPT }, { 0x293BB, 0x0209, NES_SCRIPT }, { 0x295C4, 0x00AB, NES_SCRIPT }, { 0x2966F, 0x03FD, NES_SCRIPT },
- { 0x29A6C, 0x01A1, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x29C0D, 0x005C, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x29C69, 0x0005, NES_SCRIPT },
- { 0x2B980, 0x000D, NES_SCRIPT }, { 0x2B98D, 0x000D, NES_SCRIPT }, { 0x186C8, 0x0040, NES_SCRIPT }, { 0x18708, 0x0016, NES_SCRIPT }, { 0x1B4B1, 0x0046, NES_SCRIPT },
- { 0x1EEBB, 0x00B8, NES_SCRIPT }, { 0x21CFA, 0x005C, NES_SCRIPT }, { 0x17537, 0x0027, NES_SCRIPT }, { 0x1FD0A, 0x0027, NES_SCRIPT }, { 0x1FD31, 0x0027, NES_SCRIPT },
- { 0x1BBB5, 0x0022, NES_SCRIPT }, { 0x15BC0, 0x0085, NES_SCRIPT }, { 0x22324, 0x001E, NES_SCRIPT }, { 0x22342, 0x008F, NES_SCRIPT }, { 0x19252, 0x002B, NES_SCRIPT },
- { 0x1CB1B, 0x006D, NES_SCRIPT }, { 0x1CB88, 0x004C, NES_SCRIPT }, { 0x1CBD4, 0x0044, NES_SCRIPT }, { 0x1CC18, 0x0053, NES_SCRIPT }, { 0x2049D, 0x0081, NES_SCRIPT },
- { 0x1634C, 0x0035, NES_SCRIPT }, { 0x16381, 0x001C, NES_SCRIPT }, { 0x1639D, 0x0014, NES_SCRIPT }, { 0x163B1, 0x001C, NES_SCRIPT }, { 0x163CD, 0x0027, NES_SCRIPT },
- { 0x163F4, 0x019B, NES_SCRIPT }, { 0x1D183, 0x0094, NES_SCRIPT }, { 0x1D217, 0x0117, NES_SCRIPT }, { 0x1D32E, 0x001C, NES_SCRIPT }, { 0x1D34A, 0x0056, NES_SCRIPT },
- { 0x1D3A0, 0x0072, NES_SCRIPT }, { 0x1E47F, 0x0028, NES_SCRIPT }, { 0x1E4A7, 0x0175, NES_SCRIPT }, { 0x1E61C, 0x022B, NES_SCRIPT }, { 0x27C85, 0x0071, NES_SCRIPT },
- { 0x17C86, 0x004A, NES_SCRIPT }, { 0x13DD6, 0x0039, NES_SCRIPT }, { 0x1871E, 0x0270, NES_SCRIPT }, { 0x1898E, 0x00C0, NES_SCRIPT }, { 0x18A4E, 0x01B6, NES_SCRIPT },
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x19DC9, 0x00EE, NES_SCRIPT }, { 0x21D56, 0x00F5, NES_SCRIPT }, { 0x1E847, 0x0094, NES_SCRIPT }, { 0x21E4B, 0x0047, NES_SCRIPT },
- { 0x2B99A, 0x004D, NES_SCRIPT }, { 0x13E0F, 0x0024, NES_SCRIPT }, { 0x14D13, 0x0014, NES_SCRIPT }, { 0x1755E, 0x0054, NES_SCRIPT }, { 0x175B2, 0x011A, NES_SCRIPT },
- { 0x176CC, 0x0009, NES_SCRIPT }, { 0x14D27, 0x01B9, NES_SCRIPT }, { 0x2AA0E, 0x0256, NES_SCRIPT }, { 0x231A4, 0x06D2, NES_SCRIPT }, { 0x2B9E7, 0x001D, NES_SCRIPT },
- { 0x2BA04, 0x0016, NES_SCRIPT }, { 0x2BA1A, 0x002D, NES_SCRIPT }, { 0x2BA47, 0x0027, NES_SCRIPT }, { 0x2BA6E, 0x0016, NES_SCRIPT }, { 0x2BA84, 0x0014, NES_SCRIPT },
- { 0x2BA98, 0x0015, NES_SCRIPT }, { 0x2BAAD, 0x0029, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2BAD6, 0x0010, NES_SCRIPT }, { 0x176D5, 0x00A2, NES_SCRIPT },
- { 0x22831, 0x0066, NES_SCRIPT }, { 0x14EE0, 0x0077, NES_SCRIPT }, { 0x1F30B, 0x011A, NES_SCRIPT }, { 0x1FD58, 0x001D, NES_SCRIPT }, { 0x1F425, 0x0095, NES_SCRIPT },
- { 0x1F4BA, 0x009E, NES_SCRIPT }, { 0x17777, 0x006F, NES_SCRIPT }, { 0x177E6, 0x002F, NES_SCRIPT }, { 0x1F558, 0x0098, NES_SCRIPT }, { 0x2BAE6, 0x00C4, NES_SCRIPT },
- { 0x2BBAA, 0x00AE, NES_SCRIPT }, { 0x2BC58, 0x0088, NES_SCRIPT }, { 0x20A3C, 0x01BB, NES_SCRIPT }, { 0x20BF7, 0x0197, NES_SCRIPT }, { 0x20D8E, 0x006E, NES_SCRIPT },
- { 0x20DFC, 0x0028, NES_SCRIPT }, { 0x20E24, 0x00EA, NES_SCRIPT }, { 0x20F0E, 0x0049, NES_SCRIPT }, { 0x20F57, 0x00E7, NES_SCRIPT }, { 0x2103E, 0x010C, NES_SCRIPT },
- { 0x2114A, 0x0151, NES_SCRIPT }, { 0x2129B, 0x01B0, NES_SCRIPT }, { 0x2144B, 0x0034, NES_SCRIPT }, { 0x2147F, 0x00A9, NES_SCRIPT }, { 0x24379, 0x010E, NES_SCRIPT },
- { 0x1BBD7, 0x0072, NES_SCRIPT }, { 0x1CC6B, 0x0092, NES_SCRIPT }, { 0x2898B, 0x0054, NES_SCRIPT }, { 0x19EB7, 0x00D3, NES_SCRIPT }, { 0x19F8A, 0x0077, NES_SCRIPT },
- { 0x14F57, 0x0057, NES_SCRIPT }, { 0x2703E, 0x0307, NES_SCRIPT }, { 0x1D9FB, 0x024F, NES_SCRIPT }, { 0x1DC4A, 0x00E4, NES_SCRIPT }, { 0x1DD2E, 0x0059, NES_SCRIPT },
- { 0x1DD87, 0x01C2, NES_SCRIPT }, { 0x14FAE, 0x004D, NES_SCRIPT }, { 0x26D52, 0x00D5, NES_SCRIPT }, { 0x21E92, 0x0013, NES_SCRIPT }, { 0x29C6E, 0x00F0, NES_SCRIPT },
- { 0x24487, 0x00E0, NES_SCRIPT }, { 0x21528, 0x00F2, NES_SCRIPT }, { 0x24567, 0x0023, NES_SCRIPT }, { 0x2B6B2, 0x010B, NES_SCRIPT }, { 0x2458A, 0x00A1, NES_SCRIPT },
- { 0x250A0, 0x018B, NES_SCRIPT }, { 0x1B4F7, 0x000D, NES_SCRIPT }, { 0x1B504, 0x000D, NES_SCRIPT }, { 0x23876, 0x018E, NES_SCRIPT }, { 0x27639, 0x01F0, NES_SCRIPT },
- { 0x23A04, 0x017B, NES_SCRIPT }, { 0x23B7F, 0x01AC, NES_SCRIPT }, { 0x23D2B, 0x0016, NES_SCRIPT }, { 0x2B7BD, 0x005B, NES_SCRIPT }, { 0x23D41, 0x0020, NES_SCRIPT },
- { 0x2A643, 0x00A6, NES_SCRIPT }, { 0x29D5E, 0x0399, NES_SCRIPT }, { 0x14FFB, 0x00D2, NES_SCRIPT }, { 0x2B1DE, 0x0063, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT },
- { 0x2522B, 0x003C, NES_SCRIPT }, { 0x1E8DB, 0x0011, NES_SCRIPT }, { 0x13E33, 0x0018, NES_SCRIPT }, { 0x26585, 0x001F, NES_SCRIPT }, { 0x265A4, 0x0054, NES_SCRIPT },
- { 0x265F8, 0x017D, NES_SCRIPT }, { 0x26775, 0x004B, NES_SCRIPT }, { 0x267C0, 0x0165, NES_SCRIPT }, { 0x26925, 0x0027, NES_SCRIPT }, { 0x2694C, 0x0041, NES_SCRIPT },
- { 0x2698D, 0x01CB, NES_SCRIPT }, { 0x13E4B, 0x001F, NES_SCRIPT }, { 0x2462B, 0x002A, NES_SCRIPT }, { 0x150CD, 0x0187, NES_SCRIPT }, { 0x1927D, 0x0031, NES_SCRIPT },
- { 0x17815, 0x0087, NES_SCRIPT }, { 0x2161A, 0x00D8, NES_SCRIPT }, { 0x1D412, 0x0018, NES_SCRIPT }, { 0x1D42A, 0x0058, NES_SCRIPT }, { 0x18C04, 0x0005, NES_SCRIPT },
- { 0x15254, 0x0108, NES_SCRIPT }, { 0x1535C, 0x000B, NES_SCRIPT }, { 0x24655, 0x0139, NES_SCRIPT }, { 0x2478E, 0x0014, NES_SCRIPT }, { 0x1DF49, 0x0018, NES_SCRIPT },
- { 0x247A2, 0x0027, NES_SCRIPT }, { 0x1A001, 0x004C, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2B241, 0x00A5, NES_SCRIPT }, { 0x2A0F7, 0x00B5, NES_SCRIPT },
- { 0x2A1AC, 0x0140, NES_SCRIPT }, { 0x19759, 0x00CA, NES_SCRIPT }, { 0x19823, 0x014D, NES_SCRIPT }, { 0x19970, 0x0012, NES_SCRIPT }, { 0x2A2EC, 0x0005, NES_SCRIPT },
- { 0x2A2F1, 0x0005, NES_SCRIPT }, { 0x2A2F6, 0x0005, NES_SCRIPT }, { 0x2A2FB, 0x0005, NES_SCRIPT }, { 0x2A300, 0x0005, NES_SCRIPT }, { 0x216F2, 0x0033, NES_SCRIPT },
- { 0x2A305, 0x0005, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A30A, 0x009C, NES_SCRIPT }, { 0x2A3A6, 0x009C, NES_SCRIPT }
-};
-static ScummNESFile::Resource res_scripts_fra[179] = {
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x2947D, 0x0480, NES_SCRIPT }, { 0x298FD, 0x0226, NES_SCRIPT }, { 0x29B23, 0x0092, NES_SCRIPT }, { 0x29BB5, 0x040C, NES_SCRIPT },
- { 0x29FC1, 0x01A1, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A162, 0x005C, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A1BE, 0x0005, NES_SCRIPT },
- { 0x2C169, 0x000D, NES_SCRIPT }, { 0x2C176, 0x000D, NES_SCRIPT }, { 0x186E3, 0x0040, NES_SCRIPT }, { 0x18723, 0x0016, NES_SCRIPT }, { 0x1B59F, 0x0046, NES_SCRIPT },
- { 0x1EFD7, 0x00CB, NES_SCRIPT }, { 0x21D09, 0x0054, NES_SCRIPT }, { 0x176C8, 0x0027, NES_SCRIPT }, { 0x1FE6A, 0x0027, NES_SCRIPT }, { 0x1FE91, 0x0027, NES_SCRIPT },
- { 0x1BC9A, 0x0022, NES_SCRIPT }, { 0x15CD6, 0x0092, NES_SCRIPT }, { 0x22336, 0x001C, NES_SCRIPT }, { 0x22352, 0x008F, NES_SCRIPT }, { 0x192A5, 0x002B, NES_SCRIPT },
- { 0x1CAAA, 0x0069, NES_SCRIPT }, { 0x1CB13, 0x0054, NES_SCRIPT }, { 0x1CB67, 0x0048, NES_SCRIPT }, { 0x1CBAF, 0x0058, NES_SCRIPT }, { 0x204B6, 0x0078, NES_SCRIPT },
- { 0x16471, 0x0035, NES_SCRIPT }, { 0x164A6, 0x001C, NES_SCRIPT }, { 0x164C2, 0x0014, NES_SCRIPT }, { 0x164D6, 0x001C, NES_SCRIPT }, { 0x164F2, 0x0027, NES_SCRIPT },
- { 0x16519, 0x01BB, NES_SCRIPT }, { 0x1D135, 0x008D, NES_SCRIPT }, { 0x1D1C2, 0x0119, NES_SCRIPT }, { 0x1D2DB, 0x001C, NES_SCRIPT }, { 0x1D2F7, 0x0056, NES_SCRIPT },
- { 0x1D34D, 0x0072, NES_SCRIPT }, { 0x1E4BF, 0x0028, NES_SCRIPT }, { 0x1E4E7, 0x01E0, NES_SCRIPT }, { 0x1E6C7, 0x0241, NES_SCRIPT }, { 0x2845D, 0x0071, NES_SCRIPT },
- { 0x17E48, 0x004C, NES_SCRIPT }, { 0x13DE3, 0x0039, NES_SCRIPT }, { 0x18739, 0x0296, NES_SCRIPT }, { 0x189CF, 0x00C2, NES_SCRIPT }, { 0x18A91, 0x01A5, NES_SCRIPT },
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x19E13, 0x00F3, NES_SCRIPT }, { 0x21D5D, 0x00F6, NES_SCRIPT }, { 0x1E908, 0x00B8, NES_SCRIPT }, { 0x21E53, 0x0047, NES_SCRIPT },
- { 0x2C183, 0x004D, NES_SCRIPT }, { 0x13E1C, 0x0024, NES_SCRIPT }, { 0x14D77, 0x0014, NES_SCRIPT }, { 0x176EF, 0x0059, NES_SCRIPT }, { 0x17748, 0x013F, NES_SCRIPT },
- { 0x17887, 0x0009, NES_SCRIPT }, { 0x14D8B, 0x01D4, NES_SCRIPT }, { 0x2ACFB, 0x028D, NES_SCRIPT }, { 0x23203, 0x0779, NES_SCRIPT }, { 0x2C1D0, 0x001B, NES_SCRIPT },
- { 0x2C1EB, 0x001F, NES_SCRIPT }, { 0x2C20A, 0x0024, NES_SCRIPT }, { 0x2C22E, 0x0019, NES_SCRIPT }, { 0x2C247, 0x0018, NES_SCRIPT }, { 0x2C25F, 0x001D, NES_SCRIPT },
- { 0x2C27C, 0x0016, NES_SCRIPT }, { 0x2C292, 0x0027, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2C2B9, 0x0011, NES_SCRIPT }, { 0x17890, 0x00AA, NES_SCRIPT },
- { 0x22846, 0x0066, NES_SCRIPT }, { 0x14F5F, 0x0083, NES_SCRIPT }, { 0x1F43C, 0x013A, NES_SCRIPT }, { 0x1FEB8, 0x001D, NES_SCRIPT }, { 0x1F576, 0x0098, NES_SCRIPT },
- { 0x1F60E, 0x009B, NES_SCRIPT }, { 0x1793A, 0x006E, NES_SCRIPT }, { 0x179A8, 0x0033, NES_SCRIPT }, { 0x1F6A9, 0x00A5, NES_SCRIPT }, { 0x2C2CA, 0x00BA, NES_SCRIPT },
- { 0x2C384, 0x00AC, NES_SCRIPT }, { 0x2C430, 0x008F, NES_SCRIPT }, { 0x20A2D, 0x01BE, NES_SCRIPT }, { 0x20BEB, 0x0158, NES_SCRIPT }, { 0x20D43, 0x0079, NES_SCRIPT },
- { 0x20DBC, 0x002B, NES_SCRIPT }, { 0x20DE7, 0x00E8, NES_SCRIPT }, { 0x20ECF, 0x004A, NES_SCRIPT }, { 0x20F19, 0x0110, NES_SCRIPT }, { 0x21029, 0x0136, NES_SCRIPT },
- { 0x2115F, 0x0152, NES_SCRIPT }, { 0x212B1, 0x01B3, NES_SCRIPT }, { 0x21464, 0x0032, NES_SCRIPT }, { 0x21496, 0x00A9, NES_SCRIPT }, { 0x2437F, 0x0133, NES_SCRIPT },
- { 0x1BCBC, 0x0074, NES_SCRIPT }, { 0x1CC07, 0x0090, NES_SCRIPT }, { 0x28E43, 0x0054, NES_SCRIPT }, { 0x19F06, 0x00DB, NES_SCRIPT }, { 0x19FE1, 0x0080, NES_SCRIPT },
- { 0x14FE2, 0x0057, NES_SCRIPT }, { 0x273F4, 0x031F, NES_SCRIPT }, { 0x1D9D4, 0x0238, NES_SCRIPT }, { 0x1DC0C, 0x00FE, NES_SCRIPT }, { 0x1DD0A, 0x005A, NES_SCRIPT },
- { 0x1DD64, 0x01F5, NES_SCRIPT }, { 0x15039, 0x004D, NES_SCRIPT }, { 0x270DD, 0x0100, NES_SCRIPT }, { 0x21E9A, 0x0013, NES_SCRIPT }, { 0x2A1C3, 0x00F0, NES_SCRIPT },
- { 0x244B2, 0x00E4, NES_SCRIPT }, { 0x2153F, 0x00EC, NES_SCRIPT }, { 0x24596, 0x0033, NES_SCRIPT }, { 0x2BC04, 0x0108, NES_SCRIPT }, { 0x245C9, 0x009F, NES_SCRIPT },
- { 0x250F1, 0x0193, NES_SCRIPT }, { 0x1B5E5, 0x000D, NES_SCRIPT }, { 0x1B5F2, 0x000D, NES_SCRIPT }, { 0x2397C, 0x0199, NES_SCRIPT }, { 0x27A07, 0x0233, NES_SCRIPT },
- { 0x23B15, 0x0171, NES_SCRIPT }, { 0x23C86, 0x01BC, NES_SCRIPT }, { 0x23E42, 0x0016, NES_SCRIPT }, { 0x2BD0C, 0x005B, NES_SCRIPT }, { 0x23E58, 0x0020, NES_SCRIPT },
- { 0x27E3B, 0x00B9, NES_SCRIPT }, { 0x2A2B3, 0x03D3, NES_SCRIPT }, { 0x15086, 0x00E4, NES_SCRIPT }, { 0x2B70C, 0x0067, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT },
- { 0x25284, 0x003C, NES_SCRIPT }, { 0x1E9C0, 0x0011, NES_SCRIPT }, { 0x13E40, 0x0018, NES_SCRIPT }, { 0x26621, 0x001F, NES_SCRIPT }, { 0x26640, 0x0054, NES_SCRIPT },
- { 0x26694, 0x0173, NES_SCRIPT }, { 0x26807, 0x004B, NES_SCRIPT }, { 0x26852, 0x0190, NES_SCRIPT }, { 0x269E2, 0x0027, NES_SCRIPT }, { 0x26A09, 0x0041, NES_SCRIPT },
- { 0x26A4A, 0x024E, NES_SCRIPT }, { 0x13E58, 0x001F, NES_SCRIPT }, { 0x24668, 0x002A, NES_SCRIPT }, { 0x1516A, 0x01C9, NES_SCRIPT }, { 0x192D0, 0x0031, NES_SCRIPT },
- { 0x179DB, 0x0088, NES_SCRIPT }, { 0x2162B, 0x00D0, NES_SCRIPT }, { 0x1D3BF, 0x0018, NES_SCRIPT }, { 0x1D3D7, 0x0055, NES_SCRIPT }, { 0x18C36, 0x0005, NES_SCRIPT },
- { 0x15333, 0x0113, NES_SCRIPT }, { 0x15446, 0x000B, NES_SCRIPT }, { 0x24692, 0x014D, NES_SCRIPT }, { 0x247DF, 0x0014, NES_SCRIPT }, { 0x1DF59, 0x0018, NES_SCRIPT },
- { 0x247F3, 0x0027, NES_SCRIPT }, { 0x1A061, 0x0050, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2B773, 0x00A5, NES_SCRIPT }, { 0x2A686, 0x00BA, NES_SCRIPT },
- { 0x2A740, 0x0140, NES_SCRIPT }, { 0x1979F, 0x00CA, NES_SCRIPT }, { 0x19869, 0x014D, NES_SCRIPT }, { 0x199B6, 0x0012, NES_SCRIPT }, { 0x2A880, 0x0005, NES_SCRIPT },
- { 0x2A885, 0x0005, NES_SCRIPT }, { 0x2A88A, 0x0005, NES_SCRIPT }, { 0x2A88F, 0x0005, NES_SCRIPT }, { 0x2A894, 0x0005, NES_SCRIPT }, { 0x216FB, 0x0033, NES_SCRIPT },
- { 0x2A899, 0x0005, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A89E, 0x009C, NES_SCRIPT }, { 0x2A93A, 0x009C, NES_SCRIPT }
-};
-static ScummNESFile::Resource res_scripts_ger[179] = {
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x295B0, 0x045A, NES_SCRIPT }, { 0x29A0A, 0x0218, NES_SCRIPT }, { 0x29C22, 0x00B1, NES_SCRIPT }, { 0x29CD3, 0x0408, NES_SCRIPT },
- { 0x2A0DB, 0x01A1, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A27C, 0x005C, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A2D8, 0x0005, NES_SCRIPT },
- { 0x2C169, 0x000D, NES_SCRIPT }, { 0x2C176, 0x000D, NES_SCRIPT }, { 0x186DB, 0x0040, NES_SCRIPT }, { 0x1871B, 0x0016, NES_SCRIPT }, { 0x1B5C2, 0x0046, NES_SCRIPT },
- { 0x1EFB7, 0x00E3, NES_SCRIPT }, { 0x21D9D, 0x0069, NES_SCRIPT }, { 0x174F1, 0x0027, NES_SCRIPT }, { 0x1FE92, 0x0027, NES_SCRIPT }, { 0x1FEB9, 0x0027, NES_SCRIPT },
- { 0x1BCE5, 0x0022, NES_SCRIPT }, { 0x13EF4, 0x0087, NES_SCRIPT }, { 0x223EC, 0x001F, NES_SCRIPT }, { 0x2240B, 0x008F, NES_SCRIPT }, { 0x192CC, 0x002B, NES_SCRIPT },
- { 0x1CB08, 0x006E, NES_SCRIPT }, { 0x1CB76, 0x004E, NES_SCRIPT }, { 0x1CBC4, 0x004D, NES_SCRIPT }, { 0x1CC11, 0x0059, NES_SCRIPT }, { 0x204AA, 0x0080, NES_SCRIPT },
- { 0x1628E, 0x0035, NES_SCRIPT }, { 0x162C3, 0x001C, NES_SCRIPT }, { 0x162DF, 0x0014, NES_SCRIPT }, { 0x162F3, 0x001C, NES_SCRIPT }, { 0x1630F, 0x0027, NES_SCRIPT },
- { 0x16336, 0x01D1, NES_SCRIPT }, { 0x1D199, 0x00A0, NES_SCRIPT }, { 0x1D239, 0x011C, NES_SCRIPT }, { 0x1D355, 0x001C, NES_SCRIPT }, { 0x1D371, 0x0056, NES_SCRIPT },
- { 0x1D3C7, 0x0072, NES_SCRIPT }, { 0x1E4FA, 0x0028, NES_SCRIPT }, { 0x1E522, 0x019D, NES_SCRIPT }, { 0x1E6BF, 0x023B, NES_SCRIPT }, { 0x2845D, 0x0071, NES_SCRIPT },
- { 0x17C50, 0x0052, NES_SCRIPT }, { 0x15AC9, 0x0039, NES_SCRIPT }, { 0x18731, 0x02E7, NES_SCRIPT }, { 0x18A18, 0x00BC, NES_SCRIPT }, { 0x18AD4, 0x01A2, NES_SCRIPT },
- { 0x00000, 0x0000, NES_SCRIPT }, { 0x19E45, 0x00F8, NES_SCRIPT }, { 0x21E06, 0x00F7, NES_SCRIPT }, { 0x1E8FA, 0x00B5, NES_SCRIPT }, { 0x21EFD, 0x0047, NES_SCRIPT },
- { 0x2C183, 0x004D, NES_SCRIPT }, { 0x15B02, 0x0024, NES_SCRIPT }, { 0x14D64, 0x0014, NES_SCRIPT }, { 0x17518, 0x005E, NES_SCRIPT }, { 0x17576, 0x0125, NES_SCRIPT },
- { 0x1769B, 0x0009, NES_SCRIPT }, { 0x14D78, 0x01C7, NES_SCRIPT }, { 0x2ADCE, 0x0263, NES_SCRIPT }, { 0x232AF, 0x077F, NES_SCRIPT }, { 0x2C1D0, 0x001E, NES_SCRIPT },
- { 0x2C1EE, 0x0024, NES_SCRIPT }, { 0x2C212, 0x002E, NES_SCRIPT }, { 0x2C240, 0x0022, NES_SCRIPT }, { 0x2C262, 0x0013, NES_SCRIPT }, { 0x2C275, 0x001E, NES_SCRIPT },
- { 0x2C293, 0x0016, NES_SCRIPT }, { 0x2C2A9, 0x0027, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2C2D0, 0x0012, NES_SCRIPT }, { 0x176A4, 0x00A4, NES_SCRIPT },
- { 0x228F8, 0x0066, NES_SCRIPT }, { 0x14F3F, 0x007F, NES_SCRIPT }, { 0x1F428, 0x013A, NES_SCRIPT }, { 0x1FEE0, 0x001D, NES_SCRIPT }, { 0x1F562, 0x00A0, NES_SCRIPT },
- { 0x1F602, 0x00A4, NES_SCRIPT }, { 0x17748, 0x0076, NES_SCRIPT }, { 0x177BE, 0x0036, NES_SCRIPT }, { 0x1F6A6, 0x00B9, NES_SCRIPT }, { 0x2C2E2, 0x00CB, NES_SCRIPT },
- { 0x2C3AD, 0x00B7, NES_SCRIPT }, { 0x2C464, 0x008A, NES_SCRIPT }, { 0x20A58, 0x01BD, NES_SCRIPT }, { 0x20C15, 0x0181, NES_SCRIPT }, { 0x20D96, 0x0078, NES_SCRIPT },
- { 0x20E0E, 0x003C, NES_SCRIPT }, { 0x20E4A, 0x00E9, NES_SCRIPT }, { 0x20F33, 0x0046, NES_SCRIPT }, { 0x20F79, 0x00F6, NES_SCRIPT }, { 0x2106F, 0x0118, NES_SCRIPT },
- { 0x21187, 0x015B, NES_SCRIPT }, { 0x212E2, 0x01AC, NES_SCRIPT }, { 0x2148E, 0x003F, NES_SCRIPT }, { 0x214CD, 0x00A9, NES_SCRIPT }, { 0x2436F, 0x0126, NES_SCRIPT },
- { 0x1BD07, 0x0075, NES_SCRIPT }, { 0x1CC6A, 0x009B, NES_SCRIPT }, { 0x28F5D, 0x0054, NES_SCRIPT }, { 0x19F3D, 0x00E1, NES_SCRIPT }, { 0x1A01E, 0x0086, NES_SCRIPT },
- { 0x14FBE, 0x0057, NES_SCRIPT }, { 0x27326, 0x033D, NES_SCRIPT }, { 0x1DA51, 0x023B, NES_SCRIPT }, { 0x1DC8C, 0x00FB, NES_SCRIPT }, { 0x1DD87, 0x0056, NES_SCRIPT },
- { 0x1DDDD, 0x01E1, NES_SCRIPT }, { 0x15015, 0x004D, NES_SCRIPT }, { 0x27027, 0x00E8, NES_SCRIPT }, { 0x21F44, 0x0013, NES_SCRIPT }, { 0x2A2DD, 0x00F0, NES_SCRIPT },
- { 0x24495, 0x00F8, NES_SCRIPT }, { 0x21576, 0x00F9, NES_SCRIPT }, { 0x2458D, 0x002B, NES_SCRIPT }, { 0x2BAA4, 0x010F, NES_SCRIPT }, { 0x245B8, 0x00A5, NES_SCRIPT },
- { 0x250D0, 0x019C, NES_SCRIPT }, { 0x1B608, 0x000D, NES_SCRIPT }, { 0x1B615, 0x000D, NES_SCRIPT }, { 0x23A2E, 0x0185, NES_SCRIPT }, { 0x27957, 0x0212, NES_SCRIPT },
- { 0x23BB3, 0x0158, NES_SCRIPT }, { 0x23D0B, 0x01C4, NES_SCRIPT }, { 0x23ECF, 0x0016, NES_SCRIPT }, { 0x2BBB3, 0x005A, NES_SCRIPT }, { 0x23EE5, 0x0020, NES_SCRIPT },
- { 0x27D6A, 0x00A7, NES_SCRIPT }, { 0x2A3CD, 0x038C, NES_SCRIPT }, { 0x15062, 0x00F6, NES_SCRIPT }, { 0x2B5B2, 0x007B, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT },
- { 0x2526C, 0x003C, NES_SCRIPT }, { 0x1E9AF, 0x0011, NES_SCRIPT }, { 0x15B26, 0x0018, NES_SCRIPT }, { 0x265F5, 0x001F, NES_SCRIPT }, { 0x26614, 0x0054, NES_SCRIPT },
- { 0x26668, 0x018E, NES_SCRIPT }, { 0x267F6, 0x004B, NES_SCRIPT }, { 0x26841, 0x0196, NES_SCRIPT }, { 0x269D7, 0x0027, NES_SCRIPT }, { 0x269FE, 0x0041, NES_SCRIPT },
- { 0x26A3F, 0x01A3, NES_SCRIPT }, { 0x15B3E, 0x001F, NES_SCRIPT }, { 0x2465D, 0x002A, NES_SCRIPT }, { 0x15158, 0x0198, NES_SCRIPT }, { 0x192F7, 0x0031, NES_SCRIPT },
- { 0x177F4, 0x008C, NES_SCRIPT }, { 0x2166F, 0x00DA, NES_SCRIPT }, { 0x1D439, 0x0018, NES_SCRIPT }, { 0x1D451, 0x0054, NES_SCRIPT }, { 0x18C76, 0x0005, NES_SCRIPT },
- { 0x152F0, 0x0126, NES_SCRIPT }, { 0x15416, 0x000B, NES_SCRIPT }, { 0x24687, 0x0137, NES_SCRIPT }, { 0x247BE, 0x0014, NES_SCRIPT }, { 0x1DFBE, 0x0018, NES_SCRIPT },
- { 0x247D2, 0x0027, NES_SCRIPT }, { 0x1A0A4, 0x004D, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2B62D, 0x00A5, NES_SCRIPT }, { 0x2A759, 0x00BA, NES_SCRIPT },
- { 0x2A813, 0x0140, NES_SCRIPT }, { 0x197CF, 0x00D0, NES_SCRIPT }, { 0x1989F, 0x014D, NES_SCRIPT }, { 0x199EC, 0x0012, NES_SCRIPT }, { 0x2A953, 0x0005, NES_SCRIPT },
- { 0x2A958, 0x0005, NES_SCRIPT }, { 0x2A95D, 0x0005, NES_SCRIPT }, { 0x2A962, 0x0005, NES_SCRIPT }, { 0x2A967, 0x0005, NES_SCRIPT }, { 0x21749, 0x0033, NES_SCRIPT },
- { 0x2A96C, 0x0005, NES_SCRIPT }, { 0x00000, 0x0000, NES_SCRIPT }, { 0x2A971, 0x009C, NES_SCRIPT }, { 0x2AA0D, 0x009C, NES_SCRIPT }
-};
-#endif
-static ScummNESFile::Resource *res_scripts[ScummNESFile::kROMsetNum] = {
- res_scripts_usa,
- res_scripts_eur,
- res_scripts_swe,
- res_scripts_fra,
- res_scripts_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_sounds_usa;
-static ScummNESFile::Resource *res_sounds_eur;
-static ScummNESFile::Resource *res_sounds_swe;
-static ScummNESFile::Resource *res_sounds_fra;
-static ScummNESFile::Resource *res_sounds_ger;
-#else
-static ScummNESFile::Resource res_sounds_usa[82] = {
- { 0x0FFE8, 0x000A, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND },
- { 0x30ECA, 0x0832, NES_SOUND }, { 0x17FCA, 0x0011, NES_SOUND }, { 0x27E0B, 0x0073, NES_SOUND }, { 0x17FDB, 0x0011, NES_SOUND }, { 0x17FEC, 0x0011, NES_SOUND },
- { 0x27E7E, 0x0056, NES_SOUND }, { 0x27ED4, 0x001F, NES_SOUND }, { 0x23FEE, 0x0011, NES_SOUND }, { 0x0FFF2, 0x000A, NES_SOUND }, { 0x27EF3, 0x000A, NES_SOUND },
- { 0x27EFD, 0x0019, NES_SOUND }, { 0x27F16, 0x004B, NES_SOUND }, { 0x27F61, 0x000A, NES_SOUND }, { 0x27F6B, 0x000F, NES_SOUND }, { 0x27F7A, 0x001D, NES_SOUND },
- { 0x27F97, 0x0045, NES_SOUND }, { 0x27FDC, 0x000F, NES_SOUND }, { 0x2FD42, 0x001B, NES_SOUND }, { 0x2FD5D, 0x0033, NES_SOUND }, { 0x27FEB, 0x0011, NES_SOUND },
- { 0x2BFEF, 0x000F, NES_SOUND }, { 0x2FD90, 0x0075, NES_SOUND }, { 0x2FE05, 0x0014, NES_SOUND }, { 0x0FFE8, 0x000A, NES_SOUND }, { 0x2FE19, 0x00FF, NES_SOUND },
- { 0x2FF18, 0x000F, NES_SOUND }, { 0x2FF27, 0x000F, NES_SOUND }, { 0x2FF36, 0x0092, NES_SOUND }, { 0x2FF36, 0x0092, NES_SOUND }, { 0x2FFC8, 0x002D, NES_SOUND },
- { 0x316FC, 0x00F8, NES_SOUND }, { 0x317F4, 0x0016, NES_SOUND }, { 0x3180A, 0x0011, NES_SOUND }, { 0x3181B, 0x004B, NES_SOUND }, { 0x31866, 0x0011, NES_SOUND },
- { 0x31877, 0x003B, NES_SOUND }, { 0x318B2, 0x008A, NES_SOUND }, { 0x3193C, 0x0011, NES_SOUND }, { 0x3194D, 0x000F, NES_SOUND }, { 0x3195C, 0x00A2, NES_SOUND },
- { 0x319FE, 0x00D3, NES_SOUND }, { 0x31AD1, 0x0097, NES_SOUND }, { 0x2BFEF, 0x000F, NES_SOUND }, { 0x3195C, 0x00A2, NES_SOUND }, { 0x31B68, 0x05D1, NES_SOUND },
- { 0x31B68, 0x05D1, NES_SOUND }, { 0x32139, 0x0011, NES_SOUND }, { 0x0FFE8, 0x000A, NES_SOUND }, { 0x2FD90, 0x0075, NES_SOUND }, { 0x27ED4, 0x001F, NES_SOUND },
- { 0x3214A, 0x098E, NES_SOUND }, { 0x3181B, 0x004B, NES_SOUND }, { 0x32AD8, 0x0011, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x32AE9, 0x000F, NES_SOUND },
- { 0x32AF8, 0x002F, NES_SOUND }, { 0x32B27, 0x001D, NES_SOUND }, { 0x32B44, 0x0018, NES_SOUND }, { 0x32B5C, 0x0016, NES_SOUND }, { 0x32B72, 0x001B, NES_SOUND },
- { 0x32B8D, 0x0088, NES_SOUND }, { 0x32C15, 0x0065, NES_SOUND }, { 0x32C7A, 0x0065, NES_SOUND }, { 0x32CDF, 0x0073, NES_SOUND }, { 0x32D52, 0x00F9, NES_SOUND },
- { 0x32E4B, 0x049E, NES_SOUND }, { 0x34001, 0x0EA8, NES_SOUND }, { 0x332E9, 0x0B18, NES_SOUND }, { 0x34EA9, 0x0B9C, NES_SOUND }, { 0x35A45, 0x0C6B, NES_SOUND },
- { 0x366B0, 0x0E56, NES_SOUND }, { 0x38001, 0x0C70, NES_SOUND }, { 0x38C71, 0x0DEC, NES_SOUND }, { 0x39A5D, 0x0B77, NES_SOUND }, { 0x37506, 0x042F, NES_SOUND },
- { 0x3A5D4, 0x0AC5, NES_SOUND }, { 0x3B099, 0x0BE4, NES_SOUND }
-};
-static ScummNESFile::Resource res_sounds_eur[82] = {
- { 0x0BF54, 0x000A, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND },
- { 0x30ECA, 0x0832, NES_SOUND }, { 0x0BF5E, 0x0011, NES_SOUND }, { 0x27ECB, 0x0073, NES_SOUND }, { 0x0BF6F, 0x0011, NES_SOUND }, { 0x0FF5D, 0x0011, NES_SOUND },
- { 0x316FC, 0x0056, NES_SOUND }, { 0x13F4E, 0x001F, NES_SOUND }, { 0x0FF6E, 0x0011, NES_SOUND }, { 0x13F6D, 0x000A, NES_SOUND }, { 0x1BF47, 0x000A, NES_SOUND },
- { 0x1BF51, 0x0019, NES_SOUND }, { 0x31752, 0x004B, NES_SOUND }, { 0x1BF6A, 0x000A, NES_SOUND }, { 0x27F3E, 0x000F, NES_SOUND }, { 0x27F4D, 0x001D, NES_SOUND },
- { 0x3179D, 0x0045, NES_SOUND }, { 0x27F6A, 0x000F, NES_SOUND }, { 0x2BF40, 0x001B, NES_SOUND }, { 0x317E2, 0x0033, NES_SOUND }, { 0x2BF5B, 0x0011, NES_SOUND },
- { 0x2BF6C, 0x000F, NES_SOUND }, { 0x31815, 0x0075, NES_SOUND }, { 0x2FF6C, 0x0014, NES_SOUND }, { 0x0BF54, 0x000A, NES_SOUND }, { 0x3188A, 0x00FF, NES_SOUND },
- { 0x31989, 0x000F, NES_SOUND }, { 0x31998, 0x000F, NES_SOUND }, { 0x319A7, 0x0092, NES_SOUND }, { 0x319A7, 0x0092, NES_SOUND }, { 0x31A39, 0x002D, NES_SOUND },
- { 0x31A66, 0x00F8, NES_SOUND }, { 0x31B5E, 0x0016, NES_SOUND }, { 0x31B74, 0x0011, NES_SOUND }, { 0x31B85, 0x004B, NES_SOUND }, { 0x31BD0, 0x0011, NES_SOUND },
- { 0x31BE1, 0x003B, NES_SOUND }, { 0x31C1C, 0x008A, NES_SOUND }, { 0x31CA6, 0x0011, NES_SOUND }, { 0x31CB7, 0x000F, NES_SOUND }, { 0x31CC6, 0x00A2, NES_SOUND },
- { 0x31D68, 0x00D3, NES_SOUND }, { 0x31E3B, 0x0097, NES_SOUND }, { 0x2BF6C, 0x000F, NES_SOUND }, { 0x31CC6, 0x00A2, NES_SOUND }, { 0x31ED2, 0x05D1, NES_SOUND },
- { 0x31ED2, 0x05D1, NES_SOUND }, { 0x324A3, 0x0011, NES_SOUND }, { 0x0BF54, 0x000A, NES_SOUND }, { 0x31815, 0x0075, NES_SOUND }, { 0x13F4E, 0x001F, NES_SOUND },
- { 0x324B4, 0x098E, NES_SOUND }, { 0x31B85, 0x004B, NES_SOUND }, { 0x32E42, 0x0011, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x32E53, 0x000F, NES_SOUND },
- { 0x32E62, 0x002F, NES_SOUND }, { 0x32E91, 0x001D, NES_SOUND }, { 0x32EAE, 0x0018, NES_SOUND }, { 0x32EC6, 0x0016, NES_SOUND }, { 0x32EDC, 0x001B, NES_SOUND },
- { 0x32EF7, 0x0088, NES_SOUND }, { 0x32F7F, 0x0065, NES_SOUND }, { 0x32FE4, 0x0065, NES_SOUND }, { 0x33049, 0x0073, NES_SOUND }, { 0x330BC, 0x00F9, NES_SOUND },
- { 0x331B5, 0x049E, NES_SOUND }, { 0x34001, 0x0EA8, NES_SOUND }, { 0x34EA9, 0x0B18, NES_SOUND }, { 0x359C1, 0x0B9C, NES_SOUND }, { 0x3655D, 0x0C6B, NES_SOUND },
- { 0x38001, 0x0E56, NES_SOUND }, { 0x371C8, 0x0C70, NES_SOUND }, { 0x38E57, 0x0DEC, NES_SOUND }, { 0x39C43, 0x0B77, NES_SOUND }, { 0x33653, 0x042F, NES_SOUND },
- { 0x3A7BA, 0x0AC5, NES_SOUND }, { 0x3B27F, 0x0BE4, NES_SOUND }
-};
-static ScummNESFile::Resource res_sounds_swe[82] = {
- { 0x0BF58, 0x000A, NES_SOUND }, { 0x30352, 0x0832, NES_SOUND }, { 0x30352, 0x0832, NES_SOUND }, { 0x30352, 0x0832, NES_SOUND }, { 0x30352, 0x0832, NES_SOUND },
- { 0x30352, 0x0832, NES_SOUND }, { 0x0BF62, 0x0011, NES_SOUND }, { 0x27E5F, 0x0073, NES_SOUND }, { 0x17F5A, 0x0011, NES_SOUND }, { 0x17F6B, 0x0011, NES_SOUND },
- { 0x27ED2, 0x0056, NES_SOUND }, { 0x1BF55, 0x001F, NES_SOUND }, { 0x23F66, 0x0011, NES_SOUND }, { 0x0BF73, 0x000A, NES_SOUND }, { 0x1BF74, 0x000A, NES_SOUND },
- { 0x27F28, 0x0019, NES_SOUND }, { 0x2BF0A, 0x004B, NES_SOUND }, { 0x1FF71, 0x000A, NES_SOUND }, { 0x27F41, 0x000F, NES_SOUND }, { 0x27F50, 0x001D, NES_SOUND },
- { 0x2FEAA, 0x0045, NES_SOUND }, { 0x27F6D, 0x000F, NES_SOUND }, { 0x2BF55, 0x001B, NES_SOUND }, { 0x2FEEF, 0x0033, NES_SOUND }, { 0x2FF22, 0x0011, NES_SOUND },
- { 0x2BF70, 0x000F, NES_SOUND }, { 0x30B84, 0x0075, NES_SOUND }, { 0x2FF33, 0x0014, NES_SOUND }, { 0x0BF58, 0x000A, NES_SOUND }, { 0x30BF9, 0x00FF, NES_SOUND },
- { 0x2FF47, 0x000F, NES_SOUND }, { 0x2FF56, 0x000F, NES_SOUND }, { 0x30CF8, 0x0092, NES_SOUND }, { 0x30CF8, 0x0092, NES_SOUND }, { 0x30D8A, 0x002D, NES_SOUND },
- { 0x30DB7, 0x00F8, NES_SOUND }, { 0x2FF65, 0x0016, NES_SOUND }, { 0x30EAF, 0x0011, NES_SOUND }, { 0x30EC0, 0x004B, NES_SOUND }, { 0x30F0B, 0x0011, NES_SOUND },
- { 0x30F1C, 0x003B, NES_SOUND }, { 0x30F57, 0x008A, NES_SOUND }, { 0x30FE1, 0x0011, NES_SOUND }, { 0x30FF2, 0x000F, NES_SOUND }, { 0x31001, 0x00A2, NES_SOUND },
- { 0x310A3, 0x00D3, NES_SOUND }, { 0x31176, 0x0097, NES_SOUND }, { 0x2BF70, 0x000F, NES_SOUND }, { 0x31001, 0x00A2, NES_SOUND }, { 0x3120D, 0x05D1, NES_SOUND },
- { 0x3120D, 0x05D1, NES_SOUND }, { 0x317DE, 0x0011, NES_SOUND }, { 0x0BF58, 0x000A, NES_SOUND }, { 0x30B84, 0x0075, NES_SOUND }, { 0x1BF55, 0x001F, NES_SOUND },
- { 0x317EF, 0x098E, NES_SOUND }, { 0x30EC0, 0x004B, NES_SOUND }, { 0x3217D, 0x0011, NES_SOUND }, { 0x30352, 0x0832, NES_SOUND }, { 0x3218E, 0x000F, NES_SOUND },
- { 0x3219D, 0x002F, NES_SOUND }, { 0x321CC, 0x001D, NES_SOUND }, { 0x321E9, 0x0018, NES_SOUND }, { 0x32201, 0x0016, NES_SOUND }, { 0x32217, 0x001B, NES_SOUND },
- { 0x32232, 0x0088, NES_SOUND }, { 0x322BA, 0x0065, NES_SOUND }, { 0x3231F, 0x0065, NES_SOUND }, { 0x32384, 0x0073, NES_SOUND }, { 0x323F7, 0x00F9, NES_SOUND },
- { 0x324F0, 0x049E, NES_SOUND }, { 0x3298E, 0x0EA8, NES_SOUND }, { 0x34001, 0x0B18, NES_SOUND }, { 0x34B19, 0x0B9C, NES_SOUND }, { 0x356B5, 0x0C6B, NES_SOUND },
- { 0x36320, 0x0E56, NES_SOUND }, { 0x37176, 0x0C70, NES_SOUND }, { 0x38001, 0x0DEC, NES_SOUND }, { 0x38DED, 0x0B77, NES_SOUND }, { 0x33836, 0x042F, NES_SOUND },
- { 0x39964, 0x0AC5, NES_SOUND }, { 0x3A429, 0x0BE4, NES_SOUND }
-};
-static ScummNESFile::Resource res_sounds_fra[82] = {
- { 0x07F74, 0x000A, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND },
- { 0x30ECA, 0x0832, NES_SOUND }, { 0x0BF6C, 0x0011, NES_SOUND }, { 0x1BEFA, 0x0073, NES_SOUND }, { 0x17F10, 0x0011, NES_SOUND }, { 0x17F21, 0x0011, NES_SOUND },
- { 0x1FED5, 0x0056, NES_SOUND }, { 0x17F32, 0x001F, NES_SOUND }, { 0x17F51, 0x0011, NES_SOUND }, { 0x0FF76, 0x000A, NES_SOUND }, { 0x17F62, 0x000A, NES_SOUND },
- { 0x1FF2B, 0x0019, NES_SOUND }, { 0x23E78, 0x004B, NES_SOUND }, { 0x17F6C, 0x000A, NES_SOUND }, { 0x1BF6D, 0x000F, NES_SOUND }, { 0x1FF44, 0x001D, NES_SOUND },
- { 0x23EC3, 0x0045, NES_SOUND }, { 0x1FF61, 0x000F, NES_SOUND }, { 0x23F08, 0x001B, NES_SOUND }, { 0x23F23, 0x0033, NES_SOUND }, { 0x23F56, 0x0011, NES_SOUND },
- { 0x1FF70, 0x000F, NES_SOUND }, { 0x27EF4, 0x0075, NES_SOUND }, { 0x23F67, 0x0014, NES_SOUND }, { 0x07F74, 0x000A, NES_SOUND }, { 0x2FB83, 0x00FF, NES_SOUND },
- { 0x27F69, 0x000F, NES_SOUND }, { 0x2BF70, 0x000F, NES_SOUND }, { 0x2FC82, 0x0092, NES_SOUND }, { 0x2FC82, 0x0092, NES_SOUND }, { 0x2FD14, 0x002D, NES_SOUND },
- { 0x2FD41, 0x00F8, NES_SOUND }, { 0x2FE39, 0x0016, NES_SOUND }, { 0x2FE4F, 0x0011, NES_SOUND }, { 0x2FE60, 0x004B, NES_SOUND }, { 0x2FEAB, 0x0011, NES_SOUND },
- { 0x2FEBC, 0x003B, NES_SOUND }, { 0x316FC, 0x008A, NES_SOUND }, { 0x2FEF7, 0x0011, NES_SOUND }, { 0x2FF08, 0x000F, NES_SOUND }, { 0x31786, 0x00A2, NES_SOUND },
- { 0x31828, 0x00D3, NES_SOUND }, { 0x318FB, 0x0097, NES_SOUND }, { 0x1FF70, 0x000F, NES_SOUND }, { 0x31786, 0x00A2, NES_SOUND }, { 0x31992, 0x05D1, NES_SOUND },
- { 0x31992, 0x05D1, NES_SOUND }, { 0x2FF17, 0x0011, NES_SOUND }, { 0x07F74, 0x000A, NES_SOUND }, { 0x27EF4, 0x0075, NES_SOUND }, { 0x17F32, 0x001F, NES_SOUND },
- { 0x31F63, 0x098E, NES_SOUND }, { 0x2FE60, 0x004B, NES_SOUND }, { 0x2FF28, 0x0011, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x2FF39, 0x000F, NES_SOUND },
- { 0x2FF48, 0x002F, NES_SOUND }, { 0x328F1, 0x001D, NES_SOUND }, { 0x3290E, 0x0018, NES_SOUND }, { 0x32926, 0x0016, NES_SOUND }, { 0x3293C, 0x001B, NES_SOUND },
- { 0x32957, 0x0088, NES_SOUND }, { 0x329DF, 0x0065, NES_SOUND }, { 0x32A44, 0x0065, NES_SOUND }, { 0x32AA9, 0x0073, NES_SOUND }, { 0x32B1C, 0x00F9, NES_SOUND },
- { 0x32C15, 0x049E, NES_SOUND }, { 0x330B3, 0x0EA8, NES_SOUND }, { 0x34001, 0x0B18, NES_SOUND }, { 0x34B19, 0x0B9C, NES_SOUND }, { 0x356B5, 0x0C6B, NES_SOUND },
- { 0x36320, 0x0E56, NES_SOUND }, { 0x37176, 0x0C70, NES_SOUND }, { 0x38001, 0x0DEC, NES_SOUND }, { 0x38DED, 0x0B77, NES_SOUND }, { 0x39964, 0x042F, NES_SOUND },
- { 0x39D93, 0x0AC5, NES_SOUND }, { 0x3A858, 0x0BE4, NES_SOUND }
-};
-static ScummNESFile::Resource res_sounds_ger[82] = {
- { 0x0BF6D, 0x000A, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND },
- { 0x30ECA, 0x0832, NES_SOUND }, { 0x23F05, 0x0011, NES_SOUND }, { 0x2FA49, 0x0073, NES_SOUND }, { 0x23F16, 0x0011, NES_SOUND }, { 0x23F27, 0x0011, NES_SOUND },
- { 0x2FABC, 0x0056, NES_SOUND }, { 0x23F38, 0x001F, NES_SOUND }, { 0x23F57, 0x0011, NES_SOUND }, { 0x0FF76, 0x000A, NES_SOUND }, { 0x17F71, 0x000A, NES_SOUND },
- { 0x2BF2F, 0x0019, NES_SOUND }, { 0x2FB12, 0x004B, NES_SOUND }, { 0x23F68, 0x000A, NES_SOUND }, { 0x2BF48, 0x000F, NES_SOUND }, { 0x2BF57, 0x001D, NES_SOUND },
- { 0x2FB5D, 0x0045, NES_SOUND }, { 0x2FBA2, 0x000F, NES_SOUND }, { 0x2FBB1, 0x001B, NES_SOUND }, { 0x2FBCC, 0x0033, NES_SOUND }, { 0x2FBFF, 0x0011, NES_SOUND },
- { 0x2FC10, 0x000F, NES_SOUND }, { 0x2FC1F, 0x0075, NES_SOUND }, { 0x2FC94, 0x0014, NES_SOUND }, { 0x0BF6D, 0x000A, NES_SOUND }, { 0x2FCA8, 0x00FF, NES_SOUND },
- { 0x2FDA7, 0x000F, NES_SOUND }, { 0x2FDB6, 0x000F, NES_SOUND }, { 0x2FDC5, 0x0092, NES_SOUND }, { 0x2FDC5, 0x0092, NES_SOUND }, { 0x2FE57, 0x002D, NES_SOUND },
- { 0x2FE84, 0x00F8, NES_SOUND }, { 0x316FC, 0x0016, NES_SOUND }, { 0x31712, 0x0011, NES_SOUND }, { 0x31723, 0x004B, NES_SOUND }, { 0x3176E, 0x0011, NES_SOUND },
- { 0x3177F, 0x003B, NES_SOUND }, { 0x317BA, 0x008A, NES_SOUND }, { 0x31844, 0x0011, NES_SOUND }, { 0x31855, 0x000F, NES_SOUND }, { 0x31864, 0x00A2, NES_SOUND },
- { 0x31906, 0x00D3, NES_SOUND }, { 0x319D9, 0x0097, NES_SOUND }, { 0x2FC10, 0x000F, NES_SOUND }, { 0x31864, 0x00A2, NES_SOUND }, { 0x31A70, 0x05D1, NES_SOUND },
- { 0x31A70, 0x05D1, NES_SOUND }, { 0x32041, 0x0011, NES_SOUND }, { 0x0BF6D, 0x000A, NES_SOUND }, { 0x2FC1F, 0x0075, NES_SOUND }, { 0x23F38, 0x001F, NES_SOUND },
- { 0x32052, 0x098E, NES_SOUND }, { 0x31723, 0x004B, NES_SOUND }, { 0x329E0, 0x0011, NES_SOUND }, { 0x30ECA, 0x0832, NES_SOUND }, { 0x329F1, 0x000F, NES_SOUND },
- { 0x32A00, 0x002F, NES_SOUND }, { 0x32A2F, 0x001D, NES_SOUND }, { 0x32A4C, 0x0018, NES_SOUND }, { 0x32A64, 0x0016, NES_SOUND }, { 0x32A7A, 0x001B, NES_SOUND },
- { 0x32A95, 0x0088, NES_SOUND }, { 0x32B1D, 0x0065, NES_SOUND }, { 0x32B82, 0x0065, NES_SOUND }, { 0x32BE7, 0x0073, NES_SOUND }, { 0x32C5A, 0x00F9, NES_SOUND },
- { 0x32D53, 0x049E, NES_SOUND }, { 0x34001, 0x0EA8, NES_SOUND }, { 0x331F1, 0x0B18, NES_SOUND }, { 0x34EA9, 0x0B9C, NES_SOUND }, { 0x35A45, 0x0C6B, NES_SOUND },
- { 0x366B0, 0x0E56, NES_SOUND }, { 0x38001, 0x0C70, NES_SOUND }, { 0x38C71, 0x0DEC, NES_SOUND }, { 0x39A5D, 0x0B77, NES_SOUND }, { 0x37506, 0x042F, NES_SOUND },
- { 0x3A5D4, 0x0AC5, NES_SOUND }, { 0x3B099, 0x0BE4, NES_SOUND }
-};
-#endif
-static ScummNESFile::Resource *res_sounds[ScummNESFile::kROMsetNum] = {
- res_sounds_usa,
- res_sounds_eur,
- res_sounds_swe,
- res_sounds_fra,
- res_sounds_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_costumes_usa;
-static ScummNESFile::Resource *res_costumes_eur;
-static ScummNESFile::Resource *res_costumes_swe;
-static ScummNESFile::Resource *res_costumes_fra;
-static ScummNESFile::Resource *res_costumes_ger;
-#else
-static ScummNESFile::Resource res_costumes_usa[25] = {
- { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME },
- { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x13FAB, 0x004B, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME },
- { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x17F5A, 0x0036, NES_COSTUME }, { 0x17F90, 0x003A, NES_COSTUME }, { 0x17F90, 0x003A, NES_COSTUME },
- { 0x17F05, 0x0055, NES_COSTUME }, { 0x1BF87, 0x003B, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x23FA9, 0x0045, NES_COSTUME }, { 0x1FFBD, 0x0040, NES_COSTUME },
- { 0x1BFC2, 0x003C, NES_COSTUME }, { 0x17F90, 0x003A, NES_COSTUME }, { 0x17F90, 0x003A, NES_COSTUME }, { 0x17F05, 0x0055, NES_COSTUME }, { 0x13FAB, 0x004B, NES_COSTUME }
-};
-static ScummNESFile::Resource res_costumes_eur[25] = {
- { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME },
- { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0FEA2, 0x004B, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME },
- { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0FEED, 0x0036, NES_COSTUME }, { 0x0FF23, 0x003A, NES_COSTUME }, { 0x0FF23, 0x003A, NES_COSTUME },
- { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x13F13, 0x003B, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x23F2F, 0x0045, NES_COSTUME }, { 0x1FF3E, 0x0040, NES_COSTUME },
- { 0x27E8F, 0x003C, NES_COSTUME }, { 0x0FF23, 0x003A, NES_COSTUME }, { 0x0FF23, 0x003A, NES_COSTUME }, { 0x0BEFF, 0x0055, NES_COSTUME }, { 0x0FEA2, 0x004B, NES_COSTUME }
-};
-static ScummNESFile::Resource res_costumes_swe[25] = {
- { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME },
- { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x17E9A, 0x004B, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME },
- { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x0FF4A, 0x0036, NES_COSTUME }, { 0x17EE5, 0x003A, NES_COSTUME }, { 0x17EE5, 0x003A, NES_COSTUME },
- { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x17F1F, 0x003B, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x1BE94, 0x0045, NES_COSTUME }, { 0x1BED9, 0x0040, NES_COSTUME },
- { 0x1BF19, 0x003C, NES_COSTUME }, { 0x17EE5, 0x003A, NES_COSTUME }, { 0x17EE5, 0x003A, NES_COSTUME }, { 0x0FEF5, 0x0055, NES_COSTUME }, { 0x17E9A, 0x004B, NES_COSTUME }
-};
-static ScummNESFile::Resource res_costumes_fra[25] = {
- { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME },
- { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x13E77, 0x004B, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME },
- { 0x0BF17, 0x0055, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x07F3E, 0x0036, NES_COSTUME }, { 0x13EC2, 0x003A, NES_COSTUME }, { 0x13EC2, 0x003A, NES_COSTUME },
- { 0x0BF17, 0x0055, NES_COSTUME }, { 0x13EFC, 0x003B, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x13F37, 0x0045, NES_COSTUME }, { 0x17E94, 0x0040, NES_COSTUME },
- { 0x17ED4, 0x003C, NES_COSTUME }, { 0x13EC2, 0x003A, NES_COSTUME }, { 0x13EC2, 0x003A, NES_COSTUME }, { 0x0BF17, 0x0055, NES_COSTUME }, { 0x13E77, 0x004B, NES_COSTUME }
-};
-static ScummNESFile::Resource res_costumes_ger[25] = {
- { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME },
- { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x17E6C, 0x004B, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME },
- { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x0FF40, 0x0036, NES_COSTUME }, { 0x17EB7, 0x003A, NES_COSTUME }, { 0x17EB7, 0x003A, NES_COSTUME },
- { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x17EF1, 0x003B, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x17F2C, 0x0045, NES_COSTUME }, { 0x1FEFD, 0x0040, NES_COSTUME },
- { 0x1FF3D, 0x003C, NES_COSTUME }, { 0x17EB7, 0x003A, NES_COSTUME }, { 0x17EB7, 0x003A, NES_COSTUME }, { 0x0FEEB, 0x0055, NES_COSTUME }, { 0x17E6C, 0x004B, NES_COSTUME }
-};
-#endif
-static ScummNESFile::Resource *res_costumes[ScummNESFile::kROMsetNum] = {
- res_costumes_usa,
- res_costumes_eur,
- res_costumes_swe,
- res_costumes_fra,
- res_costumes_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_globdata_usa;
-static ScummNESFile::Resource *res_globdata_eur;
-static ScummNESFile::Resource *res_globdata_swe;
-static ScummNESFile::Resource *res_globdata_fra;
-static ScummNESFile::Resource *res_globdata_ger;
-#else
-static ScummNESFile::Resource res_globdata_usa[1] = { { 0x2CA11, 0x0307, NES_GLOBDATA } };
-static ScummNESFile::Resource res_globdata_eur[1] = { { 0x2CA11, 0x0307, NES_GLOBDATA } };
-static ScummNESFile::Resource res_globdata_swe[1] = { { 0x2C001, 0x0307, NES_GLOBDATA } };
-static ScummNESFile::Resource res_globdata_fra[1] = { { 0x2C628, 0x0307, NES_GLOBDATA } };
-static ScummNESFile::Resource res_globdata_ger[1] = { { 0x2C4EE, 0x0307, NES_GLOBDATA } };
-#endif
-static ScummNESFile::Resource *res_globdata[ScummNESFile::kROMsetNum] = {
- res_globdata_usa,
- res_globdata_eur,
- res_globdata_swe,
- res_globdata_fra,
- res_globdata_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_sprpals_usa;
-static ScummNESFile::Resource *res_sprpals_eur;
-static ScummNESFile::Resource *res_sprpals_swe;
-static ScummNESFile::Resource *res_sprpals_fra;
-static ScummNESFile::Resource *res_sprpals_ger;
-#else
-// sprite palette data
-static ScummNESFile::Resource res_sprpals_usa[2] = { { 0x0BFC1, 0x0010, NES_SPRPALS }, { 0x0BFD1, 0x0010, NES_SPRPALS } };
-static ScummNESFile::Resource res_sprpals_eur[2] = { { 0x07F61, 0x0010, NES_SPRPALS }, { 0x0BEB2, 0x0010, NES_SPRPALS } };
-static ScummNESFile::Resource res_sprpals_swe[2] = { { 0x07F55, 0x0010, NES_SPRPALS }, { 0x07F65, 0x0010, NES_SPRPALS } };
-static ScummNESFile::Resource res_sprpals_fra[2] = { { 0x07ED8, 0x0010, NES_SPRPALS }, { 0x07EE8, 0x0010, NES_SPRPALS } };
-static ScummNESFile::Resource res_sprpals_ger[2] = { { 0x07F6B, 0x0010, NES_SPRPALS }, { 0x0BF17, 0x0010, NES_SPRPALS } };
-#endif
-static ScummNESFile::Resource *res_sprpals[ScummNESFile::kROMsetNum] = {
- res_sprpals_usa,
- res_sprpals_eur,
- res_sprpals_swe,
- res_sprpals_fra,
- res_sprpals_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_sprdesc_usa;
-static ScummNESFile::Resource *res_sprdesc_eur;
-static ScummNESFile::Resource *res_sprdesc_swe;
-static ScummNESFile::Resource *res_sprdesc_fra;
-static ScummNESFile::Resource *res_sprdesc_ger;
-#else
-// associates costume IDs with sprite sets (indexes into SPRLENS/SPROFFS)
-static ScummNESFile::Resource res_sprdesc_usa[2] = { { 0x0FFB7, 0x0031, NES_SPRDESC }, { 0x0BFE1, 0x0009, NES_SPRDESC } };
-static ScummNESFile::Resource res_sprdesc_eur[2] = { { 0x0BEC2, 0x0031, NES_SPRDESC }, { 0x07F71, 0x0009, NES_SPRDESC } };
-static ScummNESFile::Resource res_sprdesc_swe[2] = { { 0x0BF1B, 0x0031, NES_SPRDESC }, { 0x07F75, 0x0009, NES_SPRDESC } };
-static ScummNESFile::Resource res_sprdesc_fra[2] = { { 0x07EF8, 0x0031, NES_SPRDESC }, { 0x07F29, 0x0009, NES_SPRDESC } };
-static ScummNESFile::Resource res_sprdesc_ger[2] = { { 0x0BF27, 0x0031, NES_SPRDESC }, { 0x0BF58, 0x0009, NES_SPRDESC } };
-#endif
-static ScummNESFile::Resource *res_sprdesc[ScummNESFile::kROMsetNum] = {
- res_sprdesc_usa,
- res_sprdesc_eur,
- res_sprdesc_swe,
- res_sprdesc_fra,
- res_sprdesc_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_sprlens_usa;
-static ScummNESFile::Resource *res_sprlens_eur;
-static ScummNESFile::Resource *res_sprlens_swe;
-static ScummNESFile::Resource *res_sprlens_fra;
-static ScummNESFile::Resource *res_sprlens_ger;
-#else
-// number of sprites in each set (indicates length within SPRDATA)
-static ScummNESFile::Resource res_sprlens_usa[2] = { { 0x0FEA2, 0x0115, NES_SPRLENS }, { 0x07FF5, 0x0006, NES_SPRLENS } };
-static ScummNESFile::Resource res_sprlens_eur[2] = { { 0x1BE32, 0x0115, NES_SPRLENS }, { 0x07F5B, 0x0006, NES_SPRLENS } };
-static ScummNESFile::Resource res_sprlens_swe[2] = { { 0x13E6A, 0x0115, NES_SPRLENS }, { 0x07F4F, 0x0006, NES_SPRLENS } };
-static ScummNESFile::Resource res_sprlens_fra[2] = { { 0x0FE61, 0x0115, NES_SPRLENS }, { 0x07ED2, 0x0006, NES_SPRLENS } };
-static ScummNESFile::Resource res_sprlens_ger[2] = { { 0x2BE1A, 0x0115, NES_SPRLENS }, { 0x07F65, 0x0006, NES_SPRLENS } };
-#endif
-static ScummNESFile::Resource *res_sprlens[ScummNESFile::kROMsetNum] = {
- res_sprlens_usa,
- res_sprlens_eur,
- res_sprlens_swe,
- res_sprlens_fra,
- res_sprlens_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_sproffs_usa;
-static ScummNESFile::Resource *res_sproffs_eur;
-static ScummNESFile::Resource *res_sproffs_swe;
-static ScummNESFile::Resource *res_sproffs_fra;
-static ScummNESFile::Resource *res_sproffs_ger;
-#else
-// offset of each sprite set (indexes into SPRDATA)
-static ScummNESFile::Resource res_sproffs_usa[2] = { { 0x2BDC5, 0x022A, NES_SPROFFS }, { 0x0BFEA, 0x000C, NES_SPROFFS } };
-static ScummNESFile::Resource res_sproffs_eur[2] = { { 0x2FD42, 0x022A, NES_SPROFFS }, { 0x0BEF3, 0x000C, NES_SPROFFS } };
-static ScummNESFile::Resource res_sproffs_swe[2] = { { 0x2BCE0, 0x022A, NES_SPROFFS }, { 0x0BF4C, 0x000C, NES_SPROFFS } };
-static ScummNESFile::Resource res_sproffs_fra[2] = { { 0x2F959, 0x022A, NES_SPROFFS }, { 0x07F32, 0x000C, NES_SPROFFS } };
-static ScummNESFile::Resource res_sproffs_ger[2] = { { 0x2F81F, 0x022A, NES_SPROFFS }, { 0x0BF61, 0x000C, NES_SPROFFS } };
-#endif
-static ScummNESFile::Resource *res_sproffs[ScummNESFile::kROMsetNum] = {
- res_sproffs_usa,
- res_sproffs_eur,
- res_sproffs_swe,
- res_sproffs_fra,
- res_sproffs_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_sprdata_usa;
-static ScummNESFile::Resource *res_sprdata_eur;
-static ScummNESFile::Resource *res_sprdata_swe;
-static ScummNESFile::Resource *res_sprdata_fra;
-static ScummNESFile::Resource *res_sprdata_ger;
-#else
-// sprite data sets (packed NES sprite data)
-static ScummNESFile::Resource res_sprdata_usa[2] = { { 0x2CE11, 0x2BE0, NES_SPRDATA }, { 0x07F6B, 0x008A, NES_SPRDATA } };
-static ScummNESFile::Resource res_sprdata_eur[2] = { { 0x2CE11, 0x2BE0, NES_SPRDATA }, { 0x0BE28, 0x008A, NES_SPRDATA } };
-static ScummNESFile::Resource res_sprdata_swe[2] = { { 0x2C401, 0x2BE0, NES_SPRDATA }, { 0x0FE6B, 0x008A, NES_SPRDATA } };
-static ScummNESFile::Resource res_sprdata_fra[2] = { { 0x2CA28, 0x2BE0, NES_SPRDATA }, { 0x07E48, 0x008A, NES_SPRDATA } };
-static ScummNESFile::Resource res_sprdata_ger[2] = { { 0x2C8EE, 0x2BE0, NES_SPRDATA }, { 0x0FE61, 0x008A, NES_SPRDATA } };
-static ScummNESFile::Resource *res_sprdata[ScummNESFile::kROMsetNum] = {
- res_sprdata_usa,
- res_sprdata_eur,
- res_sprdata_swe,
- res_sprdata_fra,
- res_sprdata_ger,
-};
-#endif
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_charset_usa;
-static ScummNESFile::Resource *res_charset_eur;
-static ScummNESFile::Resource *res_charset_swe;
-static ScummNESFile::Resource *res_charset_fra;
-static ScummNESFile::Resource *res_charset_ger;
-#else
-static ScummNESFile::Resource res_charset_usa[1] = { { 0x3F6EE, 0x0090, NES_CHARSET } };
-static ScummNESFile::Resource res_charset_eur[1] = { { 0x3F724, 0x0090, NES_CHARSET } };
-static ScummNESFile::Resource res_charset_swe[1] = { { 0x3F739, 0x0090, NES_CHARSET } };
-static ScummNESFile::Resource res_charset_fra[1] = { { 0x3F739, 0x0090, NES_CHARSET } };
-static ScummNESFile::Resource res_charset_ger[1] = { { 0x3F739, 0x0090, NES_CHARSET } };
-#endif
-static ScummNESFile::Resource *res_charset[ScummNESFile::kROMsetNum] = {
- res_charset_usa,
- res_charset_eur,
- res_charset_swe,
- res_charset_fra,
- res_charset_ger,
-};
-
-#ifdef PALMOS_68K
-static ScummNESFile::Resource *res_preplist_usa;
-static ScummNESFile::Resource *res_preplist_eur;
-static ScummNESFile::Resource *res_preplist_swe;
-static ScummNESFile::Resource *res_preplist_fra;
-static ScummNESFile::Resource *res_preplist_ger;
-#else
-static ScummNESFile::Resource res_preplist_usa[1] = { { 0x3FB5A, 0x000E, NES_PREPLIST } };
-static ScummNESFile::Resource res_preplist_eur[1] = { { 0x3FB90, 0x000E, NES_PREPLIST } };
-static ScummNESFile::Resource res_preplist_swe[1] = { { 0x3FBA9, 0x000E, NES_PREPLIST } };
-static ScummNESFile::Resource res_preplist_fra[1] = { { 0x3FBAF, 0x0010, NES_PREPLIST } };
-static ScummNESFile::Resource res_preplist_ger[1] = { { 0x3FBAB, 0x000F, NES_PREPLIST } };
-#endif
-static ScummNESFile::Resource *res_preplist[ScummNESFile::kROMsetNum] = {
- res_preplist_usa,
- res_preplist_eur,
- res_preplist_swe,
- res_preplist_fra,
- res_preplist_ger,
-};
-
-uint16 write_byte(Common::WriteStream *out, byte val) {
- val ^= 0xFF;
- if (out != 0)
- out->writeByte(val);
- return 1;
-}
-
-uint16 write_word(Common::WriteStream *out, uint16 val) {
- val ^= 0xFFFF;
- if (out != 0)
- out->writeUint16LE(val);
- return 2;
-}
-
-byte ScummNESFile::fileReadByte() {
- byte b = 0;
- File::read(&b, 1);
- return b;
-}
-
-uint16 ScummNESFile::fileReadUint16LE() {
- uint16 a = fileReadByte();
- uint16 b = fileReadByte();
- return a | (b << 8);
-}
-
-uint16 ScummNESFile::extractResource(Common::WriteStream *output, Resource *res) {
- uint16 len, i, j;
- byte val;
- byte cnt;
- uint16 reslen = 0;
-
- if (res == NULL)
- error("extract_resource - no resource specified");
-
- if ((res->offset == 0) && (res->length == 0))
- return 0; /* there are 8 scripts that are zero bytes long, so we should skip them */
-
- File::seek(res->offset,SEEK_SET);
-
- switch (res->type) {
- case NES_GLOBDATA:
- len = res->length;
-
- for (i = 0; i < len; i++)
- reslen += write_byte(output, fileReadByte());
-
- break;
-
- case NES_ROOMGFX:
- case NES_COSTUMEGFX:
- reslen += write_word(output, (uint16)(res->length + 2));
- len = fileReadByte();
- reslen += write_byte(output, (byte)len);
-
- if (!len)
- len = 256;
- len = len << 4;
-
- for (i = 0; i < len;) {
- reslen += write_byte(output, cnt = fileReadByte());
- for (j = 0; j < (cnt & 0x7F); j++, i++)
- if ((cnt & 0x80) || (j == 0))
- reslen += write_byte(output, fileReadByte());
- }
-
- if (File::pos() - res->offset != res->length)
- error("extract_resource - length mismatch while extracting graphics resource (was %04X, should be %04X)", File::pos() - res->offset, res->length);
-
- break;
-
- case NES_ROOM:
- case NES_SCRIPT:
- len = fileReadUint16LE();
-
- if (len != res->length)
- error("extract_resource - length mismatch while extracting room/script resource (was %04X, should be %04X)", len, res->length);
-
- File::seek(-2, SEEK_CUR);
-
- for (i = 0; i < len; i++)
- reslen += write_byte(output, fileReadByte());
-
- break;
-
- case NES_SOUND:
- len = res->length + 2;
- val = fileReadByte();
- cnt = fileReadByte();
-
- if ((val == 2) && (cnt == 100)) {
- reslen += write_word(output, len);
- reslen += write_byte(output, val);
- reslen += write_byte(output, cnt);
-
- cnt = fileReadByte();
- reslen += write_byte(output, cnt);
- for (i = 0; i < cnt; i++)
- reslen += write_byte(output, fileReadByte());
- for (i = 0; i < cnt; i++)
- reslen += write_byte(output, fileReadByte());
-
- while (1) {
- reslen += write_byte(output, val = fileReadByte());
- if (val >= 0xFE)
- break;
- }
- } else if (((val == 0) || (val == 1) || (val == 4)) && (cnt == 10)) {
- reslen += write_word(output, len);
- reslen += write_byte(output, val);
- reslen += write_byte(output, cnt);
- while (1) {
- reslen += write_byte(output, val = fileReadByte());
-
- if (val >= 0xFE)
- break;
-
- if (val >= 0x10)
- reslen += write_byte(output, fileReadByte());
- else {
- reslen += write_byte(output, fileReadByte());
- reslen += write_byte(output, fileReadByte());
- reslen += write_byte(output, fileReadByte());
- reslen += write_byte(output, fileReadByte());
- }
- }
- } else
- error("extract_resource - unknown sound type %d/%d detected",val,cnt);
-
- if (File::pos() - res->offset != res->length)
- error("extract_resource - length mismatch while extracting sound resource (was %04X, should be %04X)", File::pos() - res->offset, res->length);
-
- break;
-
- case NES_COSTUME:
- case NES_SPRPALS:
- case NES_SPRDESC:
- case NES_SPRLENS:
- case NES_SPROFFS:
- case NES_SPRDATA:
- case NES_CHARSET:
- len = res->length;
- reslen += write_word(output, (uint16)(len + 2));
-
- for (i = 0; i < len; i++)
- reslen += write_byte(output, fileReadByte());
-
- break;
-
- case NES_PREPLIST:
- len = res->length;
- reslen += write_word(output, 0x002A);
-
- reslen += write_byte(output, ' ');
- for (i = 1; i < 8; i++)
- reslen += write_byte(output, 0);
-
- for (j = 0; j < 4; j++)
- {
- reslen += write_byte(output,' ');
- for (i = 1; (val = fileReadByte()); i++)
- reslen += write_byte(output, val);
- for (; i < 8; i++)
- reslen += write_byte(output, 0);
- }
- break;
-
- default:
- error("extract_resource - unknown resource type %d specified!", res->type);
- }
-
- return reslen;
-}
-
-struct ScummNESFile::LFLEntry {
- Resource **type;
- int index;
-};
-
-// based on structure of Classic PC Maniac Mansion LFL files
-// (roomgfx resources are arranged in order, one per file,
-// after the room blocks)
-static ScummNESFile::LFLEntry lfl_01[] = { {res_rooms, 1}, {res_roomgfx, 1}, {res_scripts, 57}, {res_scripts, 61}, {res_scripts, 76}, {res_scripts, 105}, {res_scripts, 111}, {res_sounds, 5}, {res_scripts, 132}, {res_scripts, 148}, {res_scripts, 155}, {res_scripts, 156}, {res_sounds, 39}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_02[] = { {res_rooms, 2}, {res_roomgfx, 2}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_03[] = { {res_rooms, 3}, {res_roomgfx, 3}, {res_scripts, 21}, {res_sounds, 26}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_04[] = { {res_rooms, 4}, {res_roomgfx, 4}, {res_scripts, 46}, {res_scripts, 56}, {res_scripts, 137}, {res_scripts, 146}, {res_sounds, 12}, {res_sounds, 11}, {res_sounds, 13}, {res_sounds, 42}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_05[] = { {res_rooms, 5}, {res_roomgfx, 5}, {res_scripts, 30}, {res_scripts, 31}, {res_scripts, 32}, {res_scripts, 33}, {res_scripts, 34}, {res_scripts, 35}, {res_sounds, 22}, {res_sounds, 23}, {res_sounds, 24}, {res_sounds, 21}, {res_sounds, 46}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_06[] = { {res_rooms, 6}, {res_roomgfx, 6}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_07[] = { {res_rooms, 7}, {res_roomgfx, 7}, {res_scripts, 17}, {res_scripts, 58}, {res_scripts, 59}, {res_scripts, 60}, {res_scripts, 74}, {res_scripts, 81}, {res_scripts, 82}, {res_scripts, 150}, {res_sounds, 14}, {res_sounds, 15}, {res_sounds, 16}, {res_sounds, 17}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_08[] = { {res_rooms, 8}, {res_roomgfx, 8}, {res_scripts, 7}, {res_scripts, 12}, {res_scripts, 13}, {res_scripts, 47}, {res_scripts, 48}, {res_scripts, 49}, {res_scripts, 154}, {res_sounds, 32}, {res_sounds, 33}, {res_sounds, 36}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_09[] = { {res_rooms, 9}, {res_roomgfx, 9}, {res_scripts, 10}, {res_scripts, 11}, {res_scripts, 45}, {res_scripts, 55}, {res_scripts, 84}, {res_scripts, 85}, {res_scripts, 86}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_10[] = { {res_rooms, 10}, {res_roomgfx, 10}, {res_scripts, 24}, {res_scripts, 149}, {res_sounds, 28}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_11[] = { {res_rooms, 11}, {res_roomgfx, 11}, {res_scripts, 166}, {res_scripts, 167}, {res_scripts, 168}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_12[] = { {res_rooms, 12}, {res_roomgfx, 12}, {res_scripts, 51}, {res_scripts, 103}, {res_scripts, 104}, {res_scripts, 161}, {res_sounds, 63}, {res_costumes, 14}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_13[] = { {res_rooms, 13}, {res_roomgfx, 13}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_14[] = { {res_rooms, 14}, {res_roomgfx, 14}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_15[] = { {res_rooms, 15}, {res_roomgfx, 15}, {res_sounds, 27}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_16[] = { {res_rooms, 16}, {res_roomgfx, 16}, {res_scripts, 14}, {res_scripts, 121}, {res_scripts, 122}, {res_sounds, 40}, {res_sounds, 64}, {res_sounds, 68}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_17[] = { {res_rooms, 17}, {res_roomgfx, 17}, {res_scripts, 20}, {res_scripts, 100}, {res_sounds, 25}, {res_sounds, 44}, {res_sounds, 2}, {res_sounds, 50}, {res_sounds, 52}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_18[] = { {res_rooms, 18}, {res_roomgfx, 18}, {res_scripts, 25}, {res_scripts, 26}, {res_scripts, 27}, {res_scripts, 28}, {res_scripts, 64}, {res_scripts, 65}, {res_scripts, 66}, {res_scripts, 67}, {res_scripts, 68}, {res_scripts, 69}, {res_scripts, 70}, {res_scripts, 71}, {res_scripts, 73}, {res_scripts, 101}, {res_sounds, 35}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_19[] = { {res_rooms, 19}, {res_roomgfx, 19}, {res_scripts, 36}, {res_scripts, 37}, {res_scripts, 38}, {res_scripts, 39}, {res_scripts, 40}, {res_scripts, 152}, {res_scripts, 153}, {res_costumes, 10}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_20[] = { {res_rooms, 20}, {res_roomgfx, 20}, {res_scripts, 107}, {res_scripts, 108}, {res_scripts, 109}, {res_scripts, 110}, {res_scripts, 159}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_21[] = { {res_rooms, 21}, {res_roomgfx, 21}, {res_scripts, 41}, {res_scripts, 42}, {res_scripts, 43}, {res_scripts, 53}, {res_scripts, 136}, {res_sounds, 29}, {res_sounds, 20}, {res_sounds, 37}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_22[] = { {res_rooms, 22}, {res_roomgfx, 22}, {res_scripts, 15}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_23[] = { {res_rooms, 23}, {res_roomgfx, 23}, {res_scripts, 77}, {res_scripts, 79}, {res_scripts, 80}, {res_scripts, 83}, {res_sounds, 41}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_24[] = { {res_rooms, 24}, {res_roomgfx, 24}, {res_scripts, 18}, {res_scripts, 19}, {res_scripts, 78}, {res_sounds, 7}, {res_sounds, 3}, {res_sounds, 18}, {res_sounds, 34}, {res_costumes, 12}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_25[] = { {res_rooms, 25}, {res_roomgfx, 25}, {res_scripts, 29}, {res_sounds, 30}, {res_sounds, 31}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_26[] = { {res_rooms, 26}, {res_roomgfx, 26}, {res_scripts, 87}, {res_scripts, 88}, {res_scripts, 89}, {res_scripts, 90}, {res_scripts, 91}, {res_scripts, 92}, {res_scripts, 93}, {res_scripts, 94}, {res_scripts, 95}, {res_scripts, 96}, {res_scripts, 97}, {res_scripts, 98}, {res_scripts, 116}, {res_scripts, 151}, {res_scripts, 174}, {res_costumes, 11}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_27[] = { {res_rooms, 27}, {res_roomgfx, 27}, {res_scripts, 16}, {res_scripts, 52}, {res_scripts, 54}, {res_scripts, 113}, {res_sounds, 45}, {res_costumes, 19}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_28[] = { {res_rooms, 28}, {res_roomgfx, 28}, {res_scripts, 22}, {res_scripts, 23}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_29[] = { {res_rooms, 29}, {res_roomgfx, 29}, {res_scripts, 75}, {res_sounds, 43}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_30[] = { {res_rooms, 30}, {res_roomgfx, 30}, {res_scripts, 63}, {res_sounds, 0}, {res_scripts, 123}, {res_scripts, 125}, {res_scripts, 126}, {res_scripts, 127}, {res_scripts, 129}, {res_sounds, 55}, {res_sounds, 59}, {res_sounds, 60}, {res_costumes, 8}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_31[] = { {res_rooms, 31}, {res_roomgfx, 31}, {res_scripts, 99}, {res_scripts, 115}, {res_scripts, 117}, {res_scripts, 119}, {res_scripts, 147}, {res_scripts, 157}, {res_scripts, 158}, {res_scripts, 160}, {res_costumes, 13}, {res_costumes, 9}, {res_costumes, 23}, {res_costumes, 24}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_32[] = { {res_rooms, 32}, {res_roomgfx, 32}, {res_costumes, 15}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_33[] = { {res_rooms, 33}, {res_roomgfx, 33}, {res_scripts, 120}, {res_scripts, 135}, {res_sounds, 56}, {res_sounds, 57}, {res_sounds, 58}, {res_sounds, 1}, {res_costumes, 22}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_34[] = { {res_rooms, 34}, {res_roomgfx, 34}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_35[] = { {res_rooms, 35}, {res_roomgfx, 35}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_36[] = { {res_rooms, 36}, {res_roomgfx, 36}, {res_sounds, 10}, {res_sounds, 4}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_37[] = { {res_rooms, 37}, {res_roomgfx, 37}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_38[] = { {res_rooms, 38}, {res_roomgfx, 38}, {res_scripts, 138}, {res_scripts, 139}, {res_scripts, 140}, {res_scripts, 141}, {res_scripts, 142}, {res_scripts, 143}, {res_scripts, 144}, {res_scripts, 145}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_39[] = { {res_rooms, 39}, {res_roomgfx, 39}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_40[] = { {res_rooms, 40}, {res_roomgfx, 0}, {res_scripts, 112}, {res_costumes, 17}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_41[] = { {res_rooms, 41}, {res_scripts, 106}, {res_sounds, 47}, {res_sounds, 48}, {res_sounds, 53}, {res_sounds, 49}, {res_sounds, 51}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_42[] = { {res_rooms, 42}, {res_scripts, 124}, {res_costumes, 18}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_43[] = { {res_rooms, 43}, {res_scripts, 44}, {res_sounds, 19}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_44[] = { {res_rooms, 44}, {res_scripts, 102}, {res_sounds, 6}, {res_sounds, 38}, {res_sounds, 8}, {res_sounds, 9}, {res_costumes, 1}, {res_costumes, 2}, {res_costumes, 5}, {res_costumes, 6}, {res_costumes, 3}, {res_costumes, 4}, {res_costumes, 7}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_45[] = { {res_rooms, 45}, {res_scripts, 1}, {res_scripts, 2}, {res_scripts, 3}, {res_scripts, 4}, {res_scripts, 5}, {res_scripts, 9}, {res_scripts, 114}, {res_scripts, 131}, {res_scripts, 164}, {res_scripts, 165}, {res_scripts, 169}, {res_scripts, 170}, {res_scripts, 171}, {res_scripts, 172}, {res_scripts, 173}, {res_scripts, 175}, {res_sounds, 54}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_46[] = { {res_rooms, 46}, {res_scripts, 130}, {res_sounds, 65}, {res_costumes, 0}, {res_costumes, 21}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_47[] = { {res_rooms, 47}, {res_scripts, 62}, {res_sounds, 69}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_48[] = { {res_rooms, 48}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_49[] = { {res_rooms, 49}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_50[] = { {res_rooms, 50}, {res_scripts, 133}, {res_scripts, 163}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_51[] = { {res_rooms, 51}, {res_scripts, 118}, {res_scripts, 128}, {res_sounds, 61}, {res_sounds, 62}, {res_sounds, 67}, {res_sounds, 66}, {res_costumes, 16}, {res_costumes, 20}, {NULL, 0} };
-static ScummNESFile::LFLEntry lfl_52[] = { {res_rooms, 52}, {NULL, 0} };
-// remaining 'standard' resources (not used by any of the original LFL files)
-static ScummNESFile::LFLEntry lfl_53[] = { {res_rooms, 53}, {res_scripts, 177}, {res_scripts, 178}, {res_sounds, 70}, {res_sounds, 71}, {res_sounds, 72}, {res_sounds, 73}, {res_sounds, 74}, {res_sounds, 75}, {res_sounds, 76}, {res_sounds, 77}, {res_sounds, 78}, {res_sounds, 79}, {res_sounds, 80}, {res_sounds, 81}, {NULL, 0} };
-// all 'non-standard' resources (the costume-related stuff)
-static ScummNESFile::LFLEntry lfl_54[] = { {res_rooms, 54}, {res_sprdesc, 0}, {res_sprdesc, 1}, {res_sprlens, 0}, {res_sprlens, 1}, {res_sproffs, 0}, {res_sproffs, 1}, {res_sprdata, 0}, {res_sprdata, 1}, {res_costumegfx, 0}, {res_costumegfx, 1}, {res_sprpals, 0}, {res_sprpals, 1}, {res_charset, 0}, {res_preplist, 0}, {NULL, 0} };
-
-struct ScummNESFile::LFL {
- int num;
- ScummNESFile::LFLEntry *entries;
-};
-
-static ScummNESFile::LFL lfls[] = {
- { 1, lfl_01 },
- { 2, lfl_02 },
- { 3, lfl_03 },
- { 4, lfl_04 },
- { 5, lfl_05 },
- { 6, lfl_06 },
- { 7, lfl_07 },
- { 8, lfl_08 },
- { 9, lfl_09 },
- { 10, lfl_10 },
- { 11, lfl_11 },
- { 12, lfl_12 },
- { 13, lfl_13 },
- { 14, lfl_14 },
- { 15, lfl_15 },
- { 16, lfl_16 },
- { 17, lfl_17 },
- { 18, lfl_18 },
- { 19, lfl_19 },
- { 20, lfl_20 },
- { 21, lfl_21 },
- { 22, lfl_22 },
- { 23, lfl_23 },
- { 24, lfl_24 },
- { 25, lfl_25 },
- { 26, lfl_26 },
- { 27, lfl_27 },
- { 28, lfl_28 },
- { 29, lfl_29 },
- { 30, lfl_30 },
- { 31, lfl_31 },
- { 32, lfl_32 },
- { 33, lfl_33 },
- { 34, lfl_34 },
- { 35, lfl_35 },
- { 36, lfl_36 },
- { 37, lfl_37 },
- { 38, lfl_38 },
- { 39, lfl_39 },
- { 40, lfl_40 },
- { 41, lfl_41 },
- { 42, lfl_42 },
- { 43, lfl_43 },
- { 44, lfl_44 },
- { 45, lfl_45 },
- { 46, lfl_46 },
- { 47, lfl_47 },
- { 48, lfl_48 },
- { 49, lfl_49 },
- { 50, lfl_50 },
- { 51, lfl_51 },
- { 52, lfl_52 },
- { 53, lfl_53 },
- { 54, lfl_54 },
- { -1, NULL }
-};
-
-#pragma START_PACK_STRUCTS
-struct _lfl_index {
- byte room_lfl[55];
- uint16 room_addr[55];
- byte costume_lfl[80];
- uint16 costume_addr[80];
- byte script_lfl[200];
- uint16 script_addr[200];
- byte sound_lfl[100];
- uint16 sound_addr[100];
-} GCC_PACK lfl_index;
-#pragma END_PACK_STRUCTS
-
-
-bool ScummNESFile::generateResource(int res) {
- LFL *lfl = &lfls[res - 1];
- int j;
- int bufsize = 2;
-
- for (j = 0; lfl->entries[j].type != NULL; j++)
- bufsize += extractResource(0, &lfl->entries[j].type[_ROMset][lfl->entries[j].index]);
-
- free(_buf);
- _buf = (byte *)calloc(1, bufsize);
-
- Common::MemoryWriteStream out(_buf, bufsize);
-
- for (j = 0; lfl->entries[j].type != NULL; j++) {
- Resource *entry = &lfl->entries[j].type[_ROMset][lfl->entries[j].index];
- extractResource(&out, entry);
- }
- write_byte(&out, 0xD1);
- write_byte(&out, 0xF5);
-
- if (_stream)
- delete _stream;
-
- _stream = new Common::MemoryReadStream(_buf, bufsize);
-
- return true;
-}
-
-bool ScummNESFile::generateIndex() {
- int i, j;
-
- for (i = 0; lfls[i].num != -1; i++) {
- LFL *lfl = &lfls[i];
- uint16 respos = 0;
-
- for (j = 0; lfl->entries[j].type != NULL; j++) {
- LFLEntry *entry = &lfl->entries[j];
-
- switch (entry->type[_ROMset][entry->index].type) {
- case NES_ROOM:
- lfl_index.room_lfl[entry->index] = lfl->num;
- lfl_index.room_addr[entry->index] = TO_LE_16(respos);
- break;
- case NES_COSTUME:
- lfl_index.costume_lfl[entry->index] = lfl->num;
- lfl_index.costume_addr[entry->index] = TO_LE_16(respos);
- break;
- case NES_SPRDESC:
- lfl_index.costume_lfl[entry->index + 25] = lfl->num;
- lfl_index.costume_addr[entry->index + 25] = TO_LE_16(respos);
- break;
- case NES_SPRLENS:
- lfl_index.costume_lfl[entry->index + 27] = lfl->num;
- lfl_index.costume_addr[entry->index + 27] = TO_LE_16(respos);
- break;
- case NES_SPROFFS:
- lfl_index.costume_lfl[entry->index + 29] = lfl->num;
- lfl_index.costume_addr[entry->index + 29] = TO_LE_16(respos);
- break;
- case NES_SPRDATA:
- lfl_index.costume_lfl[entry->index + 31] = lfl->num;
- lfl_index.costume_addr[entry->index + 31] = TO_LE_16(respos);
- break;
- case NES_COSTUMEGFX:
- lfl_index.costume_lfl[entry->index + 33] = lfl->num;
- lfl_index.costume_addr[entry->index + 33] = TO_LE_16(respos);
- break;
- case NES_SPRPALS:
- lfl_index.costume_lfl[entry->index + 35] = lfl->num;
- lfl_index.costume_addr[entry->index + 35] = TO_LE_16(respos);
- break;
- case NES_ROOMGFX:
- lfl_index.costume_lfl[entry->index + 37] = lfl->num;
- lfl_index.costume_addr[entry->index + 37] = TO_LE_16(respos);
- break;
- case NES_SCRIPT:
- lfl_index.script_lfl[entry->index] = lfl->num;
- lfl_index.script_addr[entry->index] = TO_LE_16(respos);
- break;
- case NES_SOUND:
- lfl_index.sound_lfl[entry->index] = lfl->num;
- lfl_index.sound_addr[entry->index] = TO_LE_16(respos);
- break;
- case NES_CHARSET:
- lfl_index.costume_lfl[77] = lfl->num;
- lfl_index.costume_addr[77] = TO_LE_16(respos);
- break;
- case NES_PREPLIST:
- lfl_index.costume_lfl[78] = lfl->num;
- lfl_index.costume_addr[78] = TO_LE_16(respos);
- break;
- default:
- error("Unindexed entry found!");
- break;
- }
- respos += extractResource(0, &entry->type[_ROMset][entry->index]);
- }
- }
-
- int bufsize = 2;
-
- bufsize += 775;
- bufsize += sizeof(lfl_index);
-
- free(_buf);
- _buf = (byte *)calloc(1, bufsize);
-
- Common::MemoryWriteStream out(_buf, bufsize);
-
- write_byte(&out, 0x43);
- write_byte(&out, 0x46);
-
- extractResource(&out, &res_globdata[_ROMset][0]);
-
- for (i = 0; i < (int)sizeof(lfl_index); i++)
- write_byte(&out, ((byte *)&lfl_index)[i]);
-
- if (_stream)
- delete _stream;
-
- _stream = new Common::MemoryReadStream(_buf, bufsize);
-
- return true;
-}
-
-bool ScummNESFile::open(const char *filename, AccessMode mode) {
- uint8 md5sum[16];
-
- if (_ROMset == kROMsetNum) {
- if (Common::md5_file(filename, md5sum)) {
- char md5str[32+1];
- for (int j = 0; j < 16; j++) {
- sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
- }
-
- if (!strcmp(md5str, "3905799e081b80a61d4460b7b733c206")) {
- _ROMset = kROMsetUSA;
- debug(1, "ROM contents verified as Maniac Mansion (USA)");
- } else if (!strcmp(md5str, "d8d07efcb88f396bee0b402b10c3b1c9")) {
- _ROMset = kROMsetEurope;
- debug(1, "ROM contents verified as Maniac Mansion (Europe)");
- } else if (!strcmp(md5str, "22d07d6c386c9c25aca5dac2a0c0d94b")) {
- _ROMset = kROMsetSweden;
- debug(1, "ROM contents verified as Maniac Mansion (Sweden)");
- } else if (!strcmp(md5str, "81bbfa181184cb494e7a81dcfa94fbd9")) {
- _ROMset = kROMsetFrance;
- debug(2, "ROM contents verified as Maniac Mansion (France)");
- } else if (!strcmp(md5str, "257f8c14d8c584f7ddd601bcb00920c7")) {
- _ROMset = kROMsetGermany;
- debug(2, "ROM contents verified as Maniac Mansion (Germany)");
- } else {
- error("Unsupported Maniac Mansion ROM, md5: %s", md5str);
- return false;
- }
- } else {
- return false;
- }
- }
-
- if (File::open(filename, mode)) {
- if (_stream)
- delete _stream;
- _stream = 0;
-
- free(_buf);
- _buf = 0;
-
- return true;
- } else {
- return false;
- }
-}
-
-void ScummNESFile::close() {
- if (_stream)
- delete _stream;
- _stream = 0;
-
- free(_buf);
- _buf = 0;
-
- File::close();
-}
-
-bool ScummNESFile::openSubFile(const char *filename) {
- assert(isOpen());
-
- const char *ext = strrchr(filename, '.');
- char resNum[3];
- int res;
-
- // We always have file name in form of XX.lfl
- resNum[0] = ext[-2];
- resNum[1] = ext[-1];
- resNum[2] = 0;
-
- res = atoi(resNum);
-
- if (res == 0) {
- return generateIndex();
- } else {
- return generateResource(res);
- }
-}
-
-#pragma mark -
-#pragma mark --- ScummC64File ---
-#pragma mark -
-
-static const int maniacResourcesPerFile[55] = {
- 0, 11, 1, 3, 9, 12, 1, 13, 10, 6,
- 4, 1, 7, 1, 1, 2, 7, 8, 19, 9,
- 6, 9, 2, 6, 8, 4, 16, 8, 3, 3,
- 12, 12, 2, 8, 1, 1, 2, 1, 9, 1,
- 3, 7, 3, 3, 13, 5, 4, 3, 1, 1,
- 3, 10, 1, 0, 0
-};
-
-static const int zakResourcesPerFile[59] = {
- 0, 29, 12, 14, 13, 4, 4, 10, 7, 4,
- 14, 19, 5, 4, 7, 6, 11, 9, 4, 4,
- 1, 3, 3, 5, 1, 9, 4, 10, 13, 6,
- 7, 10, 2, 6, 1, 11, 2, 5, 7, 1,
- 7, 1, 4, 2, 8, 6, 6, 6, 4, 13,
- 3, 1, 2, 1, 2, 1, 10, 1, 1
-};
-
-
-ScummC64File::ScummC64File(char *disk1, char *disk2, bool maniac) : _stream(0), _buf(0), _maniac(maniac) {
- _disk1 = disk1;
- _disk2 = disk2;
-
- _openedDisk = 0;
-
- if (maniac) {
- _numGlobalObjects = 256;
- _numRooms = 55;
- _numCostumes = 25;
- _numScripts = 160;
- _numSounds = 70;
- _resourcesPerFile = maniacResourcesPerFile;
- } else {
- _numGlobalObjects = 775;
- _numRooms = 59;
- _numCostumes = 38;
- _numScripts = 155;
- _numSounds = 127;
- _resourcesPerFile = zakResourcesPerFile;
- }
-}
-
-uint32 ScummC64File::write(const void *, uint32) {
- error("ScummC64File does not support writing!");
- return 0;
-}
-
-void ScummC64File::setEnc(byte enc) {
- _stream->setEnc(enc);
-}
-
-byte ScummC64File::fileReadByte() {
- byte b = 0;
- File::read(&b, 1);
- return b;
-}
-
-uint16 ScummC64File::fileReadUint16LE() {
- uint16 a = fileReadByte();
- uint16 b = fileReadByte();
- return a | (b << 8);
-}
-
-bool ScummC64File::openDisk(char num) {
- if (num == '1')
- num = 1;
- if (num == '2')
- num = 2;
-
- if (_openedDisk != num || !File::isOpen()) {
- if (File::isOpen())
- File::close();
-
- if (num == 1)
- File::open(_disk1.c_str());
- else if (num == 2)
- File::open(_disk2.c_str());
- else {
- error("ScummC64File::open(): wrong disk (%c)", num);
- return false;
- }
-
- _openedDisk = num;
-
- if (!File::isOpen()) {
- error("ScummC64File::open(): cannot open disk (%d)", num);
- return false;
- }
- }
- return true;
-}
-
-bool ScummC64File::open(const char *filename, AccessMode mode) {
- uint16 signature;
-
- // check signature
- openDisk(1);
- File::seek(0);
-
- signature = fileReadUint16LE();
- if (signature != 0x0A31) {
- error("ScummC64File::open(): signature not found in disk 1!");
- return false;
- }
-
- extractIndex(0); // Fill in resource arrays
-
- openDisk(2);
- File::seek(0);
-
- signature = fileReadUint16LE();
- if (signature != 0x0132)
- error("Error: signature not found in disk 2!\n");
-
- return true;
-}
-
-
-uint16 ScummC64File::extractIndex(Common::WriteStream *out) {
- int i;
- uint16 reslen = 0;
-
- openDisk(1);
- File::seek(0);
-
- // skip signature
- fileReadUint16LE();
-
- // write expected signature
- reslen += write_word(out, 0x0132);
-
- // copy object flags
- for (i = 0; i < _numGlobalObjects; i++)
- reslen += write_byte(out, fileReadByte());
-
- // copy room offsets
- for (i = 0; i < _numRooms; i++) {
- _roomDisks[i] = fileReadByte();
- reslen += write_byte(out, _roomDisks[i]);
- }
- for (i = 0; i < _numRooms; i++) {
- _roomSectors[i] = fileReadByte();
- reslen += write_byte(out, _roomSectors[i]);
- _roomTracks[i] = fileReadByte();
- reslen += write_byte(out, _roomTracks[i]);
- }
- for (i = 0; i < _numCostumes; i++)
- reslen += write_byte(out, fileReadByte());
- for (i = 0; i < _numCostumes; i++)
- reslen += write_word(out, fileReadUint16LE());
-
- for (i = 0; i < _numScripts; i++)
- reslen += write_byte(out, fileReadByte());
- for (i = 0; i < _numScripts; i++)
- reslen += write_word(out, fileReadUint16LE());
-
- for (i = 0; i < _numSounds; i++)
- reslen += write_byte(out, fileReadByte());
- for (i = 0; i < _numSounds; i++)
- reslen += write_word(out, fileReadUint16LE());
-
- return reslen;
-}
-
-bool ScummC64File::generateIndex() {
- int bufsize;
-
- bufsize = extractIndex(0);
-
- free(_buf);
- _buf = (byte *)calloc(1, bufsize);
-
- Common::MemoryWriteStream out(_buf, bufsize);
-
- extractIndex(&out);
-
- if (_stream)
- delete _stream;
-
- _stream = new Common::MemoryReadStream(_buf, bufsize);
-
- return true;
-}
-
-uint16 ScummC64File::extractResource(Common::WriteStream *out, int res) {
- const int SectorOffset[36] = {
- 0,
- 0, 21, 42, 63, 84, 105, 126, 147, 168, 189, 210, 231, 252, 273, 294, 315, 336,
- 357, 376, 395, 414, 433, 452, 471,
- 490, 508, 526, 544, 562, 580,
- 598, 615, 632, 649, 666
- };
- int i;
- uint16 reslen = 0;
-
- openDisk(_roomDisks[res]);
-
- File::seek((SectorOffset[_roomTracks[res]] + _roomSectors[res]) * 256);
-
- for (i = 0; i < _resourcesPerFile[res]; i++) {
- uint16 len = fileReadUint16LE();
- reslen += write_word(out, len);
-
- for (len -= 2; len > 0; len--)
- reslen += write_byte(out, fileReadByte());
- }
-
- return reslen;
-}
-
-bool ScummC64File::generateResource(int res) {
- int bufsize;
-
- if (res >= _numRooms)
- return false;
-
- bufsize = extractResource(0, res);
-
- free(_buf);
- _buf = (byte *)calloc(1, bufsize);
-
- Common::MemoryWriteStream out(_buf, bufsize);
-
- extractResource(&out, res);
-
- if (_stream)
- delete _stream;
-
- _stream = new Common::MemoryReadStream(_buf, bufsize);
-
- return true;
-}
-
-void ScummC64File::close() {
- if (_stream)
- delete _stream;
- _stream = 0;
-
- free(_buf);
- _buf = 0;
-
- File::close();
-}
-
-bool ScummC64File::openSubFile(const char *filename) {
- assert(isOpen());
-
- const char *ext = strrchr(filename, '.');
- char resNum[3];
- int res;
-
- // We always have file name in form of XX.lfl
- resNum[0] = ext[-2];
- resNum[1] = ext[-1];
- resNum[2] = 0;
-
- res = atoi(resNum);
-
- if (res == 0) {
- return generateIndex();
- } else {
- return generateResource(res);
- }
-
- return true;
-}
-
-} // End of namespace Scumm
diff --git a/scumm/util.h b/scumm/util.h
deleted file mode 100644
index 99d75cf127..0000000000
--- a/scumm/util.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCUMM_UTIL_H
-#define SCUMM_UTIL_H
-
-#include "common/file.h"
-#include "common/stream.h"
-
-namespace Scumm {
-
-#define revBitMask(x) (0x80 >> (x))
-
-class BaseScummFile : public Common::File {
-public:
- virtual void setEnc(byte value) = 0;
-
- virtual bool open(const char *filename, AccessMode mode = kFileReadMode) = 0;
- virtual bool openSubFile(const char *filename) = 0;
-
- virtual bool eof() = 0;
- virtual uint32 pos() = 0;
- virtual uint32 size() = 0;
- virtual void seek(int32 offs, int whence = SEEK_SET) = 0;
- virtual uint32 read(void *dataPtr, uint32 dataSize) = 0;
- virtual uint32 write(const void *dataPtr, uint32 dataSize) = 0;
-};
-
-class ScummFile : public BaseScummFile {
-private:
- byte _encbyte;
- uint32 _subFileStart;
- uint32 _subFileLen;
-public:
- ScummFile();
- void setEnc(byte value);
-
- void setSubfileRange(uint32 start, uint32 len);
- void resetSubfile();
-
- bool open(const char *filename, AccessMode mode = kFileReadMode);
- bool openSubFile(const char *filename);
-
- bool eof();
- uint32 pos();
- uint32 size();
- void seek(int32 offs, int whence = SEEK_SET);
- uint32 read(void *dataPtr, uint32 dataSize);
- uint32 write(const void *dataPtr, uint32 dataSize);
-};
-
-class ScummNESFile : public BaseScummFile {
-public:
- enum ROMset {
- kROMsetUSA,
- kROMsetEurope,
- kROMsetSweden,
- kROMsetFrance,
- kROMsetGermany,
- kROMsetNum
- };
-
- struct Resource;
- struct LFLEntry;
- struct LFL;
-
-private:
- Common::MemoryReadStream *_stream;
- ROMset _ROMset;
- byte *_buf;
-
- bool generateIndex();
- bool generateResource(int res);
- uint16 extractResource(Common::WriteStream *out, Resource *res);
-
- byte fileReadByte();
- uint16 fileReadUint16LE();
-
-public:
- ScummNESFile();
- void setEnc(byte value);
-
- bool open(const char *filename, AccessMode mode = kFileReadMode);
- bool openSubFile(const char *filename);
-
- void close();
- bool eof() { return _stream->eos(); }
- uint32 pos() { return _stream->pos(); }
- uint32 size() { return _stream->size(); }
- void seek(int32 offs, int whence = SEEK_SET) { _stream->seek(offs, whence); }
- uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
- uint32 write(const void *dataPtr, uint32 dataSize);
-};
-
-
-class ScummC64File : public BaseScummFile {
-private:
- Common::MemoryReadStream *_stream;
- byte _roomDisks[59], _roomTracks[59], _roomSectors[59];
-
- byte *_buf;
-
- bool _maniac;
- Common::String _disk1, _disk2;
- int _openedDisk;
-
- int _numGlobalObjects;
- int _numRooms;
- int _numCostumes;
- int _numScripts;
- int _numSounds;
- const int *_resourcesPerFile;
-
- bool openDisk(char num);
-
- bool generateIndex();
- bool generateResource(int res);
-
- uint16 extractIndex(Common::WriteStream *out);
- uint16 extractResource(Common::WriteStream *out, int res);
-
- byte fileReadByte();
- uint16 fileReadUint16LE();
-
-public:
- ScummC64File(char *disk1, char *disk2, bool maniac);
- void setEnc(byte value);
-
- bool open(const char *filename, AccessMode mode = kFileReadMode);
- bool openSubFile(const char *filename);
-
- void close();
- bool eof() { return _stream->eos(); }
- uint32 pos() { return _stream->pos(); }
- uint32 size() { return _stream->size(); }
- void seek(int32 offs, int whence = SEEK_SET) { _stream->seek(offs, whence); }
- uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
- uint32 write(const void *dataPtr, uint32 dataSize);
-};
-
-
-/* Direction conversion functions (between old dir and new dir format) */
-int newDirToOldDir(int dir);
-int oldDirToNewDir(int dir);
-
-int normalizeAngle(int angle);
-int fromSimpleDir(int dirtype, int dir);
-int toSimpleDir(int dirtype, int dir);
-
-void checkRange(int max, int min, int no, const char *str);
-
-const char *tag2str(uint32 tag);
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/vars.cpp b/scumm/vars.cpp
deleted file mode 100644
index 1cdc446637..0000000000
--- a/scumm/vars.cpp
+++ /dev/null
@@ -1,736 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/config-manager.h"
-#include "scumm/scumm.h"
-#include "scumm/intern.h"
-#ifndef DISABLE_HE
-#include "scumm/intern_he.h"
-#endif
-#include "scumm/logic_he.h"
-#include "sound/mididrv.h"
-
-namespace Scumm {
-
-void ScummEngine::setupScummVars() {
- VAR_KEYPRESS = 0;
- VAR_EGO = 1;
- VAR_CAMERA_POS_X = 2;
- VAR_HAVE_MSG = 3;
- VAR_ROOM = 4;
- VAR_OVERRIDE = 5;
- VAR_MACHINE_SPEED = 6;
- VAR_ME = 7;
- VAR_NUM_ACTOR = 8;
- VAR_CURRENTDRIVE = 10;
- VAR_TMR_1 = 11;
- VAR_TMR_2 = 12;
- VAR_TMR_3 = 13;
- VAR_MUSIC_TIMER = 14;
- VAR_ACTOR_RANGE_MIN = 15;
- VAR_ACTOR_RANGE_MAX = 16;
- VAR_CAMERA_MIN_X = 17;
- VAR_CAMERA_MAX_X = 18;
- VAR_TIMER_NEXT = 19;
- VAR_VIRT_MOUSE_X = 20;
- VAR_VIRT_MOUSE_Y = 21;
- VAR_ROOM_RESOURCE = 22;
- VAR_LAST_SOUND = 23;
- VAR_CUTSCENEEXIT_KEY = 24;
- VAR_TALK_ACTOR = 25;
- VAR_CAMERA_FAST_X = 26;
- VAR_ENTRY_SCRIPT = 28;
- VAR_ENTRY_SCRIPT2 = 29;
- VAR_EXIT_SCRIPT = 30;
- VAR_EXIT_SCRIPT2 = 31;
- VAR_VERB_SCRIPT = 32;
- VAR_SENTENCE_SCRIPT = 33;
- VAR_INVENTORY_SCRIPT = 34;
- VAR_CUTSCENE_START_SCRIPT = 35;
- VAR_CUTSCENE_END_SCRIPT = 36;
- VAR_CHARINC = 37;
- VAR_WALKTO_OBJ = 38;
- VAR_HEAPSPACE = 40;
- VAR_RESTART_KEY = 42;
- VAR_PAUSE_KEY = 43;
- VAR_MOUSE_X = 44;
- VAR_MOUSE_Y = 45;
- VAR_TIMER = 46;
- VAR_TMR_4 = 47;
- VAR_SOUNDCARD = 48;
- VAR_VIDEOMODE = 49;
-
- if (_version >= 4) {
- VAR_SCROLL_SCRIPT = 27;
- VAR_DEBUGMODE = 39;
- VAR_MAINMENU_KEY = 50;
- VAR_FIXEDDISK = 51;
- VAR_CURSORSTATE = 52;
- VAR_USERPUT = 53;
- }
-
- if (_version >= 5) {
- VAR_SOUNDPARAM = 64;
- VAR_SOUNDPARAM2 = 65;
- VAR_SOUNDPARAM3 = 66;
- }
- if (_version >= 5) {
- VAR_SOUNDRESULT = 56;
- VAR_TALKSTOP_KEY = 57;
- VAR_FADE_DELAY = 59;
- VAR_MOUSEPRESENT = 67;
- VAR_MEMORY_PERFORMANCE = 68;
- VAR_VIDEO_PERFORMANCE = 69;
- VAR_ROOM_FLAG = 70;
- VAR_GAME_LOADED = 71;
- VAR_NEW_ROOM = 72;
- }
-}
-
-void ScummEngine_c64::setupScummVars() {
- // TODO
- VAR_EGO = 0;
- VAR_CAMERA_POS_X = 2;
- VAR_HAVE_MSG = 3;
- VAR_ROOM = 4;
- VAR_OVERRIDE = 6;
- VAR_CHARCOUNT = 10;
-
- // FIXME: Should be removed
- VAR_CURRENT_LIGHTS = 12;
- VAR_CURSORSTATE = 21;
- VAR_CAMERA_MIN_X = 23;
- VAR_CAMERA_MAX_X = 24;
- VAR_TIMER_NEXT = 25;
-}
-
-void ScummEngine_v2::setupScummVars() {
- VAR_EGO = 0;
- VAR_CAMERA_POS_X = 2;
- VAR_HAVE_MSG = 3;
- VAR_ROOM = 4;
- VAR_OVERRIDE = 5;
- VAR_MACHINE_SPEED = 6;
- VAR_CHARCOUNT = 7;
- VAR_ACTIVE_VERB = 8;
- VAR_ACTIVE_OBJECT1 = 9;
- VAR_ACTIVE_OBJECT2 = 10;
- VAR_NUM_ACTOR = 11;
- VAR_CURRENT_LIGHTS = 12;
- VAR_CURRENTDRIVE = 13;
- VAR_MUSIC_TIMER = 17;
- VAR_VERB_ALLOWED = 18;
- VAR_ACTOR_RANGE_MIN = 19;
- VAR_ACTOR_RANGE_MAX = 20;
- VAR_CURSORSTATE = 21;
- VAR_CAMERA_MIN_X = 23;
- VAR_CAMERA_MAX_X = 24;
- VAR_TIMER_NEXT = 25;
- VAR_SENTENCE_VERB = 26;
- VAR_SENTENCE_OBJECT1 = 27;
- VAR_SENTENCE_OBJECT2 = 28;
- VAR_SENTENCE_PREPOSITION = 29;
- VAR_VIRT_MOUSE_X = 30;
- VAR_VIRT_MOUSE_Y = 31;
- VAR_CLICK_AREA = 32;
- VAR_ROOM_RESOURCE = 36;
- VAR_LAST_SOUND = 37;
- VAR_BACKUP_VERB = 38;
- VAR_KEYPRESS = 39;
- VAR_CUTSCENEEXIT_KEY = 40;
- VAR_TALK_ACTOR = 41;
-}
-
-void ScummEngine_v5::setupScummVars() {
- // Many vars are the same as in V5 & V6 games, so just call the inherited method first
- ScummEngine::setupScummVars();
-
- VAR_CURRENT_LIGHTS = 9;
-
- if (_version >= 4) {
- VAR_V5_TALK_STRING_Y = 54;
- }
- if ((_gameId == GID_LOOM && _version == 4) || _version >= 5) {
- VAR_NOSUBTITLES = 60;
- }
-}
-
-void ScummEngine_v6::setupScummVars() {
- // Many vars are the same as in V5 & V6 games, so just call the inherited method first
- ScummEngine::setupScummVars();
-
- VAR_ROOM_WIDTH = 41;
- VAR_ROOM_HEIGHT = 54;
-
- if (_heversion >= 60) {
- VAR_NOSUBTITLES = 60;
- } else {
- VAR_VOICE_MODE = 60; // 0 is voice, 1 is voice+text, 2 is text only
- VAR_SAVELOAD_SCRIPT = 61;
- VAR_SAVELOAD_SCRIPT2 = 62;
- }
-
- VAR_LEFTBTN_HOLD = 74;
- VAR_RIGHTBTN_HOLD = 75;
-
- VAR_V6_EMSSPACE = 76;
- VAR_RANDOM_NR = 118;
-
- VAR_TIMEDATE_YEAR = 119;
- VAR_TIMEDATE_MONTH = 129;
- VAR_TIMEDATE_DAY = 128;
- VAR_TIMEDATE_HOUR = 125;
- VAR_TIMEDATE_MINUTE = 126;
-
- // Sam & Max specific
- if (_gameId == GID_SAMNMAX) {
- VAR_V6_SOUNDMODE = 9;
- VAR_CHARSET_MASK = 123;
- }
-}
-
-#ifndef DISABLE_HE
-void ScummEngine_v70he::setupScummVars() {
- ScummEngine_v6::setupScummVars();
-
- VAR_CURRENTDRIVE = 0xFF;
- VAR_MUSIC_TIMER = 0xFF;
-
- VAR_NUM_SOUND_CHANNELS = 9;
- VAR_TALK_CHANNEL = 10;
- VAR_SOUND_CHANNEL = 14;
-}
-
-void ScummEngine_v72he::setupScummVars() {
- VAR_KEYPRESS = 0;
- VAR_DEBUGMODE = 1;
- VAR_TIMER_NEXT = 2;
- VAR_OVERRIDE = 3;
- VAR_WALKTO_OBJ = 4;
- VAR_RANDOM_NR = 5;
-
- VAR_GAME_LOADED = 8;
- VAR_EGO = 9;
- VAR_NUM_ACTOR = 10;
-
- VAR_VIRT_MOUSE_X = 13;
- VAR_VIRT_MOUSE_Y = 14;
- VAR_MOUSE_X = 15;
- VAR_MOUSE_Y = 16;
- VAR_LEFTBTN_HOLD = 17;
- VAR_RIGHTBTN_HOLD = 18;
-
- VAR_CURSORSTATE = 19;
- VAR_USERPUT = 20;
- VAR_ROOM = 21;
- VAR_ROOM_WIDTH = 22;
- VAR_ROOM_HEIGHT = 23;
- VAR_CAMERA_POS_X = 24;
- VAR_CAMERA_MIN_X = 25;
- VAR_CAMERA_MAX_X = 26;
- VAR_ROOM_RESOURCE = 27;
- VAR_SCROLL_SCRIPT = 28;
- VAR_ENTRY_SCRIPT = 29;
- VAR_ENTRY_SCRIPT2 = 30;
- VAR_EXIT_SCRIPT = 31;
- VAR_EXIT_SCRIPT2 = 32;
- VAR_VERB_SCRIPT = 33;
- VAR_SENTENCE_SCRIPT = 34;
- VAR_INVENTORY_SCRIPT = 35;
- VAR_CUTSCENE_START_SCRIPT = 36;
- VAR_CUTSCENE_END_SCRIPT = 37;
-
- VAR_RESTART_KEY = 42;
- VAR_PAUSE_KEY = 43;
- VAR_CUTSCENEEXIT_KEY = 44;
- VAR_TALKSTOP_KEY = 45;
- VAR_HAVE_MSG = 46;
- VAR_SUBTITLES = 47;
- VAR_CHARINC = 48;
- VAR_TALK_ACTOR = 49;
- VAR_LAST_SOUND = 50;
- VAR_TALK_CHANNEL = 51;
- VAR_SOUND_CHANNEL = 52;
-
- VAR_MEMORY_PERFORMANCE = 57;
- VAR_VIDEO_PERFORMANCE = 58;
- VAR_NEW_ROOM = 59;
- VAR_TMR_1 = 60;
- VAR_TMR_2 = 61;
- VAR_TMR_3 = 62;
- VAR_TIMEDATE_HOUR = 63;
- VAR_TIMEDATE_MINUTE = 64;
- VAR_TIMEDATE_DAY = 65;
- VAR_TIMEDATE_MONTH = 66;
- VAR_TIMEDATE_YEAR = 67;
-
- VAR_NUM_ROOMS = 68;
- VAR_NUM_SCRIPTS = 69;
- VAR_NUM_SOUNDS = 70;
- VAR_NUM_COSTUMES = 71;
- VAR_NUM_IMAGES = 72;
- VAR_NUM_CHARSETS = 73;
- VAR_NUM_GLOBAL_OBJS = 74;
- VAR_MOUSE_STATE = 75;
- VAR_POLYGONS_ONLY = 76;
-
- if (_heversion <= 73) {
- VAR_NUM_SOUND_CHANNELS = 56;
- }
-}
-
-void ScummEngine_v80he::setupScummVars() {
- ScummEngine_v72he::setupScummVars();
-
- VAR_PLATFORM = 78; // 1 is PC, 2 is Macintosh
- VAR_WINDOWS_VERSION = 79; // 31 is Windows 3.1, 40 is Windows 95+
- VAR_CURRENT_CHARSET = 80;
- VAR_SOUNDCODE_TMR = 84;
- VAR_KEY_STATE = 86;
- VAR_NUM_SOUND_CHANNELS = 88;
- VAR_COLOR_DEPTH = 89;
- VAR_REDRAW_ALL_ACTORS = 95;
-}
-
-void ScummEngine_v90he::setupScummVars() {
- ScummEngine_v80he::setupScummVars();
-
- VAR_SCRIPT_CYCLE = 103;
- VAR_NUM_SCRIPT_CYCLES = 104;
-
- if (_heversion >= 95) {
- VAR_NUM_SPRITE_GROUPS = 105;
- VAR_NUM_SPRITES = 106;
- VAR_U32_VERSION = 107;
- VAR_U32_ARRAY_UNK = 116;
- VAR_WIZ_TCOLOR = 117;
- VAR_RESERVED_SOUND_CHANNELS = 120;
- }
- if (_heversion >= 98) {
- VAR_SKIP_RESET_TALK_ACTOR = 125;
- }
- if (_heversion >= 99) {
- VAR_MAIN_SCRIPT = 127;
- VAR_NUM_PALETTES = 130;
- VAR_NUM_UNK = 131;
- }
-}
-#endif
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::setupScummVars() {
- VAR_MOUSE_X = 1;
- VAR_MOUSE_Y = 2;
- VAR_VIRT_MOUSE_X = 3;
- VAR_VIRT_MOUSE_Y = 4;
- VAR_ROOM_WIDTH = 5;
- VAR_ROOM_HEIGHT = 6;
- VAR_CAMERA_POS_X = 7;
- VAR_CAMERA_POS_Y = 8;
- VAR_OVERRIDE = 9;
- VAR_ROOM = 10;
- VAR_ROOM_RESOURCE = 11;
- VAR_TALK_ACTOR = 12;
- VAR_HAVE_MSG = 13;
- VAR_TIMER = 14;
- VAR_TMR_4 = 15;
-
- VAR_TIMEDATE_YEAR = 16;
- VAR_TIMEDATE_MONTH = 17;
- VAR_TIMEDATE_DAY = 18;
- VAR_TIMEDATE_HOUR = 19;
- VAR_TIMEDATE_MINUTE = 20;
- VAR_TIMEDATE_SECOND = 21;
-
- VAR_LEFTBTN_DOWN = 22;
- VAR_RIGHTBTN_DOWN = 23;
- VAR_LEFTBTN_HOLD = 24;
- VAR_RIGHTBTN_HOLD = 25;
-
- VAR_MEMORY_PERFORMANCE = 26;
- VAR_VIDEO_PERFORMANCE = 27;
- VAR_GAME_LOADED = 29;
- VAR_V6_EMSSPACE = 32;
- VAR_VOICE_MODE = 33; // 0 is voice, 1 is voice+text, 2 is text only
- VAR_RANDOM_NR = 34;
- VAR_NEW_ROOM = 35;
- VAR_WALKTO_OBJ = 36;
-
- VAR_NUM_GLOBAL_OBJS = 37;
-
- VAR_CAMERA_DEST_X = 38;
- VAR_CAMERA_DEST_Y = 39;
- VAR_CAMERA_FOLLOWED_ACTOR = 40;
-
- VAR_SCROLL_SCRIPT = 50;
- VAR_ENTRY_SCRIPT = 51;
- VAR_ENTRY_SCRIPT2 = 52;
- VAR_EXIT_SCRIPT = 53;
- VAR_EXIT_SCRIPT2 = 54;
- VAR_VERB_SCRIPT = 55;
- VAR_SENTENCE_SCRIPT = 56;
- VAR_INVENTORY_SCRIPT = 57;
- VAR_CUTSCENE_START_SCRIPT = 58;
- VAR_CUTSCENE_END_SCRIPT = 59;
- VAR_SAVELOAD_SCRIPT = 60;
- VAR_SAVELOAD_SCRIPT2 = 61;
-
- VAR_CUTSCENEEXIT_KEY = 62;
- VAR_RESTART_KEY = 63;
- VAR_PAUSE_KEY = 64;
- VAR_MAINMENU_KEY = 65;
- VAR_VERSION_KEY = 66;
- VAR_TALKSTOP_KEY = 67;
- VAR_KEYPRESS = 118;
-
- VAR_TIMER_NEXT = 97;
- VAR_TMR_1 = 98;
- VAR_TMR_2 = 99;
- VAR_TMR_3 = 100;
-
- VAR_CAMERA_MIN_X = 101;
- VAR_CAMERA_MAX_X = 102;
- VAR_CAMERA_MIN_Y = 103;
- VAR_CAMERA_MAX_Y = 104;
- VAR_CAMERA_THRESHOLD_X = 105;
- VAR_CAMERA_THRESHOLD_Y = 106;
- VAR_CAMERA_SPEED_X = 107;
- VAR_CAMERA_SPEED_Y = 108;
- VAR_CAMERA_ACCEL_X = 109;
- VAR_CAMERA_ACCEL_Y = 110;
-
- VAR_EGO = 111;
-
- VAR_CURSORSTATE = 112;
- VAR_USERPUT = 113;
- VAR_DEFAULT_TALK_DELAY = 114;
- VAR_CHARINC = 115;
- VAR_DEBUGMODE = 116;
- VAR_FADE_DELAY = 117;
-
- // Full Throttle specific
- if (_gameId == GID_FT) {
- VAR_CHARSET_MASK = 119;
- }
-
- VAR_VIDEONAME = 123;
-
- VAR_STRING2DRAW = 130;
- VAR_CUSTOMSCALETABLE = 131;
-
- VAR_BLAST_ABOVE_TEXT = 133;
-
- VAR_MUSIC_BUNDLE_LOADED = 135;
- VAR_VOICE_BUNDLE_LOADED = 136;
-
-}
-
-void ScummEngine_v8::setupScummVars() {
- VAR_ROOM_WIDTH = 1;
- VAR_ROOM_HEIGHT = 2;
-
- VAR_MOUSE_X = 3;
- VAR_MOUSE_Y = 4;
- VAR_VIRT_MOUSE_X = 5;
- VAR_VIRT_MOUSE_Y = 6;
-
- VAR_CURSORSTATE = 7;
- VAR_USERPUT = 8;
-
- VAR_CAMERA_POS_X = 9;
- VAR_CAMERA_POS_Y = 10;
- VAR_CAMERA_DEST_X = 11;
- VAR_CAMERA_DEST_Y = 12;
- VAR_CAMERA_FOLLOWED_ACTOR = 13;
-
- VAR_TALK_ACTOR = 14;
- VAR_HAVE_MSG = 15;
-
- VAR_LEFTBTN_DOWN = 16;
- VAR_RIGHTBTN_DOWN = 17;
- VAR_LEFTBTN_HOLD = 18;
- VAR_RIGHTBTN_HOLD = 19;
-
- VAR_TIMEDATE_YEAR = 24;
- VAR_TIMEDATE_MONTH = 25;
- VAR_TIMEDATE_DAY = 26;
- VAR_TIMEDATE_HOUR = 27;
- VAR_TIMEDATE_MINUTE = 28;
- VAR_TIMEDATE_SECOND = 29;
-
- VAR_OVERRIDE = 30;
- VAR_ROOM = 31;
- VAR_NEW_ROOM = 32;
- VAR_WALKTO_OBJ = 33;
- VAR_TIMER = 34;
-
- VAR_VOICE_MODE = 39; // 0 is voice, 1 is voice+text, 2 is text only
- VAR_GAME_LOADED = 40;
- VAR_LANGUAGE = 41;
-
- VAR_CURRENTDISK = 42;
- VAR_MUSIC_BUNDLE_LOADED = 45;
- VAR_VOICE_BUNDLE_LOADED = 46;
-
- VAR_SCROLL_SCRIPT = 50;
- VAR_ENTRY_SCRIPT = 51;
- VAR_ENTRY_SCRIPT2 = 52;
- VAR_EXIT_SCRIPT = 53;
- VAR_EXIT_SCRIPT2 = 54;
- VAR_VERB_SCRIPT = 55;
- VAR_SENTENCE_SCRIPT = 56;
- VAR_INVENTORY_SCRIPT = 57;
- VAR_CUTSCENE_START_SCRIPT = 58;
- VAR_CUTSCENE_END_SCRIPT = 59;
-
- VAR_CUTSCENEEXIT_KEY = 62;
-
- VAR_PAUSE_KEY = 64;
- VAR_MAINMENU_KEY = 65;
- VAR_VERSION_KEY = 66;
- VAR_TALKSTOP_KEY = 67;
-
- VAR_CUSTOMSCALETABLE = 111;
-
- VAR_TIMER_NEXT = 112;
- VAR_TMR_1 = 113;
- VAR_TMR_2 = 114;
- VAR_TMR_3 = 115;
-
- VAR_CAMERA_MIN_X = 116;
- VAR_CAMERA_MAX_X = 117;
- VAR_CAMERA_MIN_Y = 118;
- VAR_CAMERA_MAX_Y = 119;
- VAR_CAMERA_SPEED_X = 120;
- VAR_CAMERA_SPEED_Y = 121;
- VAR_CAMERA_ACCEL_X = 122;
- VAR_CAMERA_ACCEL_Y = 123;
- VAR_CAMERA_THRESHOLD_X = 124;
- VAR_CAMERA_THRESHOLD_Y = 125;
-
- VAR_EGO = 126;
-
- VAR_DEFAULT_TALK_DELAY = 128;
- VAR_CHARINC = 129;
-
- VAR_DEBUGMODE = 130;
- VAR_KEYPRESS = 132;
- VAR_BLAST_ABOVE_TEXT = 133;
- VAR_SYNC = 134;
-}
-#endif
-
-void ScummEngine_v2::initScummVars() {
-
- if (_platform == Common::kPlatformC64 && _gameId == GID_MANIAC) {
- VAR(VAR_EGO) = 3;
- }
-
- // This needs to be at least greater than 40 to get the more
- // elaborate version of the EGA Zak into. I don't know where
- // else it makes any difference.
- if (_gameId == GID_ZAK)
- VAR(VAR_MACHINE_SPEED) = 0x7FFF;
-}
-
-void ScummEngine_v5::initScummVars() {
- ScummEngine::initScummVars();
-
- if (_version >= 4 && _version <= 5)
- VAR(VAR_V5_TALK_STRING_Y) = -0x50;
-
- if (VAR_CURRENT_LIGHTS != 0xFF) {
- // Setup light
- VAR(VAR_CURRENT_LIGHTS) = LIGHTMODE_actor_base | LIGHTMODE_actor_color | LIGHTMODE_screen;
- }
-
- if (_gameId == GID_MONKEY)
- _scummVars[74] = 1225;
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::initScummVars() {
- ScummEngine::initScummVars();
-
- if (_version == 8) { // FIXME: How do we deal with non-cd installs?
- VAR(VAR_CURRENTDISK) = 1;
- VAR(VAR_LANGUAGE) = _language;
- } else {
- VAR(VAR_V6_EMSSPACE) = 10000;
- VAR(VAR_NUM_GLOBAL_OBJS) = _numGlobalObjects - 1;
- }
-
- VAR(VAR_DEFAULT_TALK_DELAY) = 60;
- VAR(VAR_VOICE_MODE) = ConfMan.getBool("subtitles");
-}
-#endif
-
-#ifndef DISABLE_HE
-void ScummEngine_v70he::initScummVars() {
- ScummEngine::initScummVars();
-
- if (VAR_MACHINE_SPEED != 0xFF)
- VAR(VAR_MACHINE_SPEED) = 13;
-
- VAR(VAR_NUM_SOUND_CHANNELS) = 8;
- VAR(VAR_SOUND_CHANNEL) = 1;
- VAR(VAR_TALK_CHANNEL) = 2;
-}
-
-void ScummEngine_v72he::initScummVars() {
- ScummEngine_v70he::initScummVars();
-
- VAR(VAR_VIDEO_PERFORMANCE) = 26;
-
- VAR(VAR_NUM_ROOMS) = _numRooms - 1;
- VAR(VAR_NUM_SCRIPTS) = _numScripts - 1;
- VAR(VAR_NUM_SOUNDS) = _numSounds - 1;
- VAR(VAR_NUM_COSTUMES) = _numCostumes - 1;
- VAR(VAR_NUM_IMAGES) = _numImages - 1;
- VAR(VAR_NUM_CHARSETS) = _numCharsets - 1;
- VAR(VAR_NUM_GLOBAL_OBJS) = _numGlobalObjects - 1;
-}
-
-void ScummEngine_v80he::initScummVars() {
- ScummEngine_v72he::initScummVars();
-
- VAR(VAR_PLATFORM) = 1;
- VAR(VAR_WINDOWS_VERSION) = 40;
- VAR(VAR_COLOR_DEPTH) = 256;
-}
-
-void ScummEngine_v90he::initScummVars() {
- ScummEngine_v80he::initScummVars();
-
- VAR(VAR_SCRIPT_CYCLE) = 1;
- VAR(VAR_NUM_SCRIPT_CYCLES) = 1;
-
- if (_heversion >= 95) {
- VAR(VAR_NUM_SPRITE_GROUPS) = MAX(64, _numSprites / 4) - 1;
- VAR(VAR_NUM_SPRITES) = _numSprites - 1;
- VAR(VAR_WIZ_TCOLOR) = 5;
- VAR(VAR_RESERVED_SOUND_CHANNELS) = 9;
- }
- if (_heversion >= 98) {
- VAR(VAR_U32_VERSION) = _logicHE->versionID();
- VAR(VAR_U32_ARRAY_UNK) = 0;
- }
-}
-
-void ScummEngine_v99he::initScummVars() {
- ScummEngine_v90he::initScummVars();
-
- VAR(VAR_NUM_PALETTES) = _numPalettes;
- VAR(VAR_NUM_UNK) = _numUnk;
-}
-#endif
-
-void ScummEngine::initScummVars() {
- if (_heversion < 70 && _version <= 6) {
- switch (_musicType) {
- case MDT_NONE:
- VAR(VAR_SOUNDCARD) = 0;
- break;
- case MDT_PCSPK:
- VAR(VAR_SOUNDCARD) = 1;
- break;
- case MDT_ADLIB:
- VAR(VAR_SOUNDCARD) = 3;
- break;
- default:
- if ((_gameId == GID_MONKEY_EGA || _gameId == GID_MONKEY_VGA || (_gameId == GID_LOOM && _version == 3))
- && (_platform == Common::kPlatformPC)) {
- if (_gameId == GID_LOOM) {
- char buf[50];
- Common::File f;
- for (int i = 82; i < 85; i++) {
- sprintf(buf, "%d.LFL", i);
- if (!Common::File::exists(buf))
- error("Native MIDI support requires Roland patch from LucasArts");
- }
- } else if (_gameId == GID_MONKEY_EGA) {
- if (!Common::File::exists("DISK09.LEC"))
- error("Native MIDI support requires Roland patch from LucasArts");
- }
- VAR(VAR_SOUNDCARD) = 4;
- } else {
- VAR(VAR_SOUNDCARD) = 3;
- }
- }
-
- if (_platform == Common::kPlatformFMTowns)
- VAR(VAR_VIDEOMODE) = 42;
- else if (_platform == Common::kPlatformMacintosh)
- VAR(VAR_VIDEOMODE) = 50;
- else if (_platform == Common::kPlatformAmiga)
- VAR(VAR_VIDEOMODE) = 82;
- else if (_renderMode == Common::kRenderCGA)
- VAR(VAR_VIDEOMODE) = 4;
- else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
- VAR(VAR_VIDEOMODE) = 30;
- else if (_renderMode == Common::kRenderEGA)
- VAR(VAR_VIDEOMODE) = 13;
- else
- VAR(VAR_VIDEOMODE) = 19;
-
- if (_platform == Common::kPlatformMacintosh && (_features & GF_OLD_BUNDLE)) {
- // Set screen size for the Macintosh version of Indy3/Loom
- VAR(39) = 320;
- }
- if (_platform == Common::kPlatformPC && _gameId == GID_LOOM && _version == 3) {
- // Set number of sound resources
- VAR(39) = 80;
- }
-
- if (_gameId == GID_LOOM || _version >= 4)
- VAR(VAR_HEAPSPACE) = 1400;
- if (_version >= 4)
- VAR(VAR_FIXEDDISK) = 1;
- if (_version >= 5)
- VAR(VAR_MOUSEPRESENT) = 1;
- if (_version == 6)
- VAR(VAR_V6_EMSSPACE) = 10000;
-
- if (_heversion >= 60) {
- // Set fast speed, to enable all animations
- VAR(VAR_MACHINE_SPEED) = 2;
-
- VAR(VAR_SOUNDPARAM) = 1; // Soundblaster for music
- VAR(VAR_SOUNDPARAM2) = 1; // Soundblaster for sound effects
- }
- }
-
- if (VAR_ROOM_WIDTH != 0xFF && VAR_ROOM_HEIGHT != 0xFF) {
- VAR(VAR_ROOM_WIDTH) = _screenWidth;
- VAR(VAR_ROOM_HEIGHT) = _screenHeight;
- }
-
- if (VAR_FADE_DELAY != 0xFF)
- VAR(VAR_FADE_DELAY) = 3;
-
- VAR(VAR_CHARINC) = 4;
- setTalkingActor(0);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/verbs.cpp b/scumm/verbs.cpp
deleted file mode 100644
index 7b01527b92..0000000000
--- a/scumm/verbs.cpp
+++ /dev/null
@@ -1,855 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/intern.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-enum {
- kInventoryUpArrow = 4,
- kInventoryDownArrow = 5,
- kSentenceLine = 6
-};
-
-struct VerbSettings {
- int id;
- int x_pos;
- int y_pos;
- const char *name;
-};
-
-static const VerbSettings C64VerbTable[] =
-{
- { 1, 8, 0, "Open"},
- { 2, 8, 1, "Close"},
- { 3, 0, 2, "Give"},
- { 4, 32, 0, "Turn On"},
- { 5, 32, 1, "Turn Off"},
- { 6, 32, 2, "Fix"},
- { 7, 24, 0, "New Kid"},
- { 8, 24, 1, "Unlock"},
- { 9, 0, 0, "Push"},
- {10, 0, 1, "Pull"},
- {11, 24, 2, "Use"},
- {12, 8, 2, "Read"},
- {13, 15, 0, "Walk To"},
- {14, 15, 1, "Pick Up"},
- {15, 15, 2, "What Is"}
-};
-
-void ScummEngine_c64::initC64Verbs() {
- VirtScreen *virt = &virtscr[kVerbVirtScreen];
- VerbSlot *vs;
- int i;
-
- for (i = 1; i < 16; i++) {
- vs = &_verbs[i];
- vs->verbid = C64VerbTable[i - 1].id;
- vs->color = 5;
- vs->hicolor = 7;
- vs->dimcolor = 11;
- vs->type = kTextVerbType;
- vs->charset_nr = _string[0]._default.charset;
- vs->curmode = 1;
- vs->saveid = 0;
- vs->key = 0;
- vs->center = 0;
- vs->imgindex = 0;
-
- vs->curRect.left = C64VerbTable[i - 1].x_pos * 8;
- vs->curRect.top = C64VerbTable[i - 1].y_pos * 8 + virt->topline + 8;
-
- loadPtrToResource(rtVerb, i, (const byte*)C64VerbTable[i - 1].name);
- }
-}
-
-void ScummEngine_v2::initV2MouseOver() {
- int i;
- int arrow_color, color, hi_color;
-
- if (_version == 1) {
- color = 16;
- hi_color = 7;
- arrow_color = 6;
- } else {
- color = 13;
- hi_color = 14;
- arrow_color = 1;
- }
-
- _mouseOverBoxV2 = -1;
-
- // Inventory items
-
- for (i = 0; i < 2; i++) {
- _mouseOverBoxesV2[2 * i].rect.left = 0;
- _mouseOverBoxesV2[2 * i].rect.right = 144;
- _mouseOverBoxesV2[2 * i].rect.top = 32 + 8 * i;
- _mouseOverBoxesV2[2 * i].rect.bottom = _mouseOverBoxesV2[2 * i].rect.top + 8;
-
- _mouseOverBoxesV2[2 * i].color = color;
- _mouseOverBoxesV2[2 * i].hicolor = hi_color;
-
- _mouseOverBoxesV2[2 * i + 1].rect.left = 176;
- _mouseOverBoxesV2[2 * i + 1].rect.right = 320;
- _mouseOverBoxesV2[2 * i + 1].rect.top = _mouseOverBoxesV2[2 * i].rect.top;
- _mouseOverBoxesV2[2 * i + 1].rect.bottom = _mouseOverBoxesV2[2 * i].rect.bottom;
-
- _mouseOverBoxesV2[2 * i + 1].color = color;
- _mouseOverBoxesV2[2 * i + 1].hicolor = hi_color;
- }
-
- // Inventory arrows
-
- _mouseOverBoxesV2[kInventoryUpArrow].rect.left = 144;
- _mouseOverBoxesV2[kInventoryUpArrow].rect.right = 176;
- _mouseOverBoxesV2[kInventoryUpArrow].rect.top = 32;
- _mouseOverBoxesV2[kInventoryUpArrow].rect.bottom = 40;
-
- _mouseOverBoxesV2[kInventoryUpArrow].color = arrow_color;
- _mouseOverBoxesV2[kInventoryUpArrow].hicolor = hi_color;
-
- _mouseOverBoxesV2[kInventoryDownArrow].rect.left = 144;
- _mouseOverBoxesV2[kInventoryDownArrow].rect.right = 176;
- _mouseOverBoxesV2[kInventoryDownArrow].rect.top = 40;
- _mouseOverBoxesV2[kInventoryDownArrow].rect.bottom = 48;
-
- _mouseOverBoxesV2[kInventoryDownArrow].color = arrow_color;
- _mouseOverBoxesV2[kInventoryDownArrow].hicolor = hi_color;
-
- // Sentence line
-
- _mouseOverBoxesV2[kSentenceLine].rect.left = 0;
- _mouseOverBoxesV2[kSentenceLine].rect.right = 320;
- _mouseOverBoxesV2[kSentenceLine].rect.top = 0;
- _mouseOverBoxesV2[kSentenceLine].rect.bottom = 8;
-
- _mouseOverBoxesV2[kSentenceLine].color = color;
- _mouseOverBoxesV2[kSentenceLine].hicolor = hi_color;
-}
-
-void ScummEngine_v2::initNESMouseOver() {
- int i;
- int arrow_color, color, hi_color;
-
- color = 0;
- hi_color = 0;
- arrow_color = 0;
-
- _mouseOverBoxV2 = -1;
-
- // Inventory items
-
- for (i = 0; i < 2; i++) {
- _mouseOverBoxesV2[2 * i].rect.left = 16;
- _mouseOverBoxesV2[2 * i].rect.right = 120;
- _mouseOverBoxesV2[2 * i].rect.top = 48 + 8 * i;
- _mouseOverBoxesV2[2 * i].rect.bottom = _mouseOverBoxesV2[2 * i].rect.top + 8;
-
- _mouseOverBoxesV2[2 * i].color = color;
- _mouseOverBoxesV2[2 * i].hicolor = hi_color;
-
- _mouseOverBoxesV2[2 * i + 1].rect.left = 152;
- _mouseOverBoxesV2[2 * i + 1].rect.right = 256;
- _mouseOverBoxesV2[2 * i + 1].rect.top = _mouseOverBoxesV2[2 * i].rect.top;
- _mouseOverBoxesV2[2 * i + 1].rect.bottom = _mouseOverBoxesV2[2 * i].rect.bottom;
-
- _mouseOverBoxesV2[2 * i + 1].color = color;
- _mouseOverBoxesV2[2 * i + 1].hicolor = hi_color;
- }
-
- // Inventory arrows
-
- _mouseOverBoxesV2[kInventoryUpArrow].rect.left = 128;
- _mouseOverBoxesV2[kInventoryUpArrow].rect.right = 136;
- _mouseOverBoxesV2[kInventoryUpArrow].rect.top = 48;
- _mouseOverBoxesV2[kInventoryUpArrow].rect.bottom = 56;
-
- _mouseOverBoxesV2[kInventoryUpArrow].color = arrow_color;
- _mouseOverBoxesV2[kInventoryUpArrow].hicolor = hi_color;
-
- _mouseOverBoxesV2[kInventoryDownArrow].rect.left = 136;
- _mouseOverBoxesV2[kInventoryDownArrow].rect.right = 144;
- _mouseOverBoxesV2[kInventoryDownArrow].rect.top = 48;
- _mouseOverBoxesV2[kInventoryDownArrow].rect.bottom = 56;
-
- _mouseOverBoxesV2[kInventoryDownArrow].color = arrow_color;
- _mouseOverBoxesV2[kInventoryDownArrow].hicolor = hi_color;
-
- // Sentence line
-
- _mouseOverBoxesV2[kSentenceLine].rect.left = 16;
- _mouseOverBoxesV2[kSentenceLine].rect.right = 256;
- _mouseOverBoxesV2[kSentenceLine].rect.top = 0;
- _mouseOverBoxesV2[kSentenceLine].rect.bottom = 8;
-
- _mouseOverBoxesV2[kSentenceLine].color = color;
- _mouseOverBoxesV2[kSentenceLine].hicolor = hi_color;
-}
-
-void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
- VirtScreen *vs = &virtscr[kVerbVirtScreen];
- Common::Rect rect;
- byte *ptr, *dst;
- int i, x, y, new_box = -1;
-
- // Don't do anything unless the inventory is active
- if (!(_userState & 64)) {
- _mouseOverBoxV2 = -1;
- return;
- }
-
- if (_cursor.state > 0) {
- for (i = 0; i < ARRAYSIZE(_mouseOverBoxesV2); i++) {
- if (_mouseOverBoxesV2[i].rect.contains(pos.x, pos.y - vs->topline)) {
- new_box = i;
- break;
- }
- }
- }
-
- if (new_box != _mouseOverBoxV2) {
- if (_mouseOverBoxV2 != -1) {
- rect = _mouseOverBoxesV2[_mouseOverBoxV2].rect;
-
- dst = ptr = vs->getPixels(rect.left, rect.top);
-
- // Remove highlight.
- for (y = rect.height() - 1; y >= 0; y--) {
- for (x = rect.width() - 1; x >= 0; x--) {
- if (dst[x] == _mouseOverBoxesV2[_mouseOverBoxV2].hicolor)
- dst[x] = _mouseOverBoxesV2[_mouseOverBoxV2].color;
- }
- dst += vs->pitch;
- }
-
- markRectAsDirty(kVerbVirtScreen, rect);
- }
-
- if (new_box != -1) {
- rect = _mouseOverBoxesV2[new_box].rect;
-
- dst = ptr = vs->getPixels(rect.left, rect.top);
-
- // Apply highlight
- for (y = rect.height() - 1; y >= 0; y--) {
- for (x = rect.width() - 1; x >= 0; x--) {
- if (dst[x] == _mouseOverBoxesV2[new_box].color)
- dst[x] = _mouseOverBoxesV2[new_box].hicolor;
- }
- dst += vs->pitch;
- }
-
- markRectAsDirty(kVerbVirtScreen, rect);
- }
-
- _mouseOverBoxV2 = new_box;
- }
-}
-
-void ScummEngine_v2::checkV2Inventory(int x, int y) {
- int inventoryArea = (_platform == Common::kPlatformNES) ? 48: 32;
- int object = 0;
-
- y -= virtscr[kVerbVirtScreen].topline;
-
- if ((y < inventoryArea) || !(_mouseAndKeyboardStat & MBS_LEFT_CLICK))
- return;
-
- if (_mouseOverBoxesV2[kInventoryUpArrow].rect.contains(x, y)) {
- if (_inventoryOffset >= 2) {
- _inventoryOffset -= 2;
- redrawV2Inventory();
- }
- } else if (_mouseOverBoxesV2[kInventoryDownArrow].rect.contains(x, y)) {
- if (_inventoryOffset + 4 < getInventoryCount(_scummVars[VAR_EGO])) {
- _inventoryOffset += 2;
- redrawV2Inventory();
- }
- }
-
- for (object = 0; object < 4; object++) {
- if (_mouseOverBoxesV2[object].rect.contains(x, y)) {
- break;
- }
- }
-
- if (object >= 4)
- return;
-
- object = findInventory(_scummVars[VAR_EGO], object + 1 + _inventoryOffset);
-
- if (object > 0) {
- runInputScript(3, object, 0);
- }
-}
-
-void ScummEngine_v2::redrawV2Inventory() {
- VirtScreen *vs = &virtscr[kVerbVirtScreen];
- int i;
- int max_inv;
- Common::Rect inventoryBox;
- int inventoryArea = (_platform == Common::kPlatformNES) ? 48: 32;
- int maxChars = (_platform == Common::kPlatformNES) ? 13: 18;
-
- _mouseOverBoxV2 = -1;
-
- if (!(_userState & 64)) // Don't draw inventory unless active
- return;
-
- // Clear on all invocations
- inventoryBox.top = vs->topline + inventoryArea;
- inventoryBox.bottom = vs->topline + virtscr[kVerbVirtScreen].h;
- inventoryBox.left = 0;
- inventoryBox.right = vs->w;
- restoreBG(inventoryBox);
-
- _string[1].charset = 1;
-
- max_inv = getInventoryCount(_scummVars[VAR_EGO]) - _inventoryOffset;
- if (max_inv > 4)
- max_inv = 4;
- for (i = 0; i < max_inv; i++) {
- int obj = findInventory(_scummVars[VAR_EGO], i + 1 + _inventoryOffset);
- if (obj == 0)
- break;
-
- _string[1].ypos = _mouseOverBoxesV2[i].rect.top + vs->topline;
- _string[1].xpos = _mouseOverBoxesV2[i].rect.left;
-
- _string[1].color = _mouseOverBoxesV2[i].color;
-
- const byte *tmp = getObjOrActorName(obj);
- assert(tmp);
-
- // Prevent inventory entries from overflowing by truncating the text
- byte msg[20];
- msg[maxChars] = 0;
- strncpy((char *)msg, (const char *)tmp, maxChars);
-
- // Draw it
- drawString(1, msg);
- }
-
-
- // If necessary, draw "up" arrow
- if (_inventoryOffset > 0) {
- _string[1].xpos = _mouseOverBoxesV2[kInventoryUpArrow].rect.left;
- _string[1].ypos = _mouseOverBoxesV2[kInventoryUpArrow].rect.top + vs->topline;
- _string[1].color = _mouseOverBoxesV2[kInventoryUpArrow].color;
- if (_platform == Common::kPlatformNES)
- drawString(1, (const byte *)"\x7E");
- else
- drawString(1, (const byte *)" \1\2");
- }
-
- // If necessary, draw "down" arrow
- if (_inventoryOffset + 4 < getInventoryCount(_scummVars[VAR_EGO])) {
- _string[1].xpos = _mouseOverBoxesV2[kInventoryDownArrow].rect.left;
- _string[1].ypos = _mouseOverBoxesV2[kInventoryDownArrow].rect.top + vs->topline;
- _string[1].color = _mouseOverBoxesV2[kInventoryDownArrow].color;
- if (_platform == Common::kPlatformNES)
- drawString(1, (const byte *)"\x7F");
- else
- drawString(1, (const byte *)" \3\4");
- }
-}
-
-void ScummEngine::redrawVerbs() {
- if (_version <= 2 && !(_userState & 128)) // Don't draw verbs unless active
- return;
-
- int i, verb = 0;
- if (_cursor.state > 0)
- verb = findVerbAtPos(_mouse.x, _mouse.y);
-
- // Iterate over all verbs.
- // Note: This is the correct order (at least for MI EGA, MI2, Full Throttle).
- // Do not change it! If you discover, based on disasm, that some game uses
- // another (e.g. the reverse) order here, you have to use an if/else construct
- // to add it as a special case!
- for (i = 0; i < _numVerbs; i++) {
- if (i == verb && _verbs[verb].hicolor)
- drawVerb(i, 1);
- else
- drawVerb(i, 0);
- }
- _verbMouseOver = verb;
-}
-
-void ScummEngine::handleMouseOver(bool updateInventory) {
- if (_completeScreenRedraw) {
- verbMouseOver(0);
- } else {
- if (_cursor.state > 0)
- verbMouseOver(findVerbAtPos(_mouse.x, _mouse.y));
- }
-}
-
-void ScummEngine_v2::handleMouseOver(bool updateInventory) {
- ScummEngine::handleMouseOver(updateInventory);
-
- if (updateInventory) {
- // FIXME/TODO: Reset and redraw the sentence line
- _inventoryOffset = 0;
- }
- if (_completeScreenRedraw || updateInventory) {
- redrawV2Inventory();
- }
- checkV2MouseOver(_mouse);
-}
-
-void ScummEngine::checkExecVerbs() {
- int i, over;
- VerbSlot *vs;
-
- if (VAR_MOUSE_STATE != 0xFF)
- VAR(VAR_MOUSE_STATE) = 0;
-
- if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
- return;
-
- if (VAR_MOUSE_STATE != 0xFF)
- VAR(VAR_MOUSE_STATE) = _mouseAndKeyboardStat;
-
- if (_mouseAndKeyboardStat < MBS_MAX_KEY) {
- /* Check keypresses */
- vs = &_verbs[1];
- for (i = 1; i < _numVerbs; i++, vs++) {
- if (vs->verbid && vs->saveid == 0 && vs->curmode == 1) {
- if (_mouseAndKeyboardStat == vs->key) {
- // Trigger verb as if the user clicked it
- runInputScript(1, vs->verbid, 1);
- return;
- }
- }
- }
-
- if ((_gameId == GID_INDY4 || _gameId == GID_PASS) && _mouseAndKeyboardStat >= '0' && _mouseAndKeyboardStat <= '9') {
- // To support keyboard fighting in FOA, we need to remap the number keys.
- // FOA apparently expects PC scancode values (see script 46 if you want
- // to know where I got these numbers from). Oddly enough, the The Indy 3
- // part of the "Passport to Adventure" demo expects the same keyboard
- // mapping, even though the full game doesn't.
- static const int numpad[10] = {
- '0',
- 335, 336, 337,
- 331, 332, 333,
- 327, 328, 329
- };
- _mouseAndKeyboardStat = numpad[_mouseAndKeyboardStat - '0'];
- }
-
- // Generic keyboard input
- runInputScript(4, _mouseAndKeyboardStat, 1);
- } else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
- VirtScreen *zone = findVirtScreen(_mouse.y);
- byte code = _mouseAndKeyboardStat & MBS_LEFT_CLICK ? 1 : 2;
- int inventoryArea = (_platform == Common::kPlatformNES) ? 48: 32;
-
- if (_version <= 2 && zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
- // Click into V2 sentence line
- runInputScript(5, 0, 0);
- } else if (_version <= 2 && zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) {
- // Click into V2 inventory
- ((ScummEngine_v2 *)this)->checkV2Inventory(_mouse.x, _mouse.y);
- } else {
- over = findVerbAtPos(_mouse.x, _mouse.y);
- if (over != 0) {
- // Verb was clicked
- runInputScript(1, _verbs[over].verbid, code);
- } else {
- // Scene was clicked
- runInputScript((zone->number == kMainVirtScreen) ? 2 : 1, 0, code);
- }
- }
- }
-}
-
-void ScummEngine_c64::checkExecVerbs() {
- Actor *a;
- VirtScreen *zone = findVirtScreen(_mouse.y);
-
- if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
- return;
-
- if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
- // TODO
- } else if (_version <= 2 && zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
- // Click into V2 inventory
- checkV2Inventory(_mouse.x, _mouse.y);
- } else {
- int over = findVerbAtPos(_mouse.x, _mouse.y);
- if (over) {
- _currentAction = _verbs[over].verbid;
- return;
- }
-
- // HACK: Reset value
- VAR(VAR_EGO) = 3;
-
- int object = findObject(_mouse.x, _mouse.y);
- if (object) {
- _activeObject = object;
- if (_currentMode == 3) {
- int x, y, dir;
- a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
- getObjectXYPos(object, x, y, dir);
- a->startWalkActor(x, y, dir);
- }
-
- int tmp = (_currentMode == 3) ? _currentAction : 15;
- runObjectScript(object, tmp, false, false, NULL);
- } else {
- _activeObject = 0;
- if (zone->number == kMainVirtScreen) {
- a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
- a->startWalkActor(_mouse.x, _mouse.y, -1);
- }
- }
- }
-}
-
-void ScummEngine::verbMouseOver(int verb) {
- // Don't do anything unless verbs are active
- if (_version <= 2 && !(_userState & 128))
- return;
-
- if (_gameId == GID_FT)
- return;
-
- if (_verbMouseOver == verb)
- return;
-
- if (_verbs[_verbMouseOver].type != kImageVerbType) {
- drawVerb(_verbMouseOver, 0);
- _verbMouseOver = verb;
- }
-
- if (_verbs[verb].type != kImageVerbType && _verbs[verb].hicolor) {
- drawVerb(verb, 1);
- _verbMouseOver = verb;
- }
-}
-
-int ScummEngine::findVerbAtPos(int x, int y) const {
- if (!_numVerbs)
- return 0;
-
- VerbSlot *vs;
- int i = _numVerbs - 1;
-
- vs = &_verbs[i];
- do {
- if (vs->curmode != 1 || !vs->verbid || vs->saveid || y < vs->curRect.top || y >= vs->curRect.bottom)
- continue;
- if (vs->center) {
- if (x < -(vs->curRect.right - 2 * vs->curRect.left) || x >= vs->curRect.right)
- continue;
- } else {
- if (x < vs->curRect.left || x >= vs->curRect.right)
- continue;
- }
-
- return i;
- } while (--vs, --i);
-
- return 0;
-}
-
-#ifndef DISABLE_SCUMM_7_8
-void ScummEngine_v7::drawVerb(int verb, int mode) {
- VerbSlot *vs;
-
- if (!verb)
- return;
-
- vs = &_verbs[verb];
-
- if (!vs->saveid && vs->curmode && vs->verbid) {
- if (vs->type == kImageVerbType) {
- drawVerbBitmap(verb, vs->curRect.left, vs->curRect.top);
- return;
- }
-
- uint8 color = vs->color;
- if (vs->curmode == 2)
- color = vs->dimcolor;
- else if (mode && vs->hicolor)
- color = vs->hicolor;
-
- const byte *msg = getResourceAddress(rtVerb, verb);
- if (!msg)
- return;
-
- // Convert the message, and skip a few remaining 0xFF codes (they
- // occur in FT; subtype 10, which is used for the speech associated
- // with the string).
- byte buf[384];
- convertMessageToString(msg, buf, sizeof(buf));
- msg = buf;
- while (*msg == 0xFF)
- msg += 4;
-
- enqueueText(msg, vs->curRect.left, vs->curRect.top, color, vs->charset_nr, vs->center);
-
- // Set the specified charset id
- _charset->setCurID(vs->charset_nr);
-
- // Compute the text rect
- vs->curRect.right = 0;
- vs->curRect.bottom = 0;
- while (*msg) {
- const int charWidth = _charset->getCharWidth(*msg);
- const int charHeight = _charset->getCharHeight(*msg);
- vs->curRect.right += charWidth;
- if (vs->curRect.bottom < charHeight)
- vs->curRect.bottom = charHeight;
- msg++;
- }
- vs->curRect.right += vs->curRect.left;
- vs->curRect.bottom += vs->curRect.top;
- vs->oldRect = vs->curRect;
- }
-}
-#endif
-
-void ScummEngine::drawVerb(int verb, int mode) {
- VerbSlot *vs;
- bool tmp;
-
- if (!verb)
- return;
-
- vs = &_verbs[verb];
-
- if (!vs->saveid && vs->curmode && vs->verbid) {
- if (vs->type == kImageVerbType) {
- drawVerbBitmap(verb, vs->curRect.left, vs->curRect.top);
- return;
- }
-
- restoreVerbBG(verb);
-
- _string[4].charset = vs->charset_nr;
- _string[4].xpos = vs->curRect.left;
- _string[4].ypos = vs->curRect.top;
- _string[4].right = _screenWidth - 1;
- _string[4].center = vs->center;
-
- if (vs->curmode == 2)
- _string[4].color = vs->dimcolor;
- else if (mode && vs->hicolor)
- _string[4].color = vs->hicolor;
- else
- _string[4].color = vs->color;
-
- // FIXME For the future: Indy3 and under inv scrolling
- /*
- if (verb >= 31 && verb <= 36)
- verb += _inventoryOffset;
- */
-
- const byte *msg = getResourceAddress(rtVerb, verb);
- if (!msg)
- return;
-
- tmp = _charset->_center;
- drawString(4, msg);
- _charset->_center = tmp;
-
- vs->curRect.right = _charset->_str.right;
- vs->curRect.bottom = _charset->_str.bottom;
- vs->oldRect = _charset->_str;
- _charset->_str.left = _charset->_str.right;
- } else if (_gameId != GID_FT) {
- restoreVerbBG(verb);
- }
-}
-
-void ScummEngine::restoreVerbBG(int verb) {
-
- VerbSlot *vs;
-
- vs = &_verbs[verb];
-
- if (vs->oldRect.left != -1) {
- restoreBG(vs->oldRect, vs->bkcolor);
- vs->oldRect.left = -1;
- }
-}
-
-void ScummEngine::drawVerbBitmap(int verb, int x, int y) {
- VirtScreen *vs;
- VerbSlot *vst;
- bool twobufs;
- const byte *imptr = 0;
- int ydiff, xstrip;
- int imgw, imgh;
- int i, tmp;
- byte *obim;
- const ImageHeader *imhd;
- uint32 size;
-
- if ((vs = findVirtScreen(y)) == NULL)
- return;
-
- gdi.disableZBuffer();
-
- twobufs = vs->hasTwoBuffers;
- vs->hasTwoBuffers = false;
-
- xstrip = x / 8;
- ydiff = y - vs->topline;
-
- obim = getResourceAddress(rtVerb, verb);
- assert(obim);
- if (_features & GF_OLD_BUNDLE) {
- imgw = obim[0];
- imgh = obim[1] / 8;
- imptr = obim + 2;
- } else if (_features & GF_SMALL_HEADER) {
- size = READ_LE_UINT32(obim);
-
- imgw = (*(obim + size + 11));
- imgh = (*(obim + size + 17)) / 8;
- imptr = getObjectImage(obim, 1);
- } else {
- imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), obim);
- if (_version >= 7) {
- imgw = READ_LE_UINT16(&imhd->v7.width) / 8;
- imgh = READ_LE_UINT16(&imhd->v7.height) / 8;
- } else {
- imgw = READ_LE_UINT16(&imhd->old.width) / 8;
- imgh = READ_LE_UINT16(&imhd->old.height) / 8;
- }
- imptr = getObjectImage(obim, 1);
- }
- assert(imptr);
- for (i = 0; i < imgw; i++) {
- tmp = xstrip + i;
- gdi.drawBitmap(imptr, vs, tmp, ydiff, imgw * 8, imgh * 8, i, 1, Gdi::dbAllowMaskOr | Gdi::dbObjectMode);
- }
-
- vst = &_verbs[verb];
- vst->curRect.right = vst->curRect.left + imgw * 8;
- vst->curRect.bottom = vst->curRect.top + imgh * 8;
- vst->oldRect = vst->curRect;
-
- gdi.enableZBuffer();
-
- vs->hasTwoBuffers = twobufs;
-}
-
-int ScummEngine::getVerbSlot(int id, int mode) const {
- int i;
- for (i = 1; i < _numVerbs; i++) {
- if (_verbs[i].verbid == id && _verbs[i].saveid == mode) {
- return i;
- }
- }
- return 0;
-}
-
-void ScummEngine::killVerb(int slot) {
- VerbSlot *vs;
-
- if (slot == 0)
- return;
-
- vs = &_verbs[slot];
- vs->verbid = 0;
- vs->curmode = 0;
-
- res.nukeResource(rtVerb, slot);
-
- if (_version <= 6 && vs->saveid == 0) {
- drawVerb(slot, 0);
- verbMouseOver(0);
- }
- vs->saveid = 0;
-}
-
-void ScummEngine::setVerbObject(uint room, uint object, uint verb) {
- const byte *obimptr;
- const byte *obcdptr;
- uint32 size, size2;
- FindObjectInRoom foir;
- int i;
-
- if (_heversion >= 70) { // Windows titles. Here we always ignore room
- room = getObjectRoom(object);
- }
-
- if (whereIsObject(object) == WIO_FLOBJECT)
- error("Can't grab verb image from flobject");
-
- if (_features & GF_OLD_BUNDLE) {
- for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_objs[i].obj_nr == object) {
- findObjectInRoom(&foir, foImageHeader, object, room);
- size = READ_LE_UINT16(foir.obim);
- byte *ptr = res.createResource(rtVerb, verb, size + 2);
- obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object);
- ptr[0] = *(obcdptr + 9); // Width
- ptr[1] = *(obcdptr + 15); // Height
- memcpy(ptr + 2, foir.obim, size);
- return;
- }
- }
- } else if (_features & GF_SMALL_HEADER) {
- for (i = (_numLocalObjects-1); i > 0; i--) {
- if (_objs[i].obj_nr == object) {
- // FIXME - the only thing we need from the OBCD is the image size!
- // So we could use almost the same code (save for offsets)
- // as in the GF_OLD_BUNDLE code. But of course that would break save games
- // unless we insert special conversion code... <sigh>
- findObjectInRoom(&foir, foImageHeader, object, room);
- size = READ_LE_UINT32(foir.obim);
- obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object);
- size2 = READ_LE_UINT32(obcdptr);
- res.createResource(rtVerb, verb, size + size2);
- obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim;
- obcdptr = getResourceAddress(rtRoom, room) + getOBCDOffs(object);
- memcpy(getResourceAddress(rtVerb, verb), obimptr, size);
- memcpy(getResourceAddress(rtVerb, verb) + size, obcdptr, size2);
- return;
- }
- }
- } else {
- findObjectInRoom(&foir, foImageHeader, object, room);
- size = READ_BE_UINT32(foir.obim + 4);
- res.createResource(rtVerb, verb, size);
- obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim;
- memcpy(getResourceAddress(rtVerb, verb), obimptr, size);
- }
-}
-
-} // End of namespace Scumm
diff --git a/scumm/verbs.h b/scumm/verbs.h
deleted file mode 100644
index 87cf7f3955..0000000000
--- a/scumm/verbs.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2002-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-#ifndef VERBS_H
-#define VERBS_H
-
-#include "common/scummsys.h"
-#include "common/rect.h"
-
-namespace Scumm {
-
-enum {
- kTextVerbType = 0,
- kImageVerbType = 1
-};
-
-struct VerbSlot {
- Common::Rect curRect;
- Common::Rect oldRect;
- uint16 verbid;
- uint8 color, hicolor, dimcolor, bkcolor, type;
- uint8 charset_nr, curmode;
- uint16 saveid;
- uint8 key;
- bool center;
- uint8 prep;
- uint16 imgindex;
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/scumm/wiz_he.cpp b/scumm/wiz_he.cpp
deleted file mode 100644
index 9b0f9c3f15..0000000000
--- a/scumm/wiz_he.cpp
+++ /dev/null
@@ -1,2088 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-
-#include "scumm/intern_he.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/wiz_he.h"
-
-namespace Scumm {
-
-Wiz::Wiz(ScummEngine_v70he *vm) : _vm(vm) {
- _imagesNum = 0;
- memset(&_images, 0, sizeof(_images));
- memset(&_polygons, 0, sizeof(_polygons));
- _rectOverrideEnabled = false;
-}
-
-void Wiz::clearWizBuffer() {
- _imagesNum = 0;
-}
-
-void Wiz::polygonClear() {
- for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
- if (_polygons[i].flag == 1)
- memset(&_polygons[i], 0, sizeof(WizPolygon));
- }
-}
-
-void Wiz::polygonLoad(const uint8 *polData) {
- int slots = READ_LE_UINT32(polData);
- polData += 4;
-
- bool flag = 1;
- int id, points, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y;
- while (slots--) {
- id = READ_LE_UINT32(polData);
- points = READ_LE_UINT32(polData + 4);
- if (points != 4)
- error("Illegal polygon with %d points", points);
- vert1x = READ_LE_UINT32(polData + 8);
- vert1y = READ_LE_UINT32(polData + 12);
- vert2x = READ_LE_UINT32(polData + 16);
- vert2y = READ_LE_UINT32(polData + 20);
- vert3x = READ_LE_UINT32(polData + 24);
- vert3y = READ_LE_UINT32(polData + 28);
- vert4x = READ_LE_UINT32(polData + 32);
- vert4y = READ_LE_UINT32(polData + 36);
-
- polData += 40;
- polygonStore(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
- }
-}
-
-void Wiz::polygonStore(int id, bool flag, int vert1x, int vert1y, int vert2x, int vert2y, int vert3x, int vert3y, int vert4x, int vert4y) {
- WizPolygon *wp = NULL;
- for (int i = 0; i < ARRAYSIZE(_polygons); ++i) {
- if (_polygons[i].id == 0) {
- wp = &_polygons[i];
- break;
- }
- }
- if (!wp) {
- error("Wiz::polygonStore: out of polygon slot, max = %d", ARRAYSIZE(_polygons));
- }
-
- wp->vert[0].x = vert1x;
- wp->vert[0].y = vert1y;
- wp->vert[1].x = vert2x;
- wp->vert[1].y = vert2y;
- wp->vert[2].x = vert3x;
- wp->vert[2].y = vert3y;
- wp->vert[3].x = vert4x;
- wp->vert[3].y = vert4y;
- wp->vert[4].x = vert1x;
- wp->vert[4].y = vert1y;
- wp->id = id;
- wp->numVerts = 5;
- wp->flag = flag;
-
- polygonCalcBoundBox(wp->vert, wp->numVerts, wp->bound);
-}
-
-void Wiz::polygonRotatePoints(Common::Point *pts, int num, int angle) {
- double alpha = angle * PI / 180.;
- double cos_alpha = cos(alpha);
- double sin_alpha = sin(alpha);
-
- for (int i = 0; i < num; ++i) {
- int16 x = pts[i].x;
- int16 y = pts[i].y;
- pts[i].x = (int16)(x * cos_alpha - y * sin_alpha);
- pts[i].y = (int16)(y * cos_alpha + x * sin_alpha);
- }
-}
-
-void Wiz::polygonTransform(int resNum, int state, int po_x, int po_y, int angle, int scale, Common::Point *pts) {
- int32 w, h;
-
- getWizImageDim(resNum, state, w, h);
-
- // set the transformation origin to the center of the image
- if (_vm->_heversion >= 99) {
- pts[0].x = pts[3].x = -(w / 2);
- pts[1].x = pts[2].x = w / 2 - 1;
- pts[0].y = pts[1].y = -(h / 2);
- pts[2].y = pts[3].y = h / 2 - 1;
- } else {
- pts[1].x = pts[2].x = w / 2 - 1;
- pts[0].x = pts[0].y = pts[1].y = pts[3].x = -(w / 2);
- pts[2].y = pts[3].y = h / 2 - 1;
- }
-
- // scale
- if (scale != 0 && scale != 256) {
- for (int i = 0; i < 4; ++i) {
- pts[i].x = pts[i].x * scale / 256;
- pts[i].y = pts[i].y * scale / 256;
- }
- }
-
- // rotate
- if (angle != 0)
- polygonRotatePoints(pts, 4, angle);
-
- // translate
- for (int i = 0; i < 4; ++i) {
- pts[i].x += po_x;
- pts[i].y += po_y;
- }
-}
-
-void Wiz::polygonCalcBoundBox(Common::Point *vert, int numVerts, Common::Rect &bound) {
- bound.left = 10000;
- bound.top = 10000;
- bound.right = -10000;
- bound.bottom = -10000;
-
- // compute bounding box
- for (int j = 0; j < numVerts; j++) {
- Common::Rect r(vert[j].x, vert[j].y, vert[j].x + 1, vert[j].y + 1);
- bound.extend(r);
- }
-}
-
-void Wiz::polygonErase(int fromId, int toId) {
- for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
- if (_polygons[i].id >= fromId && _polygons[i].id <= toId)
- memset(&_polygons[i], 0, sizeof(WizPolygon));
- }
-}
-
-int Wiz::polygonHit(int id, int x, int y) {
- for (int i = 0; i < ARRAYSIZE(_polygons); i++) {
- if ((id == 0 || _polygons[i].id == id) && _polygons[i].bound.contains(x, y)) {
- if (polygonContains(_polygons[i], x, y)) {
- return _polygons[i].id;
- }
- }
- }
- return 0;
-}
-
-bool Wiz::polygonDefined(int id) {
- for (int i = 0; i < ARRAYSIZE(_polygons); i++)
- if (_polygons[i].id == id)
- return true;
- return false;
-}
-
-bool Wiz::polygonContains(const WizPolygon &pol, int x, int y) {
- int pi = pol.numVerts - 1;
- bool diry = (y < pol.vert[pi].y);
- bool curdir;
- bool r = false;
-
- for (int i = 0; i < pol.numVerts; i++) {
- curdir = (y < pol.vert[i].y);
-
- if (curdir != diry) {
- if (((pol.vert[pi].y - pol.vert[i].y) * (pol.vert[i].x - x) <
- (pol.vert[pi].x - pol.vert[i].x) * (pol.vert[i].y - y)) == diry)
- r = !r;
- }
-
- pi = i;
- diry = curdir;
- }
-
- // HE80+
- int a, b;
- pi = pol.numVerts - 1;
- if (r == 0) {
- for (int i = 0; i < pol.numVerts; i++) {
- if (pol.vert[i].y == y && pol.vert[i].y == pol.vert[pi].y) {
-
- a = pol.vert[i].x;
- b = pol.vert[pi].x;
-
- if (pol.vert[i].x >= pol.vert[pi].x)
- a = pol.vert[pi].x;
-
- if (pol.vert[i].x > pol.vert[pi].x)
- b = pol.vert[i].x;
-
- if (x >= a && x <= b)
- return 1;
-
- } else if (pol.vert[i].x == x && pol.vert[i].x == pol.vert[pi].x) {
-
- a = pol.vert[i].y;
- b = pol.vert[i].y;
-
- if (pol.vert[i].y >= pol.vert[pi].y)
- a = pol.vert[pi].y;
-
- if (pol.vert[i].y <= pol.vert[pi].y)
- b = pol.vert[pi].y;
-
- if (y >= a && y <= b)
- return 1;
- }
- pi = i;
- }
- }
-
- return r;
-}
-
-void Wiz::copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch) {
- Common::Rect dstRect(srcx, srcy, srcx + srcw, srcy + srch);
- dstRect.clip(dstw, dsth);
-
- int rw = dstRect.width();
- int rh = dstRect.height();
- if (rh <= 0 || rw <= 0)
- return;
-
- uint8 *dst1Ptr = dst1 + dstRect.left + dstRect.top * dstw;
- uint8 *dst2Ptr = dst2 + dstRect.left + dstRect.top * dstw;
- const uint8 *dataPtr = src;
-
- while (rh--) {
- uint16 off = READ_LE_UINT16(dataPtr); dataPtr += 2;
- const uint8 *dataPtrNext = off + dataPtr;
- uint8 *dst1PtrNext = dst1Ptr + dstw;
- uint8 *dst2PtrNext = dst2Ptr + dstw;
- if (off != 0) {
- int w = rw;
- while (w > 0) {
- uint8 code = *dataPtr++;
- if (code & 1) {
- code >>= 1;
- dst1Ptr += code;
- dst2Ptr += code;
- w -= code;
- } else if (code & 2) {
- code = (code >> 2) + 1;
- w -= code;
- if (w >= 0) {
- memset(dst1Ptr, *dataPtr++, code);
- dst1Ptr += code;
- dst2Ptr += code;
- } else {
- code += w;
- memset(dst1Ptr, *dataPtr, code);
- }
- } else {
- code = (code >> 2) + 1;
- w -= code;
- if (w >= 0) {
- memcpy(dst1Ptr, dst2Ptr, code);
- dst1Ptr += code;
- dst2Ptr += code;
- } else {
- code += w;
- memcpy(dst1Ptr, dst2Ptr, code);
- }
- }
- }
- }
- dataPtr = dataPtrNext;
- dst1Ptr = dst1PtrNext;
- dst2Ptr = dst2PtrNext;
- }
-}
-
-static bool calcClipRects(int dst_w, int dst_h, int src_x, int src_y, int src_w, int src_h, const Common::Rect *rect, Common::Rect &srcRect, Common::Rect &dstRect) {
- srcRect = Common::Rect(src_w, src_h);
- dstRect = Common::Rect(src_x, src_y, src_x + src_w, src_y + src_h);
- Common::Rect r3;
- int diff;
-
- if (rect) {
- r3 = *rect;
- Common::Rect r4(dst_w, dst_h);
- if (r3.intersects(r4)) {
- r3.clip(r4);
- } else {
- return false;
- }
- } else {
- r3 = Common::Rect(dst_w, dst_h);
- }
- diff = dstRect.left - r3.left;
- if (diff < 0) {
- srcRect.left -= diff;
- dstRect.left -= diff;
- }
- diff = dstRect.right - r3.right;
- if (diff > 0) {
- srcRect.right -= diff;
- dstRect.right -= diff;
- }
- diff = dstRect.top - r3.top;
- if (diff < 0) {
- srcRect.top -= diff;
- dstRect.top -= diff;
- }
- diff = dstRect.bottom - r3.bottom;
- if (diff > 0) {
- srcRect.bottom -= diff;
- dstRect.bottom -= diff;
- }
-
- return srcRect.isValidRect() && dstRect.isValidRect();
-}
-
-void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
- Common::Rect r1, r2;
- if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
- dst += r2.left + r2.top * dstw;
- decompressWizImage(dst, dstw, r2, src, r1, flags, palPtr, xmapPtr);
- }
-}
-
-void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) {
- // RAW 16 bits in 555 format
-
- // HACK: Skip every second bit for now
- Common::Rect r1, r2;
- if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
- if (flags & kWIFFlipX) {
- int l = r1.left;
- int r = r1.right;
- r1.left = srcw - r;
- r1.right = srcw - l;
- }
- if (flags & kWIFFlipY) {
- int t = r1.top;
- int b = r1.bottom;
- r1.top = srch - b;
- r1.bottom = srch - t;
- }
- byte imagePal[256];
- if (!palPtr) {
- for (int i = 0; i < 256; i++) {
- imagePal[i] = i;
- }
- palPtr = imagePal;
- }
-
- int h = r1.height();
- int w = r1.width();
- src += r1.left + r1.top * srcw * 2;
- dst += r2.left + r2.top * dstw;
-
- while (h--) {
- const uint8 *p = src;
- for (int i = 0; i < w; ++i) {
- uint8 col = *p;
- if (transColor == -1 || transColor != col) {
- dst[i] = palPtr[col];
- }
- p += 2;
- }
- src += srcw * 2;
- dst += dstw;
- }
-
- }
-}
-
-void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) {
- Common::Rect r1, r2;
- if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
- if (flags & kWIFFlipX) {
- int l = r1.left;
- int r = r1.right;
- r1.left = srcw - r;
- r1.right = srcw - l;
- }
- if (flags & kWIFFlipY) {
- int t = r1.top;
- int b = r1.bottom;
- r1.top = srch - b;
- r1.bottom = srch - t;
- }
- byte imagePal[256];
- if (!palPtr) {
- for (int i = 0; i < 256; i++) {
- imagePal[i] = i;
- }
- palPtr = imagePal;
- }
- int h = r1.height();
- int w = r1.width();
- src += r1.left + r1.top * srcw;
- dst += r2.left + r2.top * dstw;
- while (h--) {
- const uint8 *p = src;
- for (int i = 0; i < w; ++i) {
- uint8 col = *p++;
- if (transColor == -1 || transColor != col) {
- dst[i] = palPtr[col];
- }
- }
- src += srcw;
- dst += dstw;
- }
- }
-}
-
-void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const Common::Rect &dstRect, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
- if (flags & kWIFFlipX) {
- debug(1, "decompressWizImage: Unhandled flag kWIFFlipX");
- }
- if (flags & kWIFFlipY) {
- debug(1, "decompressWizImage: Unhandled flag kWIFFlipY");
- }
-
- const uint8 *dataPtr, *dataPtrNext;
- uint8 *dstPtr, *dstPtrNext;
- uint32 code;
- uint8 databit;
- int h, w, xoff;
- uint16 off;
-
- byte imagePal[256];
- if (!palPtr) {
- for (int i = 0; i < 256; i++) {
- imagePal[i] = i;
- }
- palPtr = imagePal;
- }
-
- dstPtr = dst;
- dataPtr = src;
-
- // Skip over the first 'srcRect->top' lines in the data
- h = srcRect.top;
- while (h--) {
- dataPtr += READ_LE_UINT16(dataPtr) + 2;
- }
- h = srcRect.height();
- w = srcRect.width();
- if (h <= 0 || w <= 0)
- return;
-
- while (h--) {
- xoff = srcRect.left;
- off = READ_LE_UINT16(dataPtr);
- w = srcRect.right - srcRect.left;
- dstPtrNext = dstPitch + dstPtr;
- dataPtrNext = off + 2 + dataPtr;
- dataPtr += 2;
- if (off == 0)
- goto dec_next;
-
- // Skip over the leftmost 'srcRect->left' pixels.
- // TODO: This code could be merged (at a loss of efficency) with the
- // loop below which does the actual drawing.
- while (xoff > 0) {
- code = *dataPtr++;
- databit = code & 1;
- code >>= 1;
- if (databit) {
- xoff -= code;
- if (xoff < 0) {
- code = -xoff;
- goto dec_sub1;
- }
- } else {
- databit = code & 1;
- code = (code >> 1) + 1;
- if (databit) {
- ++dataPtr;
- xoff -= code;
- if (xoff < 0) {
- code = -xoff;
- --dataPtr;
- goto dec_sub2;
- }
- } else {
- dataPtr += code;
- xoff -= code;
- if (xoff < 0) {
- dataPtr += xoff;
- code = -xoff;
- goto dec_sub3;
- }
- }
- }
- }
-
- while (w > 0) {
- code = *dataPtr++;
- databit = code & 1;
- code >>= 1;
- if (databit) {
-dec_sub1: dstPtr += code;
- w -= code;
- } else {
- databit = code & 1;
- code = (code >> 1) + 1;
- if (databit) {
-dec_sub2: w -= code;
- if (w < 0) {
- code += w;
- }
- while (code--) {
- if (xmapPtr) {
- *dstPtr = xmapPtr[palPtr[*dataPtr] * 256 + *dstPtr];
- dstPtr++;
- } else {
- *dstPtr++ = palPtr[*dataPtr];
- }
- }
- dataPtr++;
- } else {
-dec_sub3: w -= code;
- if (w < 0) {
- code += w;
- }
- while (code--) {
- if (xmapPtr) {
- *dstPtr = xmapPtr[palPtr[*dataPtr++] * 256 + *dstPtr];
- dstPtr++;
- } else {
- *dstPtr++ = palPtr[*dataPtr++];
- }
- }
- }
- }
- }
-dec_next:
- dataPtr = dataPtrNext;
- dstPtr = dstPtrNext;
- }
-}
-
-int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h) {
- if (x < 0 || x >= w || y < 0 || y >= h) {
- return 0;
- }
- while (y != 0) {
- data += READ_LE_UINT16(data) + 2;
- --y;
- }
- uint16 off = READ_LE_UINT16(data); data += 2;
- if (off == 0) {
- return 0;
- }
- while (x > 0) {
- uint8 code = *data++;
- if (code & 1) {
- code >>= 1;
- if (code > x) {
- return 0;
- }
- x -= code;
- } else if (code & 2) {
- code = (code >> 2) + 1;
- if (code > x) {
- return 1;
- }
- x -= code;
- ++data;
- } else {
- code = (code >> 2) + 1;
- if (code > x) {
- return 1;
- }
- x -= code;
- data += code;
- }
- }
- return (~data[0]) & 1;
-}
-
-uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) {
- if (x < 0 || x >= w || y < 0 || y >= h) {
- return color;
- }
- while (y != 0) {
- data += READ_LE_UINT16(data) + 2;
- --y;
- }
- uint16 off = READ_LE_UINT16(data); data += 2;
- if (off == 0) {
- return color;
- }
- while (x > 0) {
- uint8 code = *data++;
- if (code & 1) {
- code >>= 1;
- if (code > x) {
- return color;
- }
- x -= code;
- } else if (code & 2) {
- code = (code >> 2) + 1;
- if (code > x) {
- return data[0];
- }
- x -= code;
- ++data;
- } else {
- code = (code >> 2) + 1;
- if (code > x) {
- return data[x];
- }
- x -= code;
- data += code;
- }
- }
- return (data[0] & 1) ? color : data[1];
-}
-
-uint8 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) {
- if (x < 0 || x >= w || y < 0 || y >= h) {
- return color;
- }
- return data[y * w + x];
-}
-
-void Wiz::computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect &rCapt) {
- int y = rCapt.top;
- while (y != 0) {
- data += READ_LE_UINT16(data) + 2;
- --y;
- }
- int ih = rCapt.height();
- while (ih--) {
- uint16 off = READ_LE_UINT16(data); data += 2;
- if (off != 0) {
- const uint8 *p = data;
- int x1 = rCapt.left;
- int x2 = rCapt.right;
- uint8 code;
- while (x1 > 0) {
- code = *p++;
- if (code & 1) {
- code >>= 1;
- if (code > x1) {
- code -= x1;
- x2 -= code;
- break;
- }
- x1 -= code;
- } else if (code & 2) {
- code = (code >> 2) + 1;
- if (code > x1) {
- code -= x1;
- goto dec_sub2;
- }
- x1 -= code;
- ++p;
- } else {
- code = (code >> 2) + 1;
- if (code > x1) {
- code -= x1;
- p += x1;
- goto dec_sub3;
- }
- x1 -= code;
- p += code;
- }
- }
- while (x2 > 0) {
- code = *p++;
- if (code & 1) {
- code >>= 1;
- x2 -= code;
- } else if (code & 2) {
- code = (code >> 2) + 1;
-dec_sub2: x2 -= code;
- if (x2 < 0) {
- code += x2;
- }
- histogram[*p++] += code;
- } else {
- code = (code >> 2) + 1;
-dec_sub3: x2 -= code;
- if (x2 < 0) {
- code += x2;
- }
- int n = code;
- while (n--) {
- ++histogram[*p++];
- }
- }
- }
- data += off;
- }
- }
-}
-
-void Wiz::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect &rCapt) {
- data += rCapt.top * srcPitch + rCapt.left;
- int iw = rCapt.width();
- int ih = rCapt.height();
- while (ih--) {
- for (int i = 0; i < iw; ++i) {
- ++histogram[data[i]];
- }
- data += srcPitch;
- }
-}
-
-static int wizPackType1(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 transColor) {
- debug(9, "wizPackType1(%d, [%d,%d,%d,%d])", transColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom);
- src += rCapt.top * srcPitch + rCapt.left;
- int w = rCapt.width();
- int h = rCapt.height();
- int dataSize = 0;
- while (h--) {
- uint8 *dstLine = dst;
- if (dst) {
- dst += 2;
- }
- uint8 diffBuffer[0x40];
- int runCountSame = 0;
- int runCountDiff = 0;
- uint8 prevColor = src[0];
- for (int i = 1; i < w; ) {
- uint8 color = src[i++];
- if (i == 2) {
- if (prevColor == color) {
- runCountSame = 1;
- } else {
- diffBuffer[0] = prevColor;
- runCountDiff = 1;
- }
- }
- if (prevColor == color) {
- if (runCountDiff != 0) {
- runCountSame = 1;
- if (runCountDiff > 1) {
- --runCountDiff;
- if (dst) {
- *dst++ = ((runCountDiff - 1) << 2) | 0;
- memcpy(dst, diffBuffer, runCountDiff);
- dst += runCountDiff;
- }
- dataSize += runCountDiff + 1;
- }
- runCountDiff = 0;
- }
- ++runCountSame;
- if (prevColor == transColor) {
- if (runCountSame == 0x7F) {
- if (dst) {
- *dst++ = (runCountSame << 1) | 1;
- }
- ++dataSize;
- runCountSame = 0;
- }
- } else {
- if (runCountSame == 0x40) {
- if (dst) {
- *dst++ = ((runCountSame - 1) << 2) | 2;
- *dst++ = prevColor;
- }
- dataSize += 2;
- runCountSame = 0;
- }
- }
- } else {
- if (runCountSame != 0) {
- if (prevColor == transColor) {
- if (dst) {
- *dst++ = (runCountSame << 1) | 1;
- }
- ++dataSize;
- } else {
- if (dst) {
- *dst++ = ((runCountSame - 1) << 2) | 2;
- *dst++ = prevColor;
- }
- dataSize += 2;
- }
- runCountSame = 0;
- }
- assert(runCountDiff < ARRAYSIZE(diffBuffer));
- diffBuffer[runCountDiff++] = color;
- if (runCountDiff == 0x40) {
- if (dst) {
- *dst++ = ((runCountDiff - 1) << 2) | 0;
- memcpy(dst, diffBuffer, runCountDiff);
- dst += runCountDiff + 1;
- }
- dataSize += runCountDiff + 1;
- runCountDiff = 0;
- }
- }
- prevColor = color;
- }
- if (runCountSame != 0) {
- if (prevColor == transColor) {
- if (dst) {
- *dst++ = (runCountSame << 1) | 1;
- }
- ++dataSize;
- } else {
- if (dst) {
- *dst++ = ((runCountSame - 1) << 2) | 2;
- *dst++ = prevColor;
- }
- dataSize += 2;
- }
- }
- if (runCountDiff != 0) {
- if (dst) {
- *dst++ = ((runCountDiff - 1) << 2) | 0;
- memcpy(dst, diffBuffer, runCountDiff);
- dst += runCountDiff;
- }
- dataSize += runCountDiff + 1;
- }
- if (dst) {
- WRITE_LE_UINT16(dstLine, dst - dstLine - 2);
- }
- dataSize += 2;
- src += srcPitch;
- }
- return dataSize;
-}
-
-static int wizPackType0(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt) {
- debug(9, "wizPackType0([%d,%d,%d,%d])", rCapt.left, rCapt.top, rCapt.right, rCapt.bottom);
- int w = rCapt.width();
- int h = rCapt.height();
- int size = w * h;
- if (dst) {
- src += rCapt.top * srcPitch + rCapt.left;
- while (h--) {
- memcpy(dst, src, w);
- dst += w;
- src += srcPitch;
- }
- }
- return size;
-}
-
-void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, int compType) {
- debug(5, "ScummEngine_v72he::captureWizImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom);
- uint8 *src = NULL;
- VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen];
- if (backBuffer) {
- src = pvs->getBackPixels(0, 0);
- } else {
- src = pvs->getPixels(0, 0);
- }
- Common::Rect rCapt(pvs->w, pvs->h);
- if (rCapt.intersects(r)) {
- rCapt.clip(r);
- const uint8 *palPtr;
- if (_vm->_heversion >= 99) {
- palPtr = _vm->_hePalettes + 1024;
- } else {
- palPtr = _vm->_currentPalette;
- }
-
- int w = rCapt.width();
- int h = rCapt.height();
- int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5;
-
- // compute compressed size
- int dataSize = 0;
- int headerSize = palPtr ? 1080 : 36;
- switch (compType) {
- case 0:
- dataSize = wizPackType0(0, src, pvs->pitch, rCapt);
- break;
- case 1:
- dataSize = wizPackType1(0, src, pvs->pitch, rCapt, transColor);
- break;
- default:
- error("unhandled compression type %d", compType);
- break;
- }
-
- // alignment
- dataSize = (dataSize + 1) & ~1;
- int wizSize = headerSize + dataSize;
- // write header
- uint8 *wizImg = _vm->res.createResource(rtImage, resNum, dataSize + headerSize);
- WRITE_BE_UINT32(wizImg + 0x00, 'AWIZ');
- WRITE_BE_UINT32(wizImg + 0x04, wizSize);
- WRITE_BE_UINT32(wizImg + 0x08, 'WIZH');
- WRITE_BE_UINT32(wizImg + 0x0C, 0x14);
- WRITE_LE_UINT32(wizImg + 0x10, compType);
- WRITE_LE_UINT32(wizImg + 0x14, w);
- WRITE_LE_UINT32(wizImg + 0x18, h);
- int curSize = 0x1C;
- if (palPtr) {
- WRITE_BE_UINT32(wizImg + 0x1C, 'RGBS');
- WRITE_BE_UINT32(wizImg + 0x20, 0x308);
- memcpy(wizImg + 0x24, palPtr, 0x300);
- WRITE_BE_UINT32(wizImg + 0x324, 'RMAP');
- WRITE_BE_UINT32(wizImg + 0x328, 0x10C);
- WRITE_BE_UINT32(wizImg + 0x32C, 0);
- curSize = 0x330;
- for (int i = 0; i < 256; ++i) {
- wizImg[curSize] = i;
- ++curSize;
- }
- }
- WRITE_BE_UINT32(wizImg + curSize + 0x0, 'WIZD');
- WRITE_BE_UINT32(wizImg + curSize + 0x4, dataSize + 8);
- curSize += 8;
-
- // write compressed data
- switch (compType) {
- case 0:
- wizPackType0(wizImg + headerSize, src, pvs->pitch, rCapt);
- break;
- case 1:
- wizPackType1(wizImg + headerSize, src, pvs->pitch, rCapt, transColor);
- break;
- default:
- break;
- }
- }
- _vm->res.setModified(rtImage, resNum);
-}
-
-void Wiz::displayWizImage(WizImage *pwi) {
- if (_vm->_fullRedraw) {
- assert(_imagesNum < ARRAYSIZE(_images));
- WizImage *wi = &_images[_imagesNum];
- wi->resNum = pwi->resNum;
- wi->x1 = pwi->x1;
- wi->y1 = pwi->y1;
- wi->zorder = 0;
- wi->state = pwi->state;
- wi->flags = pwi->flags;
- wi->shadow = 0;
- wi->field_390 = 0;
- wi->palette = 0;
- ++_imagesNum;
- } else if (pwi->flags & kWIFIsPolygon) {
- drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, 0, 0, 0);
- } else {
- const Common::Rect *r = NULL;
- drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, 0, 0, 0, r, pwi->flags, 0, 0);
- }
-}
-
-uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette) {
- debug(2, "drawWizImage(resNum %d, x1 %d y1 %d flags 0x%X zorder %d shadow %d field_390 %d dstResNum %d palette %d)", resNum, x1, y1, flags, zorder, shadow, field_390, dstResNum, palette);
- uint8 *dataPtr;
- uint8 *dst = NULL;
-
- const uint8 *palPtr = NULL;
- if (_vm->_heversion >= 99) {
- if (palette) {
- palPtr = _vm->_hePalettes + palette * 1024 + 768;
- } else {
- palPtr = _vm->_hePalettes + 1792;
- }
- }
-
- const uint8 *xmapPtr = NULL;
- if (shadow) {
- dataPtr = _vm->getResourceAddress(rtImage, shadow);
- assert(dataPtr);
- xmapPtr = _vm->findResourceData(MKID('XMAP'), dataPtr);
- assert(xmapPtr);
- }
-
- dataPtr = _vm->getResourceAddress(rtImage, resNum);
- assert(dataPtr);
-
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- uint32 comp = READ_LE_UINT32(wizh + 0x0);
- uint32 width = READ_LE_UINT32(wizh + 0x4);
- uint32 height = READ_LE_UINT32(wizh + 0x8);
- debug(2, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height);
-
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), dataPtr, state, 0);
- assert(wizd);
-
- if (flags & kWIFHasPalette) {
- uint8 *pal = _vm->findWrappedBlock(MKID('RGBS'), dataPtr, state, 0);
- assert(pal);
- _vm->setPaletteFromPtr(pal, 256);
- }
-
- uint8 *rmap = NULL;
- if (flags & kWIFRemapPalette) {
- rmap = _vm->findWrappedBlock(MKID('RMAP'), dataPtr, state, 0);
- assert(rmap);
- if (_vm->_heversion <= 80 || READ_BE_UINT32(rmap) != 0x01234567) {
- uint8 *rgbs = _vm->findWrappedBlock(MKID('RGBS'), dataPtr, state, 0);
- assert(rgbs);
- _vm->remapHEPalette(rgbs, rmap + 4);
- }
- }
-
- if (flags & kWIFPrint) {
- error("WizImage printing is unimplemented");
- }
-
- int32 cw, ch;
- if (flags & kWIFBlitToMemBuffer) {
- dst = (uint8 *)malloc(width * height);
- int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? (_vm->VAR(_vm->VAR_WIZ_TCOLOR)) : 5;
- memset(dst, transColor, width * height);
- cw = width;
- ch = height;
- } else {
- if (dstResNum) {
- uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum);
- assert(dstPtr);
- dst = _vm->findWrappedBlock(MKID('WIZD'), dstPtr, 0, 0);
- assert(dst);
- getWizImageDim(dstResNum, 0, cw, ch);
- } else {
- VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen];
- if (flags & kWIFMarkBufferDirty) {
- dst = pvs->getPixels(0, pvs->topline);
- } else {
- dst = pvs->getBackPixels(0, pvs->topline);
- }
- cw = pvs->w;
- ch = pvs->h;
- }
- }
-
- Common::Rect rScreen(cw, ch);
- if (clipBox) {
- Common::Rect clip(clipBox->left, clipBox->top, clipBox->right, clipBox->bottom);
- if (rScreen.intersects(clip)) {
- rScreen.clip(clip);
- } else {
- return 0;
- }
- } else if (_rectOverrideEnabled) {
- if (rScreen.intersects(_rectOverride)) {
- rScreen.clip(_rectOverride);
- } else {
- return 0;
- }
- }
-
- if (flags & kWIFRemapPalette) {
- palPtr = rmap + 4;
- }
-
- int transColor = -1;
- if (_vm->VAR_WIZ_TCOLOR != 0xFF) {
- uint8 *trns = _vm->findWrappedBlock(MKID('TRNS'), dataPtr, state, 0);
- transColor = (trns == NULL) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : -1;
- }
-
- switch (comp) {
- case 0:
- copyRawWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor);
- break;
- case 1:
- // TODO Adding masking for flags 0x80 and 0x100
- if (flags & 0x80)
- // Used in maze
- debug(0, "drawWizImage: Unhandled flag 0x80");
- if (flags & 0x100) {
- // Used in readdemo
- debug(0, "drawWizImage: Unhandled flag 0x100");
- }
- copyWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr);
- break;
- case 2:
- copyRaw16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, transColor);
- break;
- default:
- error("drawWizImage: Unhandled wiz compression type %d", comp);
- }
-
- if (!(flags & kWIFBlitToMemBuffer) && dstResNum == 0) {
- Common::Rect rImage(x1, y1, x1 + width, y1 + height);
- if (rImage.intersects(rScreen)) {
- rImage.clip(rScreen);
- if (!(flags & kWIFBlitToFrontVideoBuffer) && (flags & (kWIFBlitToFrontVideoBuffer | kWIFMarkBufferDirty))) {
- ++rImage.bottom;
- _vm->markRectAsDirty(kMainVirtScreen, rImage);
- } else {
- _vm->gdi.copyVirtScreenBuffers(rImage);
- }
- }
- }
-
- return dst;
-}
-
-struct PolygonDrawData {
- struct PolygonArea {
- int32 xmin;
- int32 xmax;
- int32 x1;
- int32 y1;
- int32 x2;
- int32 y2;
- };
- struct ResultArea {
- int32 dst_offs;
- int32 x_step;
- int32 y_step;
- int32 x_s;
- int32 y_s;
- int32 w;
- };
- Common::Point mat[4];
- PolygonArea *pa;
- ResultArea *ra;
- int rAreasNum;
- int pAreasNum;
-
- PolygonDrawData(int n) {
- memset(mat, 0, sizeof(mat));
- pa = new PolygonArea[n];
- for (int i = 0; i < n; ++i) {
- pa[i].xmin = 0x7FFFFFFF;
- pa[i].xmax = 0x80000000;
- }
- ra = new ResultArea[n];
- rAreasNum = 0;
- pAreasNum = n;
- }
-
- ~PolygonDrawData() {
- delete[] pa;
- delete[] ra;
- }
-
- void transform(const Common::Point *tp1, const Common::Point *tp2, const Common::Point *sp1, const Common::Point *sp2) {
- int32 tx_acc = tp1->x << 16;
- int32 sx_acc = sp1->x << 16;
- int32 sy_acc = sp1->y << 16;
- uint16 dy = ABS(tp2->y - tp1->y) + 1;
- int32 tx_step = ((tp2->x - tp1->x) << 16) / dy;
- int32 sx_step = ((sp2->x - sp1->x) << 16) / dy;
- int32 sy_step = ((sp2->y - sp1->y) << 16) / dy;
-
- int y = tp1->y - mat[0].y;
- while (dy--) {
- assert(y >= 0 && y < pAreasNum);
- PolygonArea *ppa = &pa[y];
- int32 ttx = tx_acc >> 16;
- int32 tsx = sx_acc >> 16;
- int32 tsy = sy_acc >> 16;
-
- if (ppa->xmin > ttx) {
- ppa->xmin = ttx;
- ppa->x1 = tsx;
- ppa->y1 = tsy;
- }
- if (ppa->xmax < ttx) {
- ppa->xmax = ttx;
- ppa->x2 = tsx;
- ppa->y2 = tsy;
- }
-
- tx_acc += tx_step;
- sx_acc += sx_step;
- sy_acc += sy_step;
-
- if (tp2->y <= tp1->y) {
- --y;
- } else {
- ++y;
- }
- }
- }
-};
-
-void Wiz::drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int scale, const Common::Rect *r, int flags, int dstResNum, int palette) {
- Common::Point pts[4];
-
- polygonTransform(resNum, state, po_x, po_y, angle, scale, pts);
- drawWizPolygonTransform(resNum, state, pts, flags, shadow, dstResNum, palette);
-}
-
-void Wiz::drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette) {
- int i;
- WizPolygon *wp = NULL;
- for (i = 0; i < ARRAYSIZE(_polygons); ++i) {
- if (_polygons[i].id == id) {
- wp = &_polygons[i];
- break;
- }
- }
- if (!wp) {
- error("Polygon %d is not defined", id);
- }
- if (wp->numVerts != 5) {
- error("Invalid point count %d for Polygon %d", wp->numVerts, id);
- }
-
- drawWizPolygonTransform(resNum, state, wp->vert, flags, shadow, dstResNum, palette);
-}
-
-void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette) {
- debug(2, "drawWizPolygonTransform(resNum %d, flags 0x%X, shadow %d dstResNum %d palette %d)", resNum, flags, shadow, dstResNum, palette);
- int i;
-
- if (flags & 0x800000) {
- warning("0x800000 flags not supported");
- return;
- }
-
- const Common::Rect *r = NULL;
- uint8 *srcWizBuf = drawWizImage(resNum, state, 0, 0, 0, shadow, 0, r, kWIFBlitToMemBuffer, 0, palette);
- if (srcWizBuf) {
- uint8 *dst;
- int32 dstw, dsth, dstpitch, wizW, wizH;
- VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen];
- int transColor = (_vm->VAR_WIZ_TCOLOR != 0xFF) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : 5;
-
- if (dstResNum) {
- uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum);
- assert(dstPtr);
- dst = _vm->findWrappedBlock(MKID('WIZD'), dstPtr, 0, 0);
- assert(dst);
- getWizImageDim(dstResNum, 0, dstw, dsth);
- dstpitch = dstw;
- } else {
- if (flags & kWIFMarkBufferDirty) {
- dst = pvs->getPixels(0, 0);
- } else {
- dst = pvs->getBackPixels(0, 0);
- }
- dstw = pvs->w;
- dsth = pvs->h;
- dstpitch = pvs->pitch;
- }
-
- getWizImageDim(resNum, state, wizW, wizH);
-
- Common::Point bbox[4];
- bbox[0].x = 0;
- bbox[0].y = 0;
- bbox[1].x = wizW - 1;
- bbox[1].y = 0;
- bbox[2].x = wizW - 1;
- bbox[2].y = wizH - 1;
- bbox[3].x = 0;
- bbox[3].y = wizH - 1;
-
- int16 xmin_p, xmax_p, ymin_p, ymax_p;
- xmin_p = ymin_p = (int16)0x7FFF;
- xmax_p = ymax_p = (int16)0x8000;
-
- for (i = 0; i < 4; ++i) {
- xmin_p = MIN(wp[i].x, xmin_p);
- xmax_p = MAX(wp[i].x, xmax_p);
- ymin_p = MIN(wp[i].y, ymin_p);
- ymax_p = MAX(wp[i].y, ymax_p);
- }
-
- int16 xmin_b, xmax_b, ymin_b, ymax_b;
- xmin_b = ymin_b = (int16)0x7FFF;
- xmax_b = ymax_b = (int16)0x8000;
-
- for (i = 0; i < 4; ++i) {
- xmin_b = MIN(bbox[i].x, xmin_b);
- xmax_b = MAX(bbox[i].x, xmax_b);
- ymin_b = MIN(bbox[i].y, ymin_b);
- ymax_b = MAX(bbox[i].y, ymax_b);
- }
-
- PolygonDrawData pdd(ymax_p - ymin_p + 1);
- pdd.mat[0].x = xmin_p;
- pdd.mat[0].y = ymin_p;
- pdd.mat[1].x = xmax_p;
- pdd.mat[1].y = ymax_p;
- pdd.mat[2].x = xmin_b;
- pdd.mat[2].y = ymin_b;
- pdd.mat[3].x = xmax_b;
- pdd.mat[3].y = ymax_b;
-
- // precompute the transformation which remaps 'bbox' pixels to 'wp'
- for (i = 0; i < 3; ++i) {
- pdd.transform(&wp[i], &wp[i + 1], &bbox[i], &bbox[i + 1]);
- }
- pdd.transform(&wp[3], &wp[0], &bbox[3], &bbox[0]);
-
- pdd.rAreasNum = 0;
- PolygonDrawData::ResultArea *pra = &pdd.ra[0];
- int32 yoff = pdd.mat[0].y * dstpitch;
- int16 y_start = pdd.mat[0].y;
- for (i = 0; i < pdd.pAreasNum; ++i) {
- PolygonDrawData::PolygonArea *ppa = &pdd.pa[i];
- if (y_start >= 0 && y_start < dsth) {
- int16 x1 = ppa->xmin;
- if (x1 < 0) {
- x1 = 0;
- }
- int16 x2 = ppa->xmax;
- if (x2 >= dstw) {
- x2 = dstw - 1;
- }
- int16 w = x2 - x1 + 1;
- if (w > 0) {
- int16 width = ppa->xmax - ppa->xmin + 1;
- pra->x_step = ((ppa->x2 - ppa->x1) << 16) / width;
- pra->y_step = ((ppa->y2 - ppa->y1) << 16) / width;
- pra->dst_offs = yoff + x1;
- pra->w = w;
- pra->x_s = ppa->x1 << 16;
- pra->y_s = ppa->y1 << 16;
- int16 tmp = x1 - ppa->xmin;
- if (tmp != 0) {
- pra->x_s += pra->x_step * tmp;
- pra->y_s += pra->y_step * tmp;
- }
- ++pra;
- ++pdd.rAreasNum;
- }
- }
- ++ppa;
- yoff += dstpitch;
- ++y_start;
- }
-
- pra = &pdd.ra[0];
- for (i = 0; i < pdd.rAreasNum; ++i, ++pra) {
- uint8 *dstPtr = dst + pra->dst_offs;
- int32 w = pra->w;
- int32 x_acc = pra->x_s;
- int32 y_acc = pra->y_s;
- while (--w) {
- int32 src_offs = (y_acc >> 16) * wizW + (x_acc >> 16);
- assert(src_offs < wizW * wizH);
- x_acc += pra->x_step;
- y_acc += pra->y_step;
- if (transColor == -1 || transColor != srcWizBuf[src_offs]) {
- *dstPtr = srcWizBuf[src_offs];
- }
- dstPtr++;
- }
- }
-
- Common::Rect bound(xmin_p, ymin_p, xmax_p + 1, ymax_p + 1);
- if (flags & kWIFMarkBufferDirty) {
- _vm->markRectAsDirty(kMainVirtScreen, bound);
- } else {
- _vm->gdi.copyVirtScreenBuffers(bound);
- }
-
- free(srcWizBuf);
- }
-}
-
-void Wiz::flushWizBuffer() {
- for (int i = 0; i < _imagesNum; ++i) {
- WizImage *pwi = &_images[i];
- if (pwi->flags & kWIFIsPolygon) {
- drawWizPolygon(pwi->resNum, pwi->state, pwi->x1, pwi->flags, pwi->shadow, 0, pwi->palette);
- } else {
- const Common::Rect *r = NULL;
- drawWizImage(pwi->resNum, pwi->state, pwi->x1, pwi->y1, pwi->zorder, pwi->shadow, pwi->field_390, r, pwi->flags, 0, pwi->palette);
- }
- }
- _imagesNum = 0;
-}
-
-void Wiz::loadWizCursor(int resId) {
- int32 x, y;
- getWizImageSpot(resId, 0, x, y);
- if (x < 0) {
- x = 0;
- } else if (x > 32) {
- x = 32;
- }
- if (y < 0) {
- y = 0;
- } else if (y > 32) {
- y = 32;
- }
-
- const Common::Rect *r = NULL;
- uint8 *cursor = drawWizImage(resId, 0, 0, 0, 0, 0, 0, r, kWIFBlitToMemBuffer, 0, 0);
- int32 cw, ch;
- getWizImageDim(resId, 0, cw, ch);
- _vm->setCursorFromBuffer(cursor, cw, ch, cw);
- _vm->setCursorHotspot(x, y);
- free(cursor);
-}
-
-void Wiz::displayWizComplexImage(const WizParameters *params) {
- int sourceImage = 0;
- if (params->processFlags & kWPFMaskImg) {
- sourceImage = params->sourceImage;
- debug(0, "displayWizComplexImage() unhandled flag 0x80000");
- }
- int palette = 0;
- if (params->processFlags & kWPFPaletteNum) {
- palette = params->img.palette;
- }
- int scale = 256;
- if (params->processFlags & kWPFScaled) {
- scale = params->scale;
- }
- int rotationAngle = 0;
- if (params->processFlags & kWPFRotate) {
- rotationAngle = params->angle;
- }
- int state = 0;
- if (params->processFlags & kWPFNewState) {
- state = params->img.state;
- }
- int flags = 0;
- if (params->processFlags & kWPFNewFlags) {
- flags = params->img.flags;
- }
- int po_x = 0;
- int po_y = 0;
- if (params->processFlags & kWPFSetPos) {
- po_x = params->img.x1;
- po_y = params->img.y1;
- }
- int shadow = 0;
- if (params->processFlags & kWPFShadow) {
- shadow = params->img.shadow;
- }
- int field_390 = 0;
- if (params->processFlags & 0x200000) {
- field_390 = params->img.field_390;
- debug(0, "displayWizComplexImage() unhandled flag 0x200000");
- }
- const Common::Rect *r = NULL;
- if (params->processFlags & kWPFClipBox) {
- r = &params->box;
- }
- int dstResNum = 0;
- if (params->processFlags & kWPFDstResNum) {
- dstResNum = params->dstResNum;
- }
- if (params->processFlags & kWPFRemapPalette) {
- remapWizImagePal(params);
- flags |= kWIFRemapPalette;
- }
-
- if (_vm->_fullRedraw && dstResNum == 0) {
- if (sourceImage != 0 || (params->processFlags & (kWPFScaled | kWPFRotate)))
- error("Can't do this command in the enter script.");
-
- assert(_imagesNum < ARRAYSIZE(_images));
- WizImage *pwi = &_images[_imagesNum];
- pwi->resNum = params->img.resNum;
- pwi->x1 = po_x;
- pwi->y1 = po_y;
- pwi->zorder = params->img.zorder;
- pwi->state = state;
- pwi->flags = flags;
- pwi->shadow = shadow;
- pwi->field_390 = field_390;
- pwi->palette = palette;
- ++_imagesNum;
- } else {
- if (sourceImage != 0) {
- // TODO
- } else if (params->processFlags & (kWPFScaled | kWPFRotate)) {
- drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette);
- } else {
- if (flags & kWIFIsPolygon) {
- drawWizPolygon(params->img.resNum, state, po_x, flags, shadow, dstResNum, palette); // XXX , VAR(VAR_WIZ_TCOLOR));
- } else {
- drawWizImage(params->img.resNum, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette);
- }
- }
- }
-}
-
-void Wiz::createWizEmptyImage(const WizParameters *params) {
- int img_w = 640;
- if (params->processFlags & kWPFUseDefImgWidth) {
- img_w = params->resDefImgW;
- }
- int img_h = 480;
- if (params->processFlags & kWPFUseDefImgHeight) {
- img_h = params->resDefImgH;
- }
- int img_x = 0;
- int img_y = 0;
- if (params->processFlags & 1) {
- img_x = params->img.x1;
- img_y = params->img.y1;
- }
- const uint16 flags = 0xB;
- int res_size = 0x1C;
- if (flags & 1) {
- res_size += 0x308;
- }
- if (flags & 2) {
- res_size += 0x10;
- }
- if (flags & 8) {
- res_size += 0x10C;
- }
- res_size += 8 + img_w * img_h;
-
- const uint8 *palPtr;
- if (_vm->_heversion >= 99) {
- palPtr = _vm->_hePalettes + 1024;
- } else {
- palPtr = _vm->_currentPalette;
- }
- uint8 *res_data = _vm->res.createResource(rtImage, params->img.resNum, res_size);
- if (!res_data) {
- _vm->VAR(119) = -1;
- } else {
- _vm->VAR(119) = 0;
- WRITE_BE_UINT32(res_data, 'AWIZ'); res_data += 4;
- WRITE_BE_UINT32(res_data, res_size); res_data += 4;
- WRITE_BE_UINT32(res_data, 'WIZH'); res_data += 4;
- WRITE_BE_UINT32(res_data, 0x14); res_data += 4;
- WRITE_LE_UINT32(res_data, 0); res_data += 4;
- WRITE_LE_UINT32(res_data, img_w); res_data += 4;
- WRITE_LE_UINT32(res_data, img_h); res_data += 4;
- if (flags & 1) {
- WRITE_BE_UINT32(res_data, 'RGBS'); res_data += 4;
- WRITE_BE_UINT32(res_data, 0x308); res_data += 4;
- memcpy(res_data, palPtr, 0x300); res_data += 0x300;
- }
- if (flags & 2) {
- WRITE_BE_UINT32(res_data, 'SPOT'); res_data += 4;
- WRITE_BE_UINT32(res_data, 0x10); res_data += 4;
- WRITE_BE_UINT32(res_data, img_x); res_data += 4;
- WRITE_BE_UINT32(res_data, img_y); res_data += 4;
- }
- if (flags & 8) {
- WRITE_BE_UINT32(res_data, 'RMAP'); res_data += 4;
- WRITE_BE_UINT32(res_data, 0x10C); res_data += 4;
- WRITE_BE_UINT32(res_data, 0); res_data += 4;
- for (int i = 0; i < 256; ++i) {
- *res_data++ = i;
- }
- }
- WRITE_BE_UINT32(res_data, 'WIZD'); res_data += 4;
- WRITE_BE_UINT32(res_data, 8 + img_w * img_h); res_data += 4;
- }
- _vm->res.setModified(rtImage, params->img.resNum);
-}
-
-void Wiz::fillWizRect(const WizParameters *params) {
- int state = 0;
- if (params->processFlags & kWPFNewState) {
- state = params->img.state;
- }
- uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum);
- if (dataPtr) {
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- int w = READ_LE_UINT32(wizh + 0x4);
- int h = READ_LE_UINT32(wizh + 0x8);
- assert(c == 0);
- Common::Rect areaRect, imageRect(w, h);
- if (params->processFlags & kWPFClipBox) {
- if (!imageRect.intersects(params->box)) {
- return;
- }
- imageRect.clip(params->box);
- }
- if (params->processFlags & kWPFClipBox2) {
- areaRect = params->box2;
- } else {
- areaRect = imageRect;
- }
- uint8 color = _vm->VAR(93);
- if (params->processFlags & kWPFFillColor) {
- color = params->fillColor;
- }
- if (areaRect.intersects(imageRect)) {
- areaRect.clip(imageRect);
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), dataPtr, state, 0);
- assert(wizd);
- int dx = areaRect.width();
- int dy = areaRect.height();
- wizd += areaRect.top * w + areaRect.left;
- while (dy--) {
- memset(wizd, color, dx);
- wizd += w;
- }
- }
- }
- _vm->res.setModified(rtImage, params->img.resNum);
-}
-
-void Wiz::fillWizLine(const WizParameters *params) {
- if (params->processFlags & kWPFClipBox2) {
- int state = 0;
- if (params->processFlags & kWPFNewState) {
- state = params->img.state;
- }
- uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum);
- if (dataPtr) {
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- int w = READ_LE_UINT32(wizh + 0x4);
- int h = READ_LE_UINT32(wizh + 0x8);
- assert(c == 0);
- Common::Rect imageRect(w, h);
- if (params->processFlags & kWPFClipBox) {
- if (!imageRect.intersects(params->box)) {
- return;
- }
- imageRect.clip(params->box);
- }
- uint8 color = _vm->VAR(93);
- if (params->processFlags & kWPFFillColor) {
- color = params->fillColor;
- }
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), dataPtr, state, 0);
- assert(wizd);
- int x1 = params->box2.left;
- int y1 = params->box2.top;
- int x2 = params->box2.right;
- int y2 = params->box2.bottom;
-
- int dx = x2 - x1;
- int incx = 0;
- if (dx > 0) {
- incx = 1;
- } else if (dx < 0) {
- incx = -1;
- }
- int dy = y2 - y1;
- int incy = 0;
- if (dy > 0) {
- incy = 1;
- } else if (dy < 0) {
- incy = -1;
- }
-
- dx = ABS(x2 - x1);
- dy = ABS(y2 - y1);
-
- if (imageRect.contains(x1, y1)) {
- *(wizd + y1 * w + x1) = color;
- }
-
- if (dx >= dy) {
- int step1_y = (dy - dx) * 2;
- int step2_y = dy * 2;
- int accum_y = dy * 2 - dx;
- while (x1 != x2) {
- if (accum_y <= 0) {
- accum_y += step2_y;
- } else {
- accum_y += step1_y;
- y1 += incy;
- }
- x1 += incx;
- if (imageRect.contains(x1, y1)) {
- *(wizd + y1 * w + x1) = color;
- }
- }
- } else {
- int step1_x = (dx - dy) * 2;
- int step2_x = dx * 2;
- int accum_x = dx * 2 - dy;
- while (y1 != y2) {
- if (accum_x <= 0) {
- accum_x += step2_x;
- } else {
- accum_x += step1_x;
- x1 += incx;
- }
- y1 += incy;
- if (imageRect.contains(x1, y1)) {
- *(wizd + y1 * w + x1) = color;
- }
- }
- }
- }
- }
- _vm->res.setModified(rtImage, params->img.resNum);
-}
-
-void Wiz::fillWizPixel(const WizParameters *params) {
- if (params->processFlags & kWPFClipBox2) {
- int px = params->box2.left;
- int py = params->box2.top;
- uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum);
- if (dataPtr) {
- int state = 0;
- if (params->processFlags & kWPFNewState) {
- state = params->img.state;
- }
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- int w = READ_LE_UINT32(wizh + 0x4);
- int h = READ_LE_UINT32(wizh + 0x8);
- assert(c == 0);
- Common::Rect imageRect(w, h);
- if (params->processFlags & kWPFClipBox) {
- if (!imageRect.intersects(params->box)) {
- return;
- }
- imageRect.clip(params->box);
- }
- uint8 color = _vm->VAR(93);
- if (params->processFlags & kWPFFillColor) {
- color = params->fillColor;
- }
- if (imageRect.contains(px, py)) {
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), dataPtr, state, 0);
- assert(wizd);
- *(wizd + py * w + px) = color;
- }
- }
- }
- _vm->res.setModified(rtImage, params->img.resNum);
-}
-
-void Wiz::remapWizImagePal(const WizParameters *params) {
- int st = (params->processFlags & kWPFNewState) ? params->img.state : 0;
- int num = params->remapNum;
- const uint8 *index = params->remapIndex;
- uint8 *iwiz = _vm->getResourceAddress(rtImage, params->img.resNum);
- assert(iwiz);
- uint8 *rmap = _vm->findWrappedBlock(MKID('RMAP'), iwiz, st, 0) ;
- assert(rmap);
- WRITE_BE_UINT32(rmap, 0x01234567);
- while (num--) {
- uint8 idx = *index++;
- rmap[4 + idx] = params->remapColor[idx];
- }
- _vm->res.setModified(rtImage, params->img.resNum);
-}
-
-void Wiz::processWizImage(const WizParameters *params) {
- char buf[512];
- unsigned int i;
-
- debug(2, "processWizImage: processMode %d", params->processMode);
- switch (params->processMode) {
- case 0:
- // Used in racedemo
- break;
- case 1:
- displayWizComplexImage(params);
- break;
- case 2:
- captureWizImage(params->img.resNum, params->box, (params->img.flags & kWIFBlitToFrontVideoBuffer) != 0, params->compType);
- break;
- case 3:
- if (params->processFlags & kWPFUseFile) {
- Common::File f;
-
- // Convert Windows path separators to something more portable
- strncpy(buf, (const char *)params->filename, 512);
- for (i = 0; i < strlen(buf); i++) {
- if (buf[i] == '\\')
- buf[i] = '/';
- }
-
- if (f.open((const char *)buf, Common::File::kFileReadMode)) {
- uint32 id = f.readUint32LE();
- if (id == TO_LE_32(MKID('AWIZ')) || id == TO_LE_32(MKID('MULT'))) {
- uint32 size = f.readUint32BE();
- f.seek(0, SEEK_SET);
- byte *p = _vm->res.createResource(rtImage, params->img.resNum, size);
- if (f.read(p, size) != size) {
- _vm->res.nukeResource(rtImage, params->img.resNum);
- error("i/o error when reading '%s'", buf);
- _vm->VAR(_vm->VAR_GAME_LOADED) = -2;
- _vm->VAR(119) = -2;
- } else {
- _vm->res.setModified(rtImage, params->img.resNum);
- _vm->VAR(_vm->VAR_GAME_LOADED) = 0;
- _vm->VAR(119) = 0;
- }
- } else {
- _vm->VAR(_vm->VAR_GAME_LOADED) = -1;
- _vm->VAR(119) = -1;
- }
- f.close();
- } else {
- _vm->VAR(_vm->VAR_GAME_LOADED) = -3;
- _vm->VAR(119) = -3;
- debug(0, "Unable to open for read '%s'", buf);
- }
- }
- break;
- case 4:
- if (params->processFlags & kWPFUseFile) {
- Common::File f;
-
- switch(params->fileWriteMode) {
- case 2:
- _vm->VAR(119) = -1;
- break;
- case 1:
- // TODO Write image to file
- break;
- case 0:
- // Convert Windows path separators to something more portable
- strncpy(buf, (const char *)params->filename, 512);
- for (i = 0; i < strlen(buf); i++) {
- if (buf[i] == '\\')
- buf[i] = '/';
- }
-
- if (!f.open((const char *)buf, Common::File::kFileWriteMode)) {
- debug(0, "Unable to open for write '%s'", buf);
- _vm->VAR(119) = -3;
- } else {
- byte *p = _vm->getResourceAddress(rtImage, params->img.resNum);
- uint32 size = READ_BE_UINT32(p + 4);
- if (f.write(p, size) != size) {
- error("i/o error when writing '%s'", params->filename);
- _vm->VAR(119) = -2;
- } else {
- _vm->VAR(119) = 0;
- }
- f.close();
- }
- break;
- default:
- error("processWizImage: processMode 4 unhandled fileWriteMode %d", params->fileWriteMode);
- }
- }
- break;
- case 6:
- if (params->processFlags & kWPFRemapPalette) {
- remapWizImagePal(params);
- }
- break;
- // HE 99+
- case 7:
- // Used in PuttsFunShop/SamsFunShop/soccer2004
- // TODO: Capture polygon
- _vm->res.setModified(rtImage, params->img.resNum);
- break;
- case 8:
- createWizEmptyImage(params);
- break;
- case 9:
- fillWizRect(params);
- break;
- case 10:
- fillWizLine(params);
- break;
- case 11:
- fillWizPixel(params);
- break;
- case 12:
- fillWizFlood(params);
- break;
- case 13:
- // Used for text in FreddisFunShop/PuttsFunShop/SamsFunShop
- // TODO: Start Font
- break;
- case 14:
- // Used for text in FreddisFunShop/PuttsFunShop/SamsFunShop
- // TODO: End Font
- break;
- case 15:
- // Used for text in FreddisFunShop/PuttsFunShop/SamsFunShop
- // TODO: Create Font
- break;
- case 16:
- // TODO: Render Font String
- error("Render Font String");
- break;
- case 17:
- // Used in to draw circles in FreddisFunShop/PuttsFunShop/SamsFunShop
- // TODO: Ellipse
- _vm->res.setModified(rtImage, params->img.resNum);
- break;
- default:
- error("Unhandled processWizImage mode %d", params->processMode);
- }
-}
-
-void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) {
- uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
- assert(dataPtr);
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- w = READ_LE_UINT32(wizh + 0x4);
- h = READ_LE_UINT32(wizh + 0x8);
-}
-
-void Wiz::getWizImageSpot(int resId, int state, int32 &x, int32 &y) {
- uint8 *dataPtr = _vm->getResourceAddress(rtImage, resId);
- assert(dataPtr);
- uint8 *spotPtr = _vm->findWrappedBlock(MKID('SPOT'), dataPtr, state, 0);
- if (spotPtr) {
- x = READ_LE_UINT32(spotPtr + 0);
- y = READ_LE_UINT32(spotPtr + 4);
- } else {
- x = 0;
- y = 0;
- }
-}
-
-int Wiz::getWizImageData(int resNum, int state, int type) {
- uint8 *dataPtr, *wizh;
-
- dataPtr = _vm->getResourceAddress(rtImage, resNum);
- assert(dataPtr);
-
- switch (type) {
- case 0:
- wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0);
- assert(wizh);
- return READ_LE_UINT32(wizh + 0x0);
- case 1:
- return (_vm->findWrappedBlock(MKID('RGBS'), dataPtr, state, 0) != NULL) ? 1 : 0;
- case 2:
- return (_vm->findWrappedBlock(MKID('RMAP'), dataPtr, state, 0) != NULL) ? 1 : 0;
- case 3:
- return (_vm->findWrappedBlock(MKID('TRNS'), dataPtr, state, 0) != NULL) ? 1 : 0;
- case 4:
- return (_vm->findWrappedBlock(MKID('XMAP'), dataPtr, state, 0) != NULL) ? 1 : 0;
- default:
- error("getWizImageData: Unknown type %d", type);
- }
-}
-
-int Wiz::getWizImageStates(int resNum) {
- const uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum);
- assert(dataPtr);
- if (READ_UINT32(dataPtr) == MKID('MULT')) {
- const byte *offs, *wrap;
-
- wrap = _vm->findResource(MKID('WRAP'), dataPtr);
- if (wrap == NULL)
- return 1;
-
- offs = _vm->findResourceData(MKID('OFFS'), wrap);
- if (offs == NULL)
- return 1;
-
- return _vm->getResourceDataSize(offs) / 4;
- } else {
- return 1;
- }
-}
-
-int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags) {
- int ret = 0;
- uint8 *data = _vm->getResourceAddress(rtImage, resNum);
- assert(data);
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), data, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- int w = READ_LE_UINT32(wizh + 0x4);
- int h = READ_LE_UINT32(wizh + 0x8);
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), data, state, 0);
- assert(wizd);
- if (x >= 0 && x < w && y >= 0 && y < h) {
- if (flags & kWIFFlipX) {
- x = w - x - 1;
- }
- if (flags & kWIFFlipY) {
- y = h - y - 1;
- }
- switch (c) {
- case 0:
- if (_vm->_heversion >= 99) {
- ret = getRawWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
- } else {
- ret = 0;
- }
- break;
- case 1:
- ret = isWizPixelNonTransparent(wizd, x, y, w, h);
- break;
- case 2:
- // Used baseball2003
- debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
- break;
- default:
- error("isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
- break;
- }
- }
- return ret;
-}
-
-uint8 Wiz::getWizPixelColor(int resNum, int state, int x, int y, int flags) {
- uint8 color;
- uint8 *data = _vm->getResourceAddress(rtImage, resNum);
- assert(data);
- uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), data, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- int w = READ_LE_UINT32(wizh + 0x4);
- int h = READ_LE_UINT32(wizh + 0x8);
- uint8 *wizd = _vm->findWrappedBlock(MKID('WIZD'), data, state, 0);
- assert(wizd);
- switch (c) {
- case 0:
- if (_vm->_heversion >= 99) {
- color = getRawWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
- } else {
- color = _vm->VAR(_vm->VAR_WIZ_TCOLOR);
- }
- break;
- case 1:
- color = getWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
- break;
- default:
- error("getWizPixelColor: Unhandled wiz compression type %d", c);
- break;
- }
- return color;
-}
-
-int ScummEngine_v90he::computeWizHistogram(int resNum, int state, int x, int y, int w, int h) {
- writeVar(0, 0);
- defineArray(0, kDwordArray, 0, 0, 0, 255);
- if (readVar(0) != 0) {
- Common::Rect rCapt(x, y, w + 1, h + 1);
- uint8 *data = getResourceAddress(rtImage, resNum);
- assert(data);
- uint8 *wizh = findWrappedBlock(MKID('WIZH'), data, state, 0);
- assert(wizh);
- int c = READ_LE_UINT32(wizh + 0x0);
- w = READ_LE_UINT32(wizh + 0x4);
- h = READ_LE_UINT32(wizh + 0x8);
- Common::Rect rWiz(w, h);
- uint8 *wizd = findWrappedBlock(MKID('WIZD'), data, state, 0);
- assert(wizd);
- if (rCapt.intersects(rWiz)) {
- rCapt.clip(rWiz);
- uint32 histogram[256];
- memset(histogram, 0, sizeof(histogram));
- switch (c) {
- case 0:
- _wiz->computeRawWizHistogram(histogram, wizd, w, rCapt);
- break;
- case 1:
- _wiz->computeWizHistogram(histogram, wizd, rCapt);
- break;
- default:
- error("computeWizHistogram: Unhandled wiz compression type %d", c);
- break;
- }
- for (int i = 0; i < 256; ++i) {
- writeArray(0, 0, i, histogram[i]);
- }
- }
- }
- return readVar(0);
-}
-
-} // End of namespace Scumm
diff --git a/scumm/wiz_he.h b/scumm/wiz_he.h
deleted file mode 100644
index 86d3e97721..0000000000
--- a/scumm/wiz_he.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#if !defined(WIZ_HE_H) && !defined(DISABLE_HE)
-#define WIZ_HE_H
-
-#include "common/rect.h"
-
-namespace Scumm {
-
-struct WizPolygon {
- Common::Point vert[5];
- Common::Rect bound;
- int id;
- int numVerts;
- bool flag;
-};
-
-struct WizImage {
- int resNum;
- int x1;
- int y1;
- int zorder;
- int state;
- int flags;
- int shadow;
- int field_390;
- int palette;
-};
-
-struct WizParameters {
- int field_0;
- byte filename[260];
- Common::Rect box;
- int processFlags;
- int processMode;
- int field_11C;
- int field_120;
- int field_124;
- int field_128;
- int field_12C;
- int field_130;
- int field_134;
- int field_138;
- int compType;
- int fileWriteMode;
- int angle;
- int scale;
- int field_164;
- int field_168;
- int resDefImgW;
- int resDefImgH;
- int sourceImage;
- int field_180;
- int field_184;
- uint8 remapColor[256];
- uint8 remapIndex[256];
- int remapNum;
- int dstResNum;
- byte fillColor;
- byte string1[4096];
- byte string2[4096];
- int field_2399;
- int field_239D;
- int field_23A1;
- int field_23A5;
- int field_23A9;
- int field_23AD;
- int field_23B1;
- int field_23B5;
- int field_23B9;
- int field_23BD;
- int field_23C1;
- int field_23C5;
- int field_23C9;
- int field_23CD;
- Common::Rect box2;
- int field_23DE;
- int spriteId;
- int spriteGroup;
- int field_23EA;
- WizImage img;
-};
-
-enum WizImageFlags {
- kWIFHasPalette = 0x1,
- kWIFRemapPalette = 0x2,
- kWIFPrint = 0x4,
- kWIFBlitToFrontVideoBuffer = 0x8,
- kWIFMarkBufferDirty = 0x10,
- kWIFBlitToMemBuffer = 0x20,
- kWIFIsPolygon = 0x40,
- kWIFFlipX = 0x400,
- kWIFFlipY = 0x800
-};
-
-enum WizProcessFlags {
- kWPFSetPos = 0x1,
- kWPFShadow = 0x4,
- kWPFScaled = 0x8,
- kWPFRotate = 0x10,
- kWPFNewFlags = 0x20,
- kWPFRemapPalette = 0x40,
- kWPFClipBox = 0x200,
- kWPFNewState = 0x400,
- kWPFUseFile = 0x800,
- kWPFUseDefImgWidth = 0x2000,
- kWPFUseDefImgHeight = 0x4000,
- kWPFPaletteNum = 0x8000,
- kWPFDstResNum = 0x10000,
- kWPFFillColor = 0x20000,
- kWPFClipBox2 = 0x40000,
- kWPFMaskImg = 0x80000
-};
-
-class ScummEngine_v70he;
-
-class Wiz {
-public:
- enum {
- NUM_POLYGONS = 200,
- NUM_IMAGES = 255
- };
-
- WizImage _images[NUM_IMAGES];
- uint16 _imagesNum;
- WizPolygon _polygons[NUM_POLYGONS];
-
- Wiz(ScummEngine_v70he *vm);
-
- void clearWizBuffer();
- Common::Rect _rectOverride;
- bool _rectOverrideEnabled;
-
- void polygonClear();
- void polygonLoad(const uint8 *polData);
- void polygonStore(int id, bool flag, int vert1x, int vert1y, int vert2x, int vert2y, int vert3x, int vert3y, int vert4x, int vert4y);
- void polygonCalcBoundBox(Common::Point *vert, int numVerts, Common::Rect & bound);
- void polygonErase(int fromId, int toId);
- int polygonHit(int id, int x, int y);
- bool polygonDefined(int id);
- bool polygonContains(const WizPolygon &pol, int x, int y);
- void polygonRotatePoints(Common::Point *pts, int num, int alpha);
- void polygonTransform(int resNum, int state, int po_x, int po_y, int angle, int zoom, Common::Point *vert);
-
- void createWizEmptyImage(const WizParameters *params);
- void fillWizRect(const WizParameters *params);
- void fillWizLine(const WizParameters *params);
- void fillWizPixel(const WizParameters *params);
- void fillWizFlood(const WizParameters *params);
- void remapWizImagePal(const WizParameters *params);
-
- void getWizImageDim(int resNum, int state, int32 &w, int32 &h);
- int getWizImageStates(int resnum);
- int isWizPixelNonTransparent(int resnum, int state, int x, int y, int flags);
- uint8 getWizPixelColor(int resnum, int state, int x, int y, int flags);
- int getWizImageData(int resNum, int state, int type);
-
- void flushWizBuffer();
-
- void getWizImageSpot(int resId, int state, int32 &x, int32 &y);
- void loadWizCursor(int resId);
-
- void captureWizImage(int resNum, const Common::Rect& r, bool frontBuffer, int compType);
- void displayWizComplexImage(const WizParameters *params);
- void displayWizImage(WizImage *pwi);
- void processWizImage(const WizParameters *params);
-
- uint8 *drawWizImage(int resNum, int state, int x1, int y1, int zorder, int shadow, int field_390, const Common::Rect *clipBox, int flags, int dstResNum, int palette);
- void drawWizPolygon(int resNum, int state, int id, int flags, int shadow, int dstResNum, int palette);
- void drawWizComplexPolygon(int resNum, int state, int po_x, int po_y, int shadow, int angle, int zoom, const Common::Rect *r, int flags, int dstResNum, int palette);
- void drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int flags, int shadow, int dstResNum, int palette);
-
- static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch);
- static void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
- static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
- static void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
- static void decompressWizImage(uint8 *dst, int dstPitch, const Common::Rect &dstRect, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
- int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h);
- uint8 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color);
- uint8 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color);
- void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect& rCapt);
- void computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect& rCapt);
-
-private:
- ScummEngine_v70he *_vm;
-};
-
-} // End of namespace Scumm
-
-#endif