aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorStephen Kennedy2008-09-26 21:53:08 +0000
committerStephen Kennedy2008-09-26 21:53:08 +0000
commita7bb113e83c88fad3a23d408caa99f918fdb610a (patch)
tree698dd9d85abaa6a20957bfb9c0e006e9dd1dc8b3 /engines/scumm
parent11c0a3bdedcdf5eb2618b9db67b559663fb93320 (diff)
parentc1385076cbc57f1a4a52946a46b3ea06ecf37f37 (diff)
downloadscummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.gz
scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.bz2
scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.zip
Merged revisions 33452-33453,33455-33459,33463-33464,33466-33471,33473-33474,33478,33490,33492,33495-33496,33509-33512,33518-33519,33522-33527,33529-33530,33537,33541,33544,33546,33550,33552-33554,33556,33558,33561-33562,33565,33568,33570,33574,33576,33578-33581,33584-33587,33590,33596,33604-33611,33614-33615,33617-33618,33620-33621,33623,33626-33627,33632-33633,33635,33637,33639-33640,33642-33645,33648,33654-33655,33664,33667-33670,33673-33674,33678,33682,33686-33691,33693,33696,33698,33700,33703,33708,33710,33712-33714,33716,33719,33721-33723,33725-33727,33729-33730,33733,33736,33742,33754,33756,33758,33761,33763,33766,33777,33781-33788,33790,33792-33793,33795,33797,33805,33807-33812,33815-33817,33819,33822,33826,33829,33837,33839,33844,33847,33858-33861,33864,33871-33873,33875,33877-33879,33886,33889-33892,33894,33896,33900,33902-33903,33919,33928,33930,33932-33936,33938-33940,33942-33943,33948,33950,33953,33967,33973,33976,33978,33980,33985,33991,33993,33999-34000,34006,34009,34011,34013,34015,34019,34021-34023,34025,34027-34028,34030,34032-34034,34036,34038-34039,34041,34046-34048,34050-34055,34057,34059-34065,34067,34072,34074,34076,34078-34081,34084,34086-34087,34089-34090,34093,34096-34102,34104,34107,34113,34116,34119,34122,34124,34126,34128,34131-34132,34135,34138,34141,34144,34146,34149,34152-34154,34156-34157,34160,34163-34164,34169,34173,34179-34194,34196-34198,34200-34201,34205-34206,34208-34217,34219-34225,34227-34228,34234-34237,34239-34249,34251-34279,34281-34284,34286-34288,34290-34320,34323-34324,34326,34328-34329,34332,34334,34336,34338-34340,34343-34353,34356-34357,34359-34371,34373,34375,34378,34381-34382,34384-34385,34389-34391,34393-34394,34396-34397,34399-34405,34407-34409,34411,34413,34415,34417-34420,34423-34426,34428-34438,34440-34454,34456-34458,34460,34462-34469,34472,34474,34479-34481,34483-34498,34501-34505,34508,34511-34518,34520-34524,34526-34563,34566-34569,34571-34590,34592,34595-34599,34602-34603,34605,34613-34615,34617,34619-34624,34627-34628,34630-34639,34642-34649 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk svn-id: r34654
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/actor.cpp208
-rw-r--r--engines/scumm/actor.h69
-rw-r--r--engines/scumm/akos.cpp28
-rw-r--r--engines/scumm/boxes.cpp20
-rw-r--r--engines/scumm/charset-fontdata.cpp1
-rw-r--r--engines/scumm/charset.cpp22
-rw-r--r--engines/scumm/charset.h14
-rw-r--r--engines/scumm/detection.cpp104
-rw-r--r--engines/scumm/detection_tables.h3
-rw-r--r--engines/scumm/dialogs.cpp64
-rw-r--r--engines/scumm/dialogs.h6
-rw-r--r--engines/scumm/file.cpp22
-rw-r--r--engines/scumm/file.h39
-rw-r--r--engines/scumm/file_nes.cpp6
-rw-r--r--engines/scumm/file_nes.h8
-rw-r--r--engines/scumm/gfx.cpp70
-rw-r--r--engines/scumm/gfx.h3
-rw-r--r--engines/scumm/gfxARM.s79
-rw-r--r--engines/scumm/he/cup_player_he.cpp6
-rw-r--r--engines/scumm/he/intern_he.h9
-rw-r--r--engines/scumm/he/script_v100he.cpp90
-rw-r--r--engines/scumm/he/script_v60he.cpp5
-rw-r--r--engines/scumm/he/script_v70he.cpp7
-rw-r--r--engines/scumm/he/script_v71he.cpp12
-rw-r--r--engines/scumm/he/script_v72he.cpp24
-rw-r--r--engines/scumm/he/script_v80he.cpp6
-rw-r--r--engines/scumm/he/script_v90he.cpp310
-rw-r--r--engines/scumm/input.cpp10
-rw-r--r--engines/scumm/insane/insane.cpp25
-rw-r--r--engines/scumm/insane/insane.h17
-rw-r--r--engines/scumm/insane/insane_iact.cpp15
-rw-r--r--engines/scumm/module.mk2
-rw-r--r--engines/scumm/object.cpp7
-rw-r--r--engines/scumm/resource.cpp8
-rw-r--r--engines/scumm/resource_v4.cpp2
-rw-r--r--engines/scumm/saveload.cpp125
-rw-r--r--engines/scumm/saveload.h8
-rw-r--r--engines/scumm/script.cpp12
-rw-r--r--engines/scumm/script_v5.cpp4
-rw-r--r--engines/scumm/script_v6.cpp13
-rw-r--r--engines/scumm/script_v8.cpp8
-rw-r--r--engines/scumm/scumm-md5.h26
-rw-r--r--engines/scumm/scumm.cpp90
-rw-r--r--engines/scumm/scumm.h46
-rw-r--r--engines/scumm/smush/channel.h15
-rw-r--r--engines/scumm/smush/chunk.cpp168
-rw-r--r--engines/scumm/smush/chunk.h92
-rw-r--r--engines/scumm/smush/imuse_channel.cpp48
-rw-r--r--engines/scumm/smush/saud_channel.cpp24
-rw-r--r--engines/scumm/smush/smush_player.cpp228
-rw-r--r--engines/scumm/smush/smush_player.h35
-rw-r--r--engines/scumm/string.cpp2
-rw-r--r--engines/scumm/thumbnail.cpp130
53 files changed, 1048 insertions, 1347 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index df6660523a..b2bb8be9c9 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -50,9 +50,11 @@ Actor::Actor(ScummEngine *scumm, int id) :
assert(_vm != 0);
}
-void Actor::initActor(int mode) {
- // begin HE specific
+void ActorHE::initActor(int mode) {
+ Actor::initActor(mode);
+
if (mode == -1) {
+ _heOffsX = _heOffsY = 0;
_heSkipLimbs = false;
memset(_heTalkQueue, 0, sizeof(_heTalkQueue));
}
@@ -70,11 +72,18 @@ void Actor::initActor(int mode) {
_hePaletteNum = 0;
_heFlags = 0;
_heTalking = false;
- // end HE specific
+ if (_vm->_game.heversion >= 61)
+ _flip = 0;
+
+ _clipOverride = _vm->_actorClipOverride;
+
+ _auxBlock.reset();
+}
+
+void Actor::initActor(int mode) {
if (mode == -1) {
- _offsX = _offsY = 0;
_top = _bottom = 0;
_needRedraw = false;
_needBgReset = false;
@@ -132,9 +141,6 @@ void Actor::initActor(int mode) {
_forceClip = (_vm->_game.version >= 7) ? 100 : 0;
_ignoreTurns = false;
- if (_vm->_game.heversion >= 61)
- _flip = 0;
-
_talkFrequency = 256;
_talkPan = 64;
_talkVolume = 127;
@@ -148,10 +154,6 @@ void Actor::initActor(int mode) {
_walkScript = 0;
_talkScript = 0;
- _clipOverride = _vm->_actorClipOverride;
-
- _auxBlock.reset();
-
_vm->_classData[_number] = (_vm->_game.version >= 7) ? _vm->_classData[0] : 0;
}
@@ -879,9 +881,9 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
_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.
+ // WORKAROUND: The green transparency of the tank in the Hall of Oddities
+ // is positioned one pixel too far to the left. This appears to be a bug
+ // in the original game as well.
if (_vm->_game.id == GID_SAMNMAX && newRoom == 16 && _number == 5 && dstX == 235 && dstY == 236)
dstX++;
@@ -904,7 +906,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
} else {
#ifdef ENABLE_HE
if (_vm->_game.heversion >= 71)
- ((ScummEngine_v71he *)_vm)->queueAuxBlock(this);
+ ((ScummEngine_v71he *)_vm)->queueAuxBlock((ActorHE *)this);
#endif
hideActor();
}
@@ -1208,6 +1210,10 @@ void Actor::hideActor() {
_cost.soundCounter = 0;
_needRedraw = false;
_needBgReset = true;
+}
+
+void ActorHE::hideActor() {
+ Actor::hideActor();
_auxBlock.reset();
}
@@ -1434,39 +1440,28 @@ void Actor::drawActorCostume(bool hitTestMode) {
}
setupActorScale();
+
+ BaseCostumeRenderer *bcr = _vm->_costumeRenderer;
+ prepareDrawActorCostume(bcr);
- BaseCostumeRenderer* bcr = _vm->_costumeRenderer;
-
- bcr->_actorID = _number;
-
- bcr->_actorX = _pos.x + _offsX;
- bcr->_actorY = _pos.y + _offsY - _elevation;
-
- if (_vm->_game.version <= 2) {
- bcr->_actorX *= V12_X_MULTIPLIER;
- bcr->_actorY *= V12_Y_MULTIPLIER;
+ // If the actor is partially hidden, redraw it next frame.
+ if (bcr->drawCostume(_vm->_virtscr[kMainVirtScreen], _vm->_gdi->_numStrips, this, _drawToBackBuf) & 1) {
+ _needRedraw = (_vm->_game.version <= 6);
}
- bcr->_actorX -= _vm->_virtscr[kMainVirtScreen].xstart;
- if (_vm->_game.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->_game.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->_game.version == 2)
- bcr->_actorX += 8;
+ if (!hitTestMode) {
+ // Record the vertical extent of the drawn actor
+ _top = bcr->_draw_top;
+ _bottom = bcr->_draw_bottom;
}
+}
- bcr->_clipOverride = _clipOverride;
+
+void Actor::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
+
+ bcr->_actorID = _number;
+ bcr->_actorX = _pos.x - _vm->_virtscr[kMainVirtScreen].xstart;
+ bcr->_actorY = _pos.y - _elevation;
if (_vm->_game.version == 4 && (_boxscale & 0x8000)) {
bcr->_scaleX = bcr->_scaleY = _vm->getScaleFromSlot((_boxscale & 0x7fff) + 1, _pos.x, _pos.y);
@@ -1478,8 +1473,6 @@ void Actor::drawActorCostume(bool hitTestMode) {
bcr->_shadow_mode = _shadowMode;
if (_vm->_game.version >= 5 && _vm->_game.heversion == 0) {
bcr->_shadow_table = _vm->_shadowPalette;
- } else if (_vm->_game.heversion == 70) {
- bcr->_shadow_table = _vm->_HEV7ActorPalette;
}
bcr->setCostume(_costume, _heXmapNum);
@@ -1510,6 +1503,19 @@ void Actor::drawActorCostume(bool hitTestMode) {
bcr->_draw_top = 0x7fffffff;
bcr->_draw_bottom = 0;
+}
+
+void ActorHE::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
+ Actor::prepareDrawActorCostume(bcr);
+
+ bcr->_actorX += _heOffsX;
+ bcr->_actorY += _heOffsY;
+
+ bcr->_clipOverride = _clipOverride;
+
+ if (_vm->_game.heversion == 70) {
+ bcr->_shadow_table = _vm->_HEV7ActorPalette;
+ }
bcr->_skipLimbs = (_heSkipLimbs != 0);
bcr->_paletteNum = _hePaletteNum;
@@ -1530,16 +1536,36 @@ void Actor::drawActorCostume(bool hitTestMode) {
}
}
_heNoTalkAnimation = 0;
+}
- // If the actor is partially hidden, redraw it next frame.
- if (bcr->drawCostume(_vm->_virtscr[kMainVirtScreen], _vm->_gdi->_numStrips, this, _drawToBackBuf) & 1) {
- _needRedraw = (_vm->_game.version <= 6);
+void Actor_v2::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
+ Actor::prepareDrawActorCostume(bcr);
+
+ bcr->_actorX = _pos.x;
+ bcr->_actorY = _pos.y - _elevation;
+
+ if (_vm->_game.version <= 2) {
+ bcr->_actorX *= V12_X_MULTIPLIER;
+ bcr->_actorY *= V12_Y_MULTIPLIER;
}
+ bcr->_actorX -= _vm->_virtscr[kMainVirtScreen].xstart;
- if (!hitTestMode) {
- // Record the vertical extent of the drawn actor
- _top = bcr->_draw_top;
- _bottom = bcr->_draw_bottom;
+ if (_vm->_game.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->_game.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->_game.version == 2)
+ bcr->_actorX += 8;
}
}
@@ -1611,13 +1637,15 @@ void Actor::startAnimActor(int f) {
if (isInCurrentRoom() && _costume != 0) {
_animProgress = 0;
- _cost.animCounter = 0;
_needRedraw = true;
+ _cost.animCounter = 0;
// 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->_game.version >= 3 && f == _initFrame) {
_cost.reset();
- _auxBlock.reset();
+ if (_vm->_game.heversion != 0) {
+ ((ActorHE *)this)->_auxBlock.reset();
+ }
}
_vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
_frame = f;
@@ -1758,7 +1786,7 @@ void ScummEngine::resetActorBgs() {
clearGfxUsageBit(strip, USAGE_BIT_DIRTY);
clearGfxUsageBit(strip, USAGE_BIT_RESTORED);
for (j = 1; j < _numActors; j++) {
- if (_actors[j]->_heFlags & 1)
+ if (_game.heversion != 0 && ((ActorHE *)_actors[j])->_heFlags & 1)
continue;
if (testGfxUsageBit(strip, j) &&
@@ -1776,7 +1804,7 @@ void ScummEngine::resetActorBgs() {
}
// HE specific
-void Actor::drawActorToBackBuf(int x, int y) {
+void ActorHE::drawActorToBackBuf(int x, int y) {
int curTop = _top;
int curBottom = _bottom;
@@ -1936,7 +1964,8 @@ void ScummEngine::actorTalk(const byte *msg) {
stopTalk();
}
setTalkingActor(a->_number);
- a->_heTalking = true;
+ if (_game.heversion != 0)
+ ((ActorHE *)a)->_heTalking = true;
if (!_string[0].no_talk_anim) {
a->runActorTalkScript(a->_talkStartFrame);
_useTalkAnims = true;
@@ -2009,7 +2038,8 @@ void ScummEngine::stopTalk() {
}
if (_game.version <= 7 && _game.heversion == 0)
setTalkingActor(0xFF);
- a->_heTalking = false;
+ if (_game.heversion != 0)
+ ((ActorHE *)a)->_heTalking = false;
}
if (_game.id == GID_DIG || _game.id == GID_CMI) {
@@ -2035,9 +2065,7 @@ void ScummEngine::stopTalk() {
#pragma mark -
-void Actor::setActorCostume(int c) {
- int i;
-
+void ActorHE::setActorCostume(int c) {
if (_vm->_game.heversion >= 61 && (c == -1 || c == -2)) {
_heSkipLimbs = (c == -1);
_needRedraw = true;
@@ -2049,27 +2077,43 @@ void Actor::setActorCostume(int c) {
if (_vm->_game.heversion == 61)
c &= 0xff;
- _costumeNeedsInit = true;
-
if (_vm->_game.features & GF_NEW_COSTUMES) {
- memset(_animVariable, 0, sizeof(_animVariable));
-
#ifdef ENABLE_HE
if (_vm->_game.heversion >= 71)
((ScummEngine_v71he *)_vm)->queueAuxBlock(this);
#endif
+ _auxBlock.reset();
+ if (_visible) {
+ if (_vm->_game.heversion >= 60)
+ _needRedraw = true;
+ }
+ }
+
+ Actor::setActorCostume(c);
+
+ if (_vm->_game.heversion >= 71 && _vm->getTalkingActor() == _number) {
+ if (_vm->_game.heversion <= 95 || (_vm->_game.heversion >= 98 && _vm->VAR(_vm->VAR_SKIP_RESET_TALK_ACTOR) == 0)) {
+ _vm->setTalkingActor(0);
+ }
+ }
+}
+
+void Actor::setActorCostume(int c) {
+ int i;
+
+ _costumeNeedsInit = true;
+
+ if (_vm->_game.features & GF_NEW_COSTUMES) {
+ memset(_animVariable, 0, sizeof(_animVariable));
_costume = c;
_cost.reset();
- _auxBlock.reset();
if (_visible) {
if (_costume) {
_vm->ensureResourceLoaded(rtCostume, _costume);
}
startAnimActor(_initFrame);
- if (_vm->_game.heversion >= 60)
- _needRedraw = true;
}
} else {
if (_visible) {
@@ -2104,12 +2148,6 @@ void Actor::setActorCostume(int c) {
for (i = 0; i < 32; i++)
_palette[i] = 0xFF;
}
-
- if (_vm->_game.heversion >= 71 && _vm->getTalkingActor() == _number) {
- if (_vm->_game.heversion <= 95 || (_vm->_game.heversion >= 98 && _vm->VAR(_vm->VAR_SKIP_RESET_TALK_ACTOR) == 0)) {
- _vm->setTalkingActor(0);
- }
- }
}
static const char* v0ActorNames[7] = {
@@ -2245,7 +2283,7 @@ bool Actor_v2::isPlayer() {
return _vm->VAR(42) <= _number && _number <= _vm->VAR(43);
}
-void Actor::setHEFlag(int bit, int set) {
+void ActorHE::setHEFlag(int bit, int set) {
// Note that condition is inverted
if (!set) {
_heFlags |= bit;
@@ -2254,7 +2292,7 @@ void Actor::setHEFlag(int bit, int set) {
}
}
-void Actor::setUserCondition(int slot, int set) {
+void ActorHE::setUserCondition(int slot, int set) {
const int condMaskCode = (_vm->_game.heversion >= 85) ? 0x1FFF : 0x3FF;
assertRange(1, slot, 32, "setUserCondition: Condition");
if (set == 0) {
@@ -2269,12 +2307,12 @@ void Actor::setUserCondition(int slot, int set) {
}
}
-bool Actor::isUserConditionSet(int slot) const {
+bool ActorHE::isUserConditionSet(int slot) const {
assertRange(1, slot, 32, "isUserConditionSet: Condition");
return (_heCondMask & (1 << (slot + 0xF))) != 0;
}
-void Actor::setTalkCondition(int slot) {
+void ActorHE::setTalkCondition(int slot) {
const int condMaskCode = (_vm->_game.heversion >= 85) ? 0x1FFF : 0x3FF;
assertRange(1, slot, 32, "setTalkCondition: Condition");
_heCondMask = (_heCondMask & ~condMaskCode) | 1;
@@ -2288,7 +2326,7 @@ void Actor::setTalkCondition(int slot) {
}
}
-bool Actor::isTalkConditionSet(int slot) const {
+bool ActorHE::isTalkConditionSet(int slot) const {
assertRange(1, slot, 32, "isTalkConditionSet: Condition");
return (_heCondMask & (1 << (slot - 1))) != 0;
}
@@ -2311,10 +2349,10 @@ void ScummEngine_v71he::postProcessAuxQueue() {
for (int i = 0; i < _auxEntriesNum; ++i) {
AuxEntry *ae = &_auxEntries[i];
if (ae->actorNum != -1) {
- Actor *a = derefActor(ae->actorNum, "postProcessAuxQueue");
+ ActorHE *a = (ActorHE *)derefActor(ae->actorNum, "postProcessAuxQueue");
const uint8 *cost = getResourceAddress(rtCostume, a->_costume);
- int dy = a->_offsY + a->getPos().y;
- int dx = a->_offsX + a->getPos().x;
+ int dy = a->_heOffsY + a->getPos().y;
+ int dx = a->_heOffsX + a->getPos().x;
if (_game.heversion >= 72)
dy -= a->getElevation();
@@ -2378,7 +2416,7 @@ void ScummEngine_v71he::postProcessAuxQueue() {
_auxEntriesNum = 0;
}
-void ScummEngine_v71he::queueAuxBlock(Actor *a) {
+void ScummEngine_v71he::queueAuxBlock(ActorHE *a) {
if (!a->_auxBlock.visible)
return;
@@ -2401,8 +2439,8 @@ 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, _heOffsX, sleInt16, VER(32)),
+ MKLINE(Actor, _heOffsY, sleInt16, VER(32)),
MKLINE(Actor, _top, sleInt16, VER(8)),
MKLINE(Actor, _bottom, sleInt16, VER(8)),
MKLINE(Actor, _elevation, sleInt16, VER(8)),
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 30dc7789d6..3e8fe6626b 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -61,6 +61,7 @@ struct CostumeData {
uint16 end[16];
uint16 frame[16];
+ /* HE specific */
uint16 heJumpOffsetTable[16];
uint16 heJumpCountTable[16];
uint32 heCondMaskTable[16];
@@ -95,10 +96,6 @@ protected:
Common::Point _pos;
public:
- /** HE specific: This rect is used to clip actor drawing. */
- Common::Rect _clipOverride;
-
- int _offsX, _offsY;
int _top, _bottom;
uint _width;
byte _number;
@@ -137,22 +134,11 @@ public:
CostumeData _cost;
/* HE specific */
- bool _heNoTalkAnimation;
+ int _heOffsX, _heOffsY;
bool _heSkipLimbs;
- bool _heTalking;
uint32 _heCondMask;
uint32 _hePaletteNum;
uint32 _heXmapNum;
- byte _heFlags;
-
- AuxBlock _auxBlock;
-
- struct {
- int16 posX;
- int16 posY;
- int16 color;
- byte sentence[128];
- } _heTalkQueue[16];
protected:
struct ActorWalkData {
@@ -187,7 +173,7 @@ public:
virtual ~Actor() {}
//protected:
- void hideActor();
+ virtual void hideActor();
void showActor();
virtual void initActor(int mode);
@@ -223,10 +209,10 @@ public:
void faceToObject(int obj);
void turnToDirection(int newdir);
virtual void walkActor();
- void drawActorToBackBuf(int x, int y);
void drawActorCostume(bool hitTestMode = false);
+ virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
void animateCostume();
- void setActorCostume(int c);
+ virtual void setActorCostume(int c);
void animateLimb(int limb, int f);
@@ -317,6 +303,27 @@ public:
void classChanged(int cls, bool value);
+ // Used by the save/load system:
+ void saveLoadWithSerializer(Serializer *ser);
+
+protected:
+ bool isInClass(int cls);
+
+ virtual bool isPlayer();
+
+ bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath);
+};
+
+class ActorHE : public Actor {
+public:
+ ActorHE(ScummEngine *scumm, int id) : Actor(scumm, id) {}
+
+ virtual void initActor(int mode);
+
+ virtual void hideActor();
+
+ void drawActorToBackBuf(int x, int y);
+
void setHEFlag(int bit, int set);
void setUserCondition(int slot, int set);
@@ -325,15 +332,26 @@ public:
void setTalkCondition(int slot);
bool isTalkConditionSet(int slot) const;
- // Used by the save/load system:
- void saveLoadWithSerializer(Serializer *ser);
+public:
+ /** This rect is used to clip actor drawing. */
+ Common::Rect _clipOverride;
-protected:
- bool isInClass(int cls);
+ bool _heNoTalkAnimation;
+ bool _heTalking;
+ byte _heFlags;
- virtual bool isPlayer();
+ AuxBlock _auxBlock;
- bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath);
+ struct {
+ int16 posX;
+ int16 posY;
+ int16 color;
+ byte sentence[128];
+ } _heTalkQueue[16];
+
+
+ virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
+ virtual void setActorCostume(int c);
};
class Actor_v3 : public Actor {
@@ -357,6 +375,7 @@ public:
protected:
virtual bool isPlayer();
+ virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
};
class ActorC64 : public Actor_v2 {
diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp
index 8e8fff938d..19c7c3320b 100644
--- a/engines/scumm/akos.cpp
+++ b/engines/scumm/akos.cpp
@@ -1664,28 +1664,28 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
akos_queCommand(9, a, a->_sound[a->getAnimVar(GB(2))], 0);
continue;
case AKC_C045:
- a->setUserCondition(GB(3), a->getAnimVar(GB(4)));
+ ((ActorHE *)a)->setUserCondition(GB(3), a->getAnimVar(GB(4)));
continue;
case AKC_C046:
- a->setAnimVar(GB(4), a->isUserConditionSet(GB(3)));
+ a->setAnimVar(GB(4), ((ActorHE *)a)->isUserConditionSet(GB(3)));
continue;
case AKC_C047:
- a->setTalkCondition(GB(3));
+ ((ActorHE *)a)->setTalkCondition(GB(3));
continue;
case AKC_C048:
- a->setAnimVar(GB(4), a->isTalkConditionSet(GB(3)));
+ a->setAnimVar(GB(4), ((ActorHE *)a)->isTalkConditionSet(GB(3)));
continue;
case AKC_C0A0:
akos_queCommand(8, a, GB(2), 0);
continue;
case AKC_C0A1:
- if (a->_heTalking != 0) {
+ if (((ActorHE *)a)->_heTalking != 0) {
curpos = GUW(2);
break;
}
continue;
case AKC_C0A2:
- if (a->_heTalking == 0) {
+ if (((ActorHE *)a)->_heTalking == 0) {
curpos = GUW(2);
break;
}
@@ -1763,8 +1763,8 @@ void ScummEngine_v6::akos_processQueue() {
a->_forceClip = param_1;
break;
case 6:
- a->_offsX = param_1;
- a->_offsY = param_2;
+ a->_heOffsX = param_1;
+ a->_heOffsY = param_2;
break;
case 7:
#ifdef ENABLE_HE
@@ -1775,13 +1775,13 @@ void ScummEngine_v6::akos_processQueue() {
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;
+ a->_talkPosX = ((ActorHE *)a)->_heTalkQueue[param_1].posX;
+ a->_talkPosY = ((ActorHE *)a)->_heTalkQueue[param_1].posY;
+ a->_talkColor = ((ActorHE *)a)->_heTalkQueue[param_1].color;
_string[0].loadDefault();
_string[0].color = a->_talkColor;
- actorTalk(a->_heTalkQueue[param_1].sentence);
+ actorTalk(((ActorHE *)a)->_heTalkQueue[param_1].sentence);
break;
case 9:
@@ -1825,8 +1825,8 @@ void ScummEngine_v7::akos_processQueue() {
a->_forceClip = param_1;
break;
case 6:
- a->_offsX = param_1;
- a->_offsY = param_2;
+ a->_heOffsX = param_1;
+ a->_heOffsY = param_2;
break;
case 7:
if (param_1 != 0) {
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 0fa8b579ca..1e632a034e 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -544,8 +544,8 @@ bool ScummEngine::checkXYInBoxBounds(int boxnum, int x, int y) {
// Corner case: If the box is a simple line segment, we consider the
// point to be contained "in" (or rather, lying on) the line if it
// is very close to its projection to the line segment.
- if (box.ul == box.ur && box.lr == box.ll ||
- box.ul == box.ll && box.ur == box.lr) {
+ if ((box.ul == box.ur && box.lr == box.ll) ||
+ (box.ul == box.ll && box.ur == box.lr)) {
Common::Point tmp;
tmp = closestPtOnLine(box.ul, box.lr, p);
@@ -803,8 +803,8 @@ bool Actor::findPathTowards(byte box1nr, byte box2nr, byte box3nr, Common::Point
}
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) {
+ ((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)
@@ -858,8 +858,8 @@ bool Actor::findPathTowards(byte box1nr, byte box2nr, byte box3nr, Common::Point
}
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) {
+ ((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)
@@ -1074,8 +1074,8 @@ bool ScummEngine::areBoxesNeighbours(int box1nr, int box2nr) {
}
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) {
+ ((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;
}
@@ -1103,8 +1103,8 @@ bool ScummEngine::areBoxesNeighbours(int box1nr, int box2nr) {
}
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) {
+ ((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;
diff --git a/engines/scumm/charset-fontdata.cpp b/engines/scumm/charset-fontdata.cpp
index 6a45d53139..e9a496f6ed 100644
--- a/engines/scumm/charset-fontdata.cpp
+++ b/engines/scumm/charset-fontdata.cpp
@@ -1070,6 +1070,7 @@ CharsetRendererV2::CharsetRendererV2(ScummEngine *vm, Common::Language language)
: CharsetRendererV3(vm) {
_fontHeight = 8;
+ _curId = 0;
switch (language) {
case Common::DE_DEU:
diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 5a45fb7da9..609aca996d 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -49,7 +49,7 @@ void ScummEngine::loadCJKFont() {
Common::File fp;
_useCJKMode = false;
_textSurfaceMultiplier = 1;
- _newLineCharacter = 0xfe;
+ _newLineCharacter = 0;
if (_game.version <= 5 && _game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) { // FM-TOWNS v3 / v5 Kanji
int numChar = 256 * 32;
@@ -277,7 +277,7 @@ CharsetRenderer::CharsetRenderer(ScummEngine *vm) {
_disableOffsX = false;
_vm = vm;
- _curId = 0;
+ _curId = -1;
}
CharsetRenderer::~CharsetRenderer() {
@@ -289,7 +289,10 @@ CharsetRendererCommon::CharsetRendererCommon(ScummEngine *vm)
_shadowColor = 0;
}
-void CharsetRendererCommon::setCurID(byte id) {
+void CharsetRendererCommon::setCurID(int32 id) {
+ if (id == -1)
+ return;
+
assertRange(0, id, _vm->_numCharsets - 1, "charset");
_curId = id;
@@ -308,7 +311,10 @@ void CharsetRendererCommon::setCurID(byte id) {
_numChars = READ_LE_UINT16(_fontPtr + 2);
}
-void CharsetRendererV3::setCurID(byte id) {
+void CharsetRendererV3::setCurID(int32 id) {
+ if (id == -1)
+ return;
+
assertRange(0, id, _vm->_numCharsets - 1, "charset");
_curId = id;
@@ -668,7 +674,8 @@ void CharsetRenderer::translateColor() {
void CharsetRenderer::saveLoadWithSerializer(Serializer *ser) {
static const SaveLoadEntry charsetRendererEntries[] = {
- MKLINE(CharsetRenderer, _curId, sleByte, VER(73)),
+ MKLINE_OLD(CharsetRenderer, _curId, sleByte, VER(73), VER(73)),
+ MKLINE(CharsetRenderer, _curId, sleInt32, VER(74)),
MKLINE(CharsetRenderer, _color, sleByte, VER(73)),
MKEND()
};
@@ -988,7 +995,10 @@ CharsetRendererNut::~CharsetRendererNut() {
}
}
-void CharsetRendererNut::setCurID(byte id) {
+void CharsetRendererNut::setCurID(int32 id) {
+ if (id == -1)
+ return;
+
int numFonts = ((_vm->_game.id == GID_CMI) && (_vm->_game.features & GF_DEMO)) ? 4 : 5;
assert(id < numFonts);
_curId = id;
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index b62dbc6006..dbe02fc8fc 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -67,7 +67,7 @@ public:
protected:
ScummEngine *_vm;
- byte _curId;
+ int32 _curId;
public:
CharsetRenderer(ScummEngine *vm);
@@ -80,7 +80,7 @@ public:
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
void translateColor();
- virtual void setCurID(byte id) = 0;
+ virtual void setCurID(int32 id) = 0;
int getCurID() { return _curId; }
virtual int getFontHeight() = 0;
@@ -113,7 +113,7 @@ protected:
public:
CharsetRendererCommon(ScummEngine *vm);
- void setCurID(byte id);
+ void setCurID(int32 id);
int getFontHeight();
};
@@ -142,7 +142,7 @@ protected:
public:
CharsetRendererNES(ScummEngine *vm) : CharsetRendererCommon(vm) {}
- void setCurID(byte id) {}
+ void setCurID(int32 id) {}
void printChar(int chr, bool ignoreCharsetMask);
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
@@ -159,7 +159,7 @@ public:
void printChar(int chr, bool ignoreCharsetMask);
void drawChar(int chr, const Graphics::Surface &s, int x, int y);
- void setCurID(byte id);
+ void setCurID(int32 id);
void setColor(byte color);
int getCharWidth(byte chr);
};
@@ -168,7 +168,7 @@ class CharsetRendererV2 : public CharsetRendererV3 {
public:
CharsetRendererV2(ScummEngine *vm, Common::Language language);
- void setCurID(byte id) {}
+ void setCurID(int32 id) {}
int getCharWidth(byte chr) { return 8; }
};
@@ -184,7 +184,7 @@ public:
void printChar(int chr, bool ignoreCharsetMask);
- void setCurID(byte id);
+ void setCurID(int32 id);
int getFontHeight();
int getCharHeight(byte chr);
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 68d3010199..d3397fe208 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -177,7 +177,7 @@ static Common::String generateFilenameForDetection(const char *pattern, Filename
}
struct DetectorDesc {
- FilesystemNode node;
+ Common::FilesystemNode node;
Common::String md5;
const MD5Table *md5Entry; // Entry of the md5 table corresponding to this file, if any.
};
@@ -191,8 +191,8 @@ static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Com
// when performing the matching. The first match is returned, so if you
// search for "resource" and two nodes "RESOURE and "resource" are present,
// the first match is used.
-static bool searchFSNode(const FSList &fslist, const Common::String &name, FilesystemNode &result) {
- for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+static bool searchFSNode(const Common::FSList &fslist, const Common::String &name, Common::FilesystemNode &result) {
+ for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
if (!scumm_stricmp(file->getName().c_str(), name.c_str())) {
result = *file;
return true;
@@ -202,7 +202,7 @@ static bool searchFSNode(const FSList &fslist, const Common::String &name, Files
}
// The following function tries to detect the language for COMI and DIG
-static Common::Language detectLanguage(const FSList &fslist, byte id) {
+static Common::Language detectLanguage(const Common::FSList &fslist, byte id) {
assert(id == GID_CMI || id == GID_DIG);
// Check for LANGUAGE.BND (Dig) resp. LANGUAGE.TAB (CMI).
@@ -212,14 +212,14 @@ static Common::Language detectLanguage(const FSList &fslist, byte id) {
// switch to MD5 based detection).
const char *filename = (id == GID_CMI) ? "LANGUAGE.TAB" : "LANGUAGE.BND";
Common::File tmp;
- FilesystemNode langFile;
+ Common::FilesystemNode langFile;
if (!searchFSNode(fslist, filename, langFile) || !tmp.open(langFile)) {
// try loading in RESOURCE sub dir...
- FilesystemNode resDir;
- FSList tmpList;
+ Common::FilesystemNode resDir;
+ Common::FSList tmpList;
if (searchFSNode(fslist, "RESOURCE", resDir)
&& resDir.isDirectory()
- && resDir.getChildren(tmpList, FilesystemNode::kListFilesOnly)
+ && resDir.getChildren(tmpList, Common::FilesystemNode::kListFilesOnly)
&& searchFSNode(tmpList, filename, langFile)) {
tmp.open(langFile);
}
@@ -270,7 +270,7 @@ static Common::Language detectLanguage(const FSList &fslist, byte id) {
}
-static void computeGameSettingsFromMD5(const FSList &fslist, const GameFilenamePattern *gfp, const MD5Table *md5Entry, DetectorResult &dr) {
+static void computeGameSettingsFromMD5(const Common::FSList &fslist, const GameFilenamePattern *gfp, const MD5Table *md5Entry, DetectorResult &dr) {
dr.language = md5Entry->language;
dr.extra = md5Entry->extra;
@@ -315,12 +315,12 @@ static void computeGameSettingsFromMD5(const FSList &fslist, const GameFilenameP
}
}
-static void detectGames(const FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) {
+static void detectGames(const Common::FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) {
DescMap fileMD5Map;
DetectorResult dr;
char md5str[32+1];
- for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
if (!file->isDirectory()) {
DetectorDesc d;
d.node = *file;
@@ -674,15 +674,30 @@ public:
virtual const char *getName() const;
virtual const char *getCopyright() const;
+ virtual bool hasFeature(MetaEngineFeature f) const;
virtual GameList getSupportedGames() const;
virtual GameDescriptor findGame(const char *gameid) const;
- virtual GameList detectGames(const FSList &fslist) const;
-
+ virtual GameList detectGames(const Common::FSList &fslist) const;
+
virtual PluginError createInstance(OSystem *syst, Engine **engine) const;
virtual SaveStateList listSaves(const char *target) const;
+ virtual void removeSaveState(const char *target, int slot) const;
+ virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
};
+bool ScummMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsRTL) ||
+ (f == kSupportsListSaves) ||
+ (f == kSupportsDirectLoad) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSupportsMetaInfos) ||
+ (f == kSupportsThumbnails) ||
+ (f == kSupportsSaveDate) ||
+ (f == kSupportsSavePlayTime);
+}
+
GameList ScummMetaEngine::getSupportedGames() const {
return GameList(gameDescriptions);
}
@@ -691,8 +706,7 @@ GameDescriptor ScummMetaEngine::findGame(const char *gameid) const {
return Common::AdvancedDetector::findGameID(gameid, gameDescriptions, obsoleteGameIDsTable);
}
-
-GameList ScummMetaEngine::detectGames(const FSList &fslist) const {
+GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
GameList detectedGames;
Common::List<DetectorResult> results;
@@ -769,9 +783,9 @@ PluginError ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) cons
}
// Fetch the list of files in the current directory
- FSList fslist;
- FilesystemNode dir(ConfMan.get("path"));
- if (!dir.getChildren(fslist, FilesystemNode::kListFilesOnly)) {
+ Common::FSList fslist;
+ Common::FilesystemNode dir(ConfMan.get("path"));
+ if (!dir.getChildren(fslist, Common::FilesystemNode::kListFilesOnly)) {
return kInvalidPathError;
}
@@ -820,9 +834,10 @@ PluginError ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) cons
// unknown MD5, or with a medium debug level in case of a known MD5 (for
// debugging purposes).
if (!findInMD5Table(res.md5.c_str())) {
- printf("Your game version appears to be unknown. Please, report the following\n");
- printf("data to the ScummVM team along with name of the game you tried to add\n");
- printf("and its version/language/etc.:\n");
+ printf("Your game version appears to be unknown. If this is *NOT* a fan-modified\n");
+ printf("version (in particular, not a fan-made translation), please, report the\n");
+ printf("following data to the ScummVM team along with name of the game you tried\n");
+ printf("to add and its version/language/etc.:\n");
printf(" SCUMM gameid '%s', file '%s', MD5 '%s'\n\n",
res.game.gameid,
@@ -966,6 +981,53 @@ SaveStateList ScummMetaEngine::listSaves(const char *target) const {
return saveList;
}
+void ScummMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
+ g_system->getSavefileManager()->removeSavefile(filename.c_str());
+}
+
+SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (!in)
+ return SaveStateDescriptor();
+
+ Common::String saveDesc;
+ Scumm::getSavegameName(in, saveDesc, 0); // FIXME: heversion?!?
+ delete in;
+
+ // TODO: Cleanup
+ Graphics::Surface *thumbnail = ScummEngine::loadThumbnailFromSlot(target, slot);
+
+ SaveStateDescriptor desc(slot, saveDesc, filename);
+ desc.setDeletableFlag(true);
+ desc.setThumbnail(thumbnail);
+
+ InfoStuff infos;
+ memset(&infos, 0, sizeof(infos));
+ if (ScummEngine::loadInfosFromSlot(target, slot, &infos)) {
+ int day = (infos.date >> 24) & 0xFF;
+ int month = (infos.date >> 16) & 0xFF;
+ int year = infos.date & 0xFFFF;
+
+ desc.setSaveDate(year, month, day);
+
+ int hour = (infos.time >> 8) & 0xFF;
+ int minutes = infos.time & 0xFF;
+
+ desc.setSaveTime(hour, minutes);
+
+ minutes = infos.playtime / 60;
+ hour = minutes / 60;
+ minutes %= 60;
+
+ desc.setPlayTime(hour, minutes);
+ }
+
+ return desc;
+}
+
#if PLUGIN_ENABLED_DYNAMIC(SCUMM)
REGISTER_PLUGIN_DYNAMIC(SCUMM, PLUGIN_TYPE_ENGINE, ScummMetaEngine);
#else
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 324cc91e78..8d70afecf2 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -472,12 +472,14 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "fbear", "fbdemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "fbear", "Fatty Bear Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "fbear", "Fatty Bear", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "fbear", "jfbear", kGenHEPC, Common::JA_JPN, Common::kPlatform3DO, 0 },
{ "puttmoon", "puttmoon", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttmoon", "moondemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttmoon", "Putt-Putt Moon Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttmoon", "Putt-Putt Moon", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
+ { "puttputt", "jputtputt", kGenHEPC, Common::JA_JPN, Common::kPlatform3DO, 0 },
{ "puttputt", "puttputt", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttputt", "puttdemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttputt", "Putt-Putt's Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
@@ -711,6 +713,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "puttrace", "racedemo", kGenHEPC, UNK_LANG, UNK, 0 },
{ "puttrace", "RaceDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Rennen", kGenHEPC, Common::DE_DEU, UNK, 0 },
+ { "puttrace", "PouceCourse", kGenHEPC, Common::FR_FRA, UNK, 0 },
{ "puttrace", "Putt500", kGenHEPC, Common::NL_NLD, UNK, 0 },
{ "puttrace", "Putt500", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
{ "puttrace", "Putt500 demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 },
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index e4e2b2b620..799203abe7 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -244,9 +244,6 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel,
_list->setEditable(saveMode);
_list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
- _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
- _container->setHints(GUI::THEME_HINT_USE_SHADOW);
-
_gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10);
_date = new StaticTextWidget(this, 0, 0, 10, 10, "No date saved", kTextAlignCenter);
@@ -257,6 +254,9 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel,
new GUI::ButtonWidget(this, "scummsaveload_cancel", "Cancel", kCloseCmd, 0);
_chooseButton = new GUI::ButtonWidget(this, "scummsaveload_choose", buttonLabel, kChooseCmd, 0);
_chooseButton->setEnabled(false);
+
+ _container = new GUI::ContainerWidget(this, 0, 0, 10, 10);
+ _container->setHints(GUI::THEME_HINT_USE_SHADOW);
}
SaveLoadChooser::~SaveLoadChooser() {
@@ -364,62 +364,50 @@ void SaveLoadChooser::reflowLayout() {
void SaveLoadChooser::updateInfos(bool redraw) {
int selItem = _list->getSelected();
- Graphics::Surface *thumb;
- thumb = _vm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
+ Graphics::Surface *thumb = 0;
+ if (selItem >= 0 && !_list->getSelectedString().empty())
+ thumb = _vm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
if (thumb) {
_gfxWidget->setGfx(thumb);
_gfxWidget->useAlpha(256);
thumb->free();
+ delete thumb;
} else {
_gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB);
}
- delete thumb;
- if (redraw)
- _gfxWidget->draw();
-
InfoStuff infos;
memset(&infos, 0, sizeof(InfoStuff));
- char buffer[32];
- if (_vm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) {
+ if (selItem >= 0 && !_list->getSelectedString().empty()
+ && _vm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) {
+ char buffer[32];
snprintf(buffer, 32, "Date: %.2d.%.2d.%.4d",
(infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF,
infos.date & 0xFFFF);
_date->setLabel(buffer);
- if (redraw)
- _date->draw();
snprintf(buffer, 32, "Time: %.2d:%.2d",
(infos.time >> 8) & 0xFF, infos.time & 0xFF);
_time->setLabel(buffer);
- if (redraw)
- _time->draw();
int minutes = infos.playtime / 60;
int hours = minutes / 60;
minutes %= 60;
- snprintf(buffer, 32, "Playtime: %.2d:%.2d",
- hours & 0xFF, minutes & 0xFF);
+ snprintf(buffer, 32, "Playtime: %.2d:%.2d", hours, minutes);
_playtime->setLabel(buffer);
- if (redraw)
- _playtime->draw();
} else {
- snprintf(buffer, 32, "No date saved");
- _date->setLabel(buffer);
- if (redraw)
- _date->draw();
-
- snprintf(buffer, 32, "No time saved");
- _time->setLabel(buffer);
- if (redraw)
- _time->draw();
+ _date->setLabel("No date saved");
+ _time->setLabel("No time saved");
+ _playtime->setLabel("No playtime saved");
+ }
- snprintf(buffer, 32, "No playtime saved");
- _playtime->setLabel(buffer);
- if (redraw)
- _playtime->draw();
+ if (redraw) {
+ _gfxWidget->draw();
+ _date->draw();
+ _time->draw();
+ _playtime->draw();
}
}
@@ -442,7 +430,7 @@ Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
return descriptions;
}
-MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
+ScummMenuDialog::ScummMenuDialog(ScummEngine *scumm)
: ScummDialog("scummmain"), _vm(scumm) {
new GUI::ButtonWidget(this, "scummmain_resume", "Resume", kPlayCmd, 'P');
@@ -470,7 +458,7 @@ MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
_loadDialog = new SaveLoadChooser("Load game:", "Load", false, scumm);
}
-MainMenuDialog::~MainMenuDialog() {
+ScummMenuDialog::~ScummMenuDialog() {
delete _aboutDialog;
delete _optionsDialog;
#ifndef DISABLE_HELP
@@ -480,7 +468,7 @@ MainMenuDialog::~MainMenuDialog() {
delete _loadDialog;
}
-void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
+void ScummMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kSaveCmd:
save();
@@ -503,7 +491,7 @@ void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
break;
#endif
case kQuitCmd:
- _vm->_quit = true;
+ _vm->quitGame();
close();
break;
default:
@@ -511,7 +499,7 @@ void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
}
}
-void MainMenuDialog::save() {
+void ScummMenuDialog::save() {
int idx;
_saveDialog->setList(generateSavegameList(_vm, true));
idx = _saveDialog->runModal();
@@ -530,7 +518,7 @@ void MainMenuDialog::save() {
}
}
-void MainMenuDialog::load() {
+void ScummMenuDialog::load() {
int idx;
_loadDialog->setList(generateSavegameList(_vm, false));
idx = _loadDialog->runModal();
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index 0d04d8faea..3837787a3b 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -82,10 +82,10 @@ public:
virtual void reflowLayout();
};
-class MainMenuDialog : public ScummDialog {
+class ScummMenuDialog : public ScummDialog {
public:
- MainMenuDialog(ScummEngine *scumm);
- ~MainMenuDialog();
+ ScummMenuDialog(ScummEngine *scumm);
+ ~ScummMenuDialog();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
protected:
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index bf13308a0c..f258ddd420 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -42,9 +42,9 @@ void ScummFile::setEnc(byte value) {
_encbyte = value;
}
-void ScummFile::setSubfileRange(uint32 start, uint32 len) {
+void ScummFile::setSubfileRange(int32 start, int32 len) {
// TODO: Add sanity checks
- const uint32 fileSize = File::size();
+ const int32 fileSize = File::size();
assert(start <= fileSize);
assert(start + len <= fileSize);
_subFileStart = start;
@@ -125,19 +125,19 @@ bool ScummFile::openSubFile(const Common::String &filename) {
}
-bool ScummFile::eof() {
- return _subFileLen ? (pos() >= _subFileLen) : File::eof();
+bool ScummFile::eos() {
+ return _subFileLen ? (pos() >= _subFileLen) : File::eos(); // FIXME
}
-uint32 ScummFile::pos() {
+int32 ScummFile::pos() {
return File::pos() - _subFileStart;
}
-uint32 ScummFile::size() {
+int32 ScummFile::size() {
return _subFileLen ? _subFileLen : File::size();
}
-void ScummFile::seek(int32 offs, int whence) {
+bool ScummFile::seek(int32 offs, int whence) {
if (_subFileLen) {
// Constrain the seek to the subfile
switch (whence) {
@@ -154,7 +154,7 @@ void ScummFile::seek(int32 offs, int whence) {
assert((int32)_subFileStart <= offs && offs <= (int32)(_subFileStart + _subFileLen));
whence = SEEK_SET;
}
- File::seek(offs, whence);
+ return File::seek(offs, whence);
}
uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
@@ -162,12 +162,12 @@ uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
if (_subFileLen) {
// Limit the amount we read by the subfile boundaries.
- const uint32 curPos = pos();
+ const int32 curPos = pos();
assert(_subFileLen >= curPos);
- uint32 newPos = curPos + dataSize;
+ int32 newPos = curPos + dataSize;
if (newPos > _subFileLen) {
dataSize = _subFileLen - curPos;
- _ioFailed = true;
+ _myIoFailed = true;
}
}
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index a2695cac59..336f3cde12 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -39,32 +39,37 @@ public:
virtual bool open(const Common::String &filename) = 0;
virtual bool openSubFile(const Common::String &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 bool eos() = 0;
+ virtual int32 pos() = 0;
+ virtual int32 size() = 0;
+ virtual bool seek(int32 offs, int whence = SEEK_SET) = 0;
virtual uint32 read(void *dataPtr, uint32 dataSize) = 0;
};
class ScummFile : public BaseScummFile {
private:
byte _encbyte;
- uint32 _subFileStart;
- uint32 _subFileLen;
+ int32 _subFileStart;
+ int32 _subFileLen;
+ bool _myIoFailed;
+
+ void setSubfileRange(int32 start, int32 len);
+ void resetSubfile();
+
public:
ScummFile();
void setEnc(byte value);
- void setSubfileRange(uint32 start, uint32 len);
- void resetSubfile();
-
bool open(const Common::String &filename);
bool openSubFile(const Common::String &filename);
- bool eof();
- uint32 pos();
- uint32 size();
- void seek(int32 offs, int whence = SEEK_SET);
+ bool ioFailed() const { return _myIoFailed || BaseScummFile::ioFailed(); }
+ void clearIOFailed() { _myIoFailed = false; BaseScummFile::clearIOFailed(); }
+
+ bool eos();
+ int32 pos();
+ int32 size();
+ bool seek(int32 offs, int whence = SEEK_SET);
uint32 read(void *dataPtr, uint32 dataSize);
};
@@ -106,10 +111,10 @@ public:
bool openSubFile(const Common::String &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); }
+ bool eos() { return _stream->eos(); }
+ int32 pos() { return _stream->pos(); }
+ int32 size() { return _stream->size(); }
+ bool seek(int32 offs, int whence = SEEK_SET) { return _stream->seek(offs, whence); }
uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
};
diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp
index 8325436f87..0ddbd0b3ee 100644
--- a/engines/scumm/file_nes.cpp
+++ b/engines/scumm/file_nes.cpp
@@ -1124,8 +1124,7 @@ bool ScummNESFile::generateResource(int res) {
write_byte(&out, 0xD1);
write_byte(&out, 0xF5);
- if (_stream)
- delete _stream;
+ delete _stream;
_stream = new Common::MemoryReadStream(_buf, bufsize);
@@ -1221,8 +1220,7 @@ bool ScummNESFile::generateIndex() {
for (i = 0; i < (int)sizeof(lfl_index); i++)
write_byte(&out, ((byte *)&lfl_index)[i]);
- if (_stream)
- delete _stream;
+ delete _stream;
_stream = new Common::MemoryReadStream(_buf, bufsize);
diff --git a/engines/scumm/file_nes.h b/engines/scumm/file_nes.h
index 4d2d6de275..f1a07f8085 100644
--- a/engines/scumm/file_nes.h
+++ b/engines/scumm/file_nes.h
@@ -68,10 +68,10 @@ public:
bool openSubFile(const Common::String &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); }
+ bool eos() { return _stream->eos(); }
+ int32 pos() { return _stream->pos(); }
+ int32 size() { return _stream->size(); }
+ bool seek(int32 offs, int whence = SEEK_SET) { return _stream->seek(offs, whence); }
uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); }
};
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 6c8d24d25a..4e8c22479d 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -22,7 +22,6 @@
*
*/
-
#include "common/system.h"
#include "scumm/scumm.h"
#include "scumm/actor.h"
@@ -46,7 +45,7 @@ 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);
-#ifndef ARM_USE_GFX_ASM
+#ifndef USE_ARM_GFX_ASM
static void copy8Col(byte *dst, int dstPitch, const byte *src, int height);
#endif
static void clear8Col(byte *dst, int dstPitch, int height);
@@ -577,15 +576,12 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
const byte *src = vs->getPixels(x, top);
int m = _textSurfaceMultiplier;
- byte *dst;
int vsPitch;
int pitch = vs->pitch;
if (_useCJKMode && _textSurfaceMultiplier == 2) {
- dst = _fmtownsBuf;
-
- scale2x(dst, _screenWidth * m, src, vs->pitch, width, height);
- src = dst;
+ scale2x(_fmtownsBuf, _screenWidth * m, src, vs->pitch, width, height);
+ src = _fmtownsBuf;
vsPitch = _screenWidth * m - width * m;
@@ -593,7 +589,6 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
vsPitch = vs->pitch - width;
}
- dst = _compositeBuf;
if (_game.version < 7) {
// For The Dig, FT and COMI, we just blit everything to the screen at once.
@@ -612,32 +607,37 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
assert(0 == (width & 3));
// Compose the text over the game graphics
-
- // TODO: Optimize this code. There are several things that come immediately to mind:
- // (1) Loop unrolling: We could read 4 or even 8 pixels at once, since everything is
- // a multiple of 8 here.
- // (2) More ASM versions (in particular, the ARM code for the NDS could be used on
- // all ARM systems, couldn't it?)
- // (3) Better encoding of the text surface data. This is the one with the biggest
- // potential.
- // (a) Keep an "isEmpty" marker for each pixel row in the _textSurface. The idea
- // is that most rows won't contain any text data, so we can just use memcpy.
- // (b) RLE encode the _textSurface row-wise. This is an improved variant of (a),
- // but also more complicated to implement, and incurs a bigger overhead when
- // writing to the text surface.
-#ifdef ARM_USE_GFX_ASM
- asmDrawStripToScreen(height, width, text, src, dst, vs->pitch, width, _textSurface.pitch);
+#ifdef USE_ARM_GFX_ASM
+ asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch);
#else
- for (int h = 0; h < height * m; ++h) {
- for (int w = 0; w < width * m; ++w) {
- byte tmp = *text++;
- if (tmp == CHARSET_MASK_TRANSPARENCY)
- tmp = *src;
- *dst++ = tmp;
- src++;
+ // We blit four pixels at a time, for improved performance.
+ const uint32 *src32 = (const uint32 *)src;
+ const uint32 *text32 = (const uint32 *)text;
+ uint32 *dst32 = (uint32 *)_compositeBuf;
+
+ vsPitch >>= 2;
+ const int textPitch = (_textSurface.pitch - width * m) >> 2;
+ for (int h = height * m; h > 0; --h) {
+ for (int w = width*m; w > 0; w-=4) {
+ uint32 temp = *text32++;
+
+ // Generate a byte mask for those text pixels (bytes) with
+ // value CHARSET_MASK_TRANSPARENCY. In the end, each byte
+ // in mask will be either equal to 0x00 or 0xFF.
+ // Doing it this way avoids branches and bytewise operations,
+ // at the cost of readability ;).
+ uint32 mask = temp ^ CHARSET_MASK_TRANSPARENCY_32;
+ mask = (((mask & 0x7f7f7f7f) + 0x7f7f7f7f) | mask) & 0x80808080;
+ mask = ((mask >> 7) + 0x7f7f7f7f) ^ 0x80808080;
+
+ // The following line is equivalent to this code:
+ // *dst32++ = (*src32++ & mask) | (temp & ~mask);
+ // However, some compilers can generate somewhat better
+ // machine code for this equivalent statement:
+ *dst32++ = ((temp ^ *src32++) & mask) ^ temp;
}
- src += vsPitch;
- text += _textSurface.pitch - width * m;
+ src32 += vsPitch;
+ text32 += textPitch;
}
#endif
src = _compositeBuf;
@@ -669,7 +669,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
x += 16;
while (x + width >= _screenWidth)
width -= 16;
- if (width < 0)
+ if (width <= 0)
return;
}
@@ -1078,7 +1078,7 @@ static void fill(byte *dst, int dstPitch, byte color, int w, int h) {
}
}
-#ifdef ARM_USE_GFX_ASM
+#ifdef USE_ARM_GFX_ASM
#define copy8Col(A,B,C,D) asmCopy8Col(A,B,C,D)
@@ -1098,7 +1098,7 @@ static void copy8Col(byte *dst, int dstPitch, const byte *src, int height) {
} while (--height);
}
-#endif /* ARM_USE_GFX_ASM */
+#endif /* USE_ARM_GFX_ASM */
static void clear8Col(byte *dst, int dstPitch, int height) {
do {
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index e03fdd1c53..e4c1054450 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -174,7 +174,8 @@ struct ColorCycle {
struct StripTable;
-#define CHARSET_MASK_TRANSPARENCY 253
+#define CHARSET_MASK_TRANSPARENCY 0xFD
+#define CHARSET_MASK_TRANSPARENCY_32 0xFDFDFDFD
class Gdi {
protected:
diff --git a/engines/scumm/gfxARM.s b/engines/scumm/gfxARM.s
index 83aaa78927..f3a1f20303 100644
--- a/engines/scumm/gfxARM.s
+++ b/engines/scumm/gfxARM.s
@@ -24,7 +24,7 @@
.global asmDrawStripToScreen
.global asmCopy8Col
-
+
@ ARM implementation of asmDrawStripToScreen.
@
@ C prototype would be:
@@ -47,7 +47,7 @@ asmDrawStripToScreen:
@ r2 = text
@ r3 = src
MOV r12,r13
- STMFD r13!,{r4-r7,r9-r11,R14}
+ STMFD r13!,{r4-r11,R14}
LDMIA r12,{r4,r5,r6,r7}
@ r4 = dst
@ r5 = vsPitch
@@ -69,57 +69,46 @@ asmDrawStripToScreen:
MOV r10,#253
ORR r10,r10,r10,LSL #8
ORR r10,r10,r10,LSL #16 @ r10 = mask
-yLoop:
- MOV r14,r1 @ r14 = width
+ MOV r8,#0x7F
+ ORR r8, r8, r8, LSL #8
+ ORR r8, r8, r8, LSL #16 @ r8 = 7f7f7f7f
+ STR r1,[r13,#-4]! @ Stack width
+ B xLoop
+
+notEntirelyTransparent:
+ AND r14,r9, r8 @ r14 = mask & 7f7f7f7f
+ ADD r14,r14,r8 @ r14 = (mask & 7f7f7f7f)+7f7f7f7f
+ ORR r14,r14,r9 @ r14 |= mask
+ BIC r14,r14,r8 @ r14 &= 80808080
+ ADD r14,r8, r14,LSR #7 @ r14 = (rx>>7) + 7f7f7f7f
+ EOR r14,r14,r8 @ r14 ^= 7f7f7f7f
+ @ So bytes of r14 are 00 where source was matching value,FF otherwise
+ BIC r11,r11,r14
+ AND r12,r12,r14
+ ORR r12,r11,r12
+ STR r12,[r4],#4
+ SUBS r1,r1,#4
+ BLE endXLoop
xLoop:
- LDR r12,[r2],#4 @ r12 = [text]
- LDR r11,[r3],#4 @ r11 = [src]
- CMP r12,r10
- BNE singleByteCompare
- SUBS r14,r14,#4
+ LDR r12,[r2],#4 @ r12 = temp = [text]
+ LDR r11,[r3],#4 @ r11 = [src]
+ @ Stall
+ EORS r9, r12,r10 @ r9 = mask = temp ^ TRANSPARENCY
+ BNE notEntirelyTransparent
+ SUBS r1, r1, #4
STR r11,[r4], #4 @ r4 = [dst]
BGT xLoop
-
+endXLoop:
ADD r2,r2,r7 @ text += textSurfacePitch
ADD r3,r3,r5 @ src += vsPitch
ADD r4,r4,r6 @ dst += vmScreenWidth
SUBS r0,r0,#1
- BGT yLoop
- LDMFD r13!,{r4-r7,r9-r11,PC}
-
-singleByteCompare:
- MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
- CMP r9,r10,LSR #24 @ if (r9 == mask)
- MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
- ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
-
- MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
- CMP r9,r10,LSR #24 @ if (r9 == mask)
- MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
- ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
-
- MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
- CMP r9,r10,LSR #24 @ if (r9 == mask)
- MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
- ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
-
- MOV r9,r12,LSR #24 @ r9 = 1st byte of [text]
- CMP r9,r10,LSR #24 @ if (r9 == mask)
- MOVEQ r9,r11,LSR #24 @ r9 = 1st byte of [src]
- ORR r12,r9,r12,LSL #8 @ r12 = combine r9 and r12
-
- STR r12,[r4],#4
- SUBS r14,r14,#4
+ LDRGT r1,[r13] @ r14 = width
BGT xLoop
-
- ADD r2,r2,r7 @ text += textSurfacePitch
- ADD r3,r3,r5 @ src += vsPitch
- ADD r4,r4,r6 @ dst += vmScreenWidth
- SUBS r0,r0,#1
- BGT yLoop
+ ADD r13,r13,#4
end:
- LDMFD r13!,{r4-r7,r9-r11,PC}
-
+ LDMFD r13!,{r4-r11,PC}
+
@ ARM implementation of asmCopy8Col
@
@ C prototype would be:
@@ -156,4 +145,4 @@ roll2:
STR r14,[r0],r1
BNE yLoop2
- LDMFD r13!,{PC}
+ LDMFD r13!,{PC}
diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp
index e611c85e9d..685bd00065 100644
--- a/engines/scumm/he/cup_player_he.cpp
+++ b/engines/scumm/he/cup_player_he.cpp
@@ -99,7 +99,7 @@ void CUP_Player::play() {
debug(1, "rate %d width %d height %d", _playbackRate, _width, _height);
int ticks = _system->getMillis();
- while (_dataSize != 0 && !_vm->_quit) {
+ while (_dataSize != 0 && !_vm->quit()) {
while (parseNextBlockTag(_fileStream)) {
if (_fileStream.ioFailed()) {
return;
@@ -190,7 +190,7 @@ void CUP_Player::waitForSfxChannel(int channel) {
CUP_SfxChannel *sfxChannel = &_sfxChannels[channel];
debug(1, "waitForSfxChannel %d", channel);
if ((sfxChannel->flags & kSfxFlagLoop) == 0) {
- while (_mixer->isSoundHandleActive(sfxChannel->handle) && !_vm->_quit) {
+ while (_mixer->isSoundHandleActive(sfxChannel->handle) && !_vm->quit()) {
_vm->parseEvents();
_system->delayMillis(10);
}
@@ -496,7 +496,7 @@ void CUP_Player::handleTOIL(Common::SeekableReadStream &dataStream, uint32 dataS
for (int i = 0; i < kSfxChannels; ++i) {
waitForSfxChannel(i);
}
- _vm->_quit = true;
+ _vm->quitGame();
break;
case 7: {
int channelSync = dataStream.readUint32LE();
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index fff8502134..8fd9122503 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -39,6 +39,7 @@ class WriteStream;
namespace Scumm {
+class ActorHE;
class ResExtractor;
#ifdef ENABLE_HE
class LogicHE;
@@ -243,7 +244,7 @@ public:
AuxEntry _auxEntries[16];
uint16 _auxEntriesNum;
- void queueAuxBlock(Actor *a);
+ void queueAuxBlock(ActorHE *a);
void queueAuxEntry(int actorNum, int subIndex);
void remapHEPalette(const uint8 *src, uint8 *dst);
@@ -320,6 +321,8 @@ protected:
virtual bool handleNextCharsetCode(Actor *a, int *c);
virtual int convertMessageToString(const byte *msg, byte *dst, int dstSize);
+ void debugInput(byte *string);
+
/* HE version 72 script opcodes */
void o72_pushDWord();
void o72_getScriptString();
@@ -602,9 +605,12 @@ protected:
const OpcodeEntryV100he *_opcodesV100he;
+ byte _debugInputBuffer[256];
public:
ScummEngine_v100he(OSystem *syst, const DetectorResult &dr) : ScummEngine_v99he(syst, dr) {}
+ virtual void resetScumm();
+
protected:
virtual void setupOpcodes();
virtual void executeOpcode(byte i);
@@ -643,6 +649,7 @@ protected:
void o100_videoOps();
void o100_wait();
void o100_writeFile();
+ void o100_debugInput();
void o100_isResourceLoaded();
void o100_getResourceSize();
void o100_getSpriteGroupInfo();
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index f72701c229..f1a202e22c 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -23,12 +23,11 @@
*
*/
-
-
#include "common/system.h"
#include "scumm/actor.h"
#include "scumm/charset.h"
+#include "scumm/dialogs.h"
#include "scumm/he/animation_he.h"
#include "scumm/he/intern_he.h"
#include "scumm/object.h"
@@ -256,7 +255,7 @@ void ScummEngine_v100he::setupOpcodes() {
OPCODE(o90_cond),
OPCODE(o90_cos),
/* A8 */
- OPCODE(o6_invalid),
+ OPCODE(o100_debugInput),
OPCODE(o80_getFileSize),
OPCODE(o6_getActorFromXY),
OPCODE(o72_findAllObjects),
@@ -380,7 +379,7 @@ const char *ScummEngine_v100he::getOpcodeDesc(byte i) {
}
void ScummEngine_v100he::o100_actorOps() {
- Actor *a;
+ ActorHE *a;
int i, j, k;
int args[32];
byte string[256];
@@ -391,7 +390,7 @@ void ScummEngine_v100he::o100_actorOps() {
return;
}
- a = derefActorSafe(_curActor, "o100_actorOps");
+ a = (ActorHE *)derefActorSafe(_curActor, "o100_actorOps");
if (!a)
return;
@@ -1116,6 +1115,10 @@ void ScummEngine_v100he::o100_resourceRoutines() {
_heResId = pop();
break;
case 128:
+ // TODO: Clear Heap
+ break;
+ case 129:
+ // Dummy case
break;
case 132:
if (_heResType == rtScript && _heResId >= _numGlobalScripts)
@@ -2136,31 +2139,30 @@ void ScummEngine_v100he::o100_systemOps() {
byte string[1024];
byte subOp = fetchScriptByte();
- subOp -= 61;
switch (subOp) {
- case 0:
+ case 61:
restart();
break;
- case 67:
+ case 128:
clearDrawObjectQueue();
break;
- case 71:
+ case 132:
// Confirm shutdown
- shutDown();
+ quitGame();
break;
- case 72:
- shutDown();
+ case 133:
+ quitGame();
break;
- case 73:
+ case 134:
copyScriptString(string, sizeof(string));
debug(0, "Start game (%s)", string);
break;
- case 74:
+ case 135:
copyScriptString(string, sizeof(string));
debug(0, "Start executable (%s)", string);
break;
- case 75:
+ case 136:
restoreBackgroundHE(Common::Rect(_screenWidth, _screenHeight));
updatePalette();
break;
@@ -2342,6 +2344,30 @@ void ScummEngine_v100he::o100_writeFile() {
}
}
+void ScummEngine_v100he::o100_debugInput() {
+ byte subOp = fetchScriptByte();
+
+ switch (subOp) {
+ case 0:
+ copyScriptString(_debugInputBuffer, sizeof(_debugInputBuffer));
+ break;
+ case 26:
+ pop();
+ break;
+ case 27:
+ copyScriptString(_debugInputBuffer, sizeof(_debugInputBuffer));
+ break;
+ case 80:
+ copyScriptString(_debugInputBuffer, sizeof(_debugInputBuffer));
+ break;
+ case 92:
+ debugInput(_debugInputBuffer);
+ break;
+ default:
+ error("o100_debugInput: default case %d", subOp);
+ }
+}
+
void ScummEngine_v100he::o100_isResourceLoaded() {
// Reports percentage of resource loaded by queue
int type;
@@ -2493,65 +2519,64 @@ void ScummEngine_v100he::o100_getWizData() {
int32 x, y;
byte subOp = fetchScriptByte();
- subOp -= 20;
switch (subOp) {
- case 0:
+ case 20:
y = pop();
x = pop();
state = pop();
resId = pop();
push(_wiz->getWizPixelColor(resId, state, x, y, 0));
break;
- case 6:
+ case 26:
resId = pop();
push(_wiz->getWizImageStates(resId));
break;
- case 13:
+ case 33:
y = pop();
x = pop();
state = pop();
resId = pop();
push(_wiz->isWizPixelNonTransparent(resId, state, x, y, 0));
break;
- case 19:
+ case 39:
state = pop();
resId = pop();
_wiz->getWizImageDim(resId, state, w, h);
push(h);
break;
- case 34:
+ case 54:
type = pop();
state = pop();
resId = pop();
push(_wiz->getWizImageData(resId, state, type));
break;
- case 64:
+ case 84:
state = pop();
resId = pop();
_wiz->getWizImageDim(resId, state, w, h);
push(w);
break;
- case 65:
+ case 85:
state = pop();
resId = pop();
_wiz->getWizImageSpot(resId, state, x, y);
push(x);
break;
- case 66:
+ case 86:
state = pop();
resId = pop();
_wiz->getWizImageSpot(resId, state, x, y);
push(y);
break;
- case 111:
+ case 131:
pop();
copyScriptString(filename, sizeof(filename));
pop();
push(0);
debug(0, "o100_getWizData() case 111 unhandled");
break;
- case 112:
+ case 132:
h = pop();
w = pop();
y = pop();
@@ -2896,30 +2921,29 @@ void ScummEngine_v100he::o100_getSpriteInfo() {
void ScummEngine_v100he::o100_getVideoData() {
// Uses Bink video
byte subOp = fetchScriptByte();
- subOp -= 26;
switch (subOp) {
- case 0:
+ case 26:
pop();
push(_moviePlay->getFrameCount());
break;
- case 13:
+ case 39:
pop();
push(_moviePlay->getHeight());
break;
- case 14:
+ case 40:
pop();
push(_moviePlay->getImageNum());
break;
- case 28:
+ case 54:
debug(0, "o100_getVideoData: subOp 28 stub (%d, %d)", pop(), pop());
push(0);
break;
- case 47:
+ case 73:
pop();
push(_moviePlay->getCurFrame());
break;
- case 58:
+ case 84:
pop();
push(_moviePlay->getWidth());
break;
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index 9429f8d086..7f36d53791 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -23,7 +23,6 @@
*
*/
-
#include "common/savefile.h"
#include "scumm/actor.h"
@@ -623,7 +622,7 @@ void ScummEngine_v60he::swapObjects(int object1, int object2) {
}
void ScummEngine_v60he::o60_actorOps() {
- Actor *a;
+ ActorHE *a;
int i, j, k;
int args[8];
@@ -633,7 +632,7 @@ void ScummEngine_v60he::o60_actorOps() {
return;
}
- a = derefActorSafe(_curActor, "o60_actorOps");
+ a = (ActorHE *)derefActorSafe(_curActor, "o60_actorOps");
if (!a)
return;
diff --git a/engines/scumm/he/script_v70he.cpp b/engines/scumm/he/script_v70he.cpp
index 3f22c16648..577e7c3d99 100644
--- a/engines/scumm/he/script_v70he.cpp
+++ b/engines/scumm/he/script_v70he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/config-manager.h"
#include "common/system.h"
@@ -546,6 +544,7 @@ void ScummEngine_v70he::o70_resourceRoutines() {
_res->unlock(rtRoomImage, resid);
break;
case 116:
+ // TODO: Clear Heap
break;
case 117: // SO_LOAD_CHARSET
resid = pop();
@@ -634,10 +633,10 @@ void ScummEngine_v70he::o70_systemOps() {
break;
case 160:
// Confirm shutdown
- shutDown();
+ quitGame();
break;
case 244:
- shutDown();
+ quitGame();
break;
case 250:
id = pop();
diff --git a/engines/scumm/he/script_v71he.cpp b/engines/scumm/he/script_v71he.cpp
index 8b2823aa8c..1338ab3db8 100644
--- a/engines/scumm/he/script_v71he.cpp
+++ b/engines/scumm/he/script_v71he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "scumm/actor.h"
#include "scumm/he/intern_he.h"
#include "scumm/scumm.h"
@@ -500,7 +498,7 @@ void ScummEngine_v71he::adjustRect(Common::Rect &rect) {
void ScummEngine_v71he::o71_kernelSetFunctions() {
int args[29];
int num;
- Actor *a;
+ ActorHE *a;
num = getStackList(args, ARRAYSIZE(args));
@@ -511,8 +509,8 @@ void ScummEngine_v71he::o71_kernelSetFunctions() {
virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
break;
case 20: // HE72+
- a = derefActor(args[1], "o71_kernelSetFunctions: 20");
- ((ScummEngine_v71he *)this)->queueAuxBlock(a);
+ a = (ActorHE *)derefActor(args[1], "o71_kernelSetFunctions: 20");
+ queueAuxBlock(a);
break;
case 21:
_skipDrawObject = 1;
@@ -533,14 +531,14 @@ void ScummEngine_v71he::o71_kernelSetFunctions() {
redrawAllActors();
break;
case 26:
- a = derefActor(args[1], "o71_kernelSetFunctions: 26");
+ a = (ActorHE *)derefActor(args[1], "o71_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], "o71_kernelSetFunctions: 30");
+ a = (ActorHE *)derefActor(args[1], "o71_kernelSetFunctions: 30");
a->_clipOverride.bottom = args[2];
break;
case 42:
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 6c3d0023d8..2fecc58bff 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/config-manager.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -1021,7 +1019,7 @@ void ScummEngine_v72he::o72_roomOps() {
}
void ScummEngine_v72he::o72_actorOps() {
- Actor *a;
+ ActorHE *a;
int i, j, k;
int args[32];
byte string[256];
@@ -1032,7 +1030,7 @@ void ScummEngine_v72he::o72_actorOps() {
return;
}
- a = derefActorSafe(_curActor, "o72_actorOps");
+ a = (ActorHE *)derefActorSafe(_curActor, "o72_actorOps");
if (!a)
return;
@@ -1485,10 +1483,10 @@ void ScummEngine_v72he::o72_systemOps() {
break;
case 160:
// Confirm shutdown
- shutDown();
+ quitGame();
break;
case 244:
- shutDown();
+ quitGame();
break;
case 251:
copyScriptString(string, sizeof(string));
@@ -1635,13 +1633,10 @@ void ScummEngine_v72he::o72_drawWizImage() {
_wiz->displayWizImage(&wi);
}
-void ScummEngine_v72he::o72_debugInput() {
- byte string[255];
+void ScummEngine_v72he::debugInput(byte* string) {
byte *debugInputString;
- copyScriptString(string, sizeof(string));
-
- DebugInputDialog dialog(this, (char*)string);
+ DebugInputDialog dialog(this, (char *)string);
runDialog(dialog);
while (!dialog.done) {
parseEvents();
@@ -1654,6 +1649,13 @@ void ScummEngine_v72he::o72_debugInput() {
push(readVar(0));
}
+void ScummEngine_v72he::o72_debugInput() {
+ byte string[255];
+
+ copyScriptString(string, sizeof(string));
+ debugInput(string);
+}
+
void ScummEngine_v72he::o72_jumpToScript() {
int args[25];
int script;
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index 39ec715d94..46449d1683 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/config-file.h"
#include "common/config-manager.h"
#include "common/savefile.h"
@@ -646,7 +644,7 @@ void ScummEngine_v80he::drawLine(int x1, int y1, int x, int y, int step, int typ
if (type == 2) {
- Actor *a = derefActor(id, "drawLine");
+ ActorHE *a = (ActorHE *)derefActor(id, "drawLine");
a->drawActorToBackBuf(x, y);
} else if (type == 3) {
WizImage wi;
@@ -697,7 +695,7 @@ void ScummEngine_v80he::drawLine(int x1, int y1, int x, int y, int step, int typ
continue;
if (type == 2) {
- Actor *a = derefActor(id, "drawLine");
+ ActorHE *a = (ActorHE *)derefActor(id, "drawLine");
a->drawActorToBackBuf(x, y);
} else if (type == 3) {
WizImage wi;
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 37ce17c050..9829d0ecb5 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "scumm/actor.h"
#include "scumm/charset.h"
#include "scumm/he/animation_he.h"
@@ -395,42 +393,41 @@ void ScummEngine_v90he::o90_wizImageOps() {
int a, b;
int subOp = fetchScriptByte();
- subOp -= 46;
switch (subOp) {
- case -14: // HE99+
+ case 32: // HE99+
_wizParams.processFlags |= kWPFUseDefImgWidth;
_wizParams.resDefImgW = pop();
break;
- case -13: // HE99+
+ case 33: // HE99+
_wizParams.processFlags |= kWPFUseDefImgHeight;
_wizParams.resDefImgH = pop();
break;
- case 0:
+ case 46:
// Dummy case
pop();
break;
- case 1:
+ case 47:
_wizParams.box.bottom = pop();
_wizParams.box.right = pop();
_wizParams.box.top = pop();
_wizParams.box.left = pop();
break;
- case 2:
+ case 48:
_wizParams.processMode = 1;
break;
- case 3:
+ case 49:
_wizParams.processFlags |= kWPFUseFile;
_wizParams.processMode = 3;
copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
break;
- case 4:
+ case 50:
_wizParams.processFlags |= kWPFUseFile;
_wizParams.processMode = 4;
copyScriptString(_wizParams.filename, sizeof(_wizParams.filename));
_wizParams.fileWriteMode = pop();
break;
- case 5:
+ case 51:
_wizParams.processFlags |= kWPFClipBox | 0x100;
_wizParams.processMode = 2;
_wizParams.box.bottom = pop();
@@ -440,19 +437,19 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.compType = pop();
adjustRect(_wizParams.box);
break;
- case 6:
+ case 52:
_wizParams.processFlags |= kWPFNewState;
_wizParams.img.state = pop();
break;
- case 7:
+ case 53:
_wizParams.processFlags |= kWPFRotate;
_wizParams.angle = pop();
break;
- case 8:
+ case 54:
_wizParams.processFlags |= kWPFNewFlags;
_wizParams.img.flags |= pop();
break;
- case 10:
+ case 56:
_wizParams.img.flags = pop();
_wizParams.img.state = pop();
_wizParams.img.y1 = pop();
@@ -460,7 +457,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.img.resNum = pop();
_wiz->displayWizImage(&_wizParams.img);
break;
- case 11:
+ case 57:
_wizParams.img.resNum = pop();
_wizParams.processMode = 0;
_wizParams.processFlags = 0;
@@ -471,18 +468,18 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.spriteId = 0;
_wizParams.spriteGroup = 0;
break;
- case 16: // HE99+
+ case 62: // HE99+
_wizParams.processFlags |= kWPFMaskImg;
_wizParams.sourceImage = pop();
break;
- case 19:
- case 108:
+ case 65:
+ case 154:
_wizParams.processFlags |= kWPFSetPos;
_wizParams.img.y1 = pop();
_wizParams.img.x1 = pop();
break;
- case 20:
- case 203: // HE98+
+ case 66:
+ case 249: // HE98+
b = pop();
a = pop();
_wizParams.processFlags |= kWPFRemapPalette;
@@ -495,7 +492,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.remapColor[a] = b;
_wizParams.remapNum++;
break;
- case 21:
+ case 67:
_wizParams.processFlags |= kWPFClipBox;
_wizParams.box.bottom = pop();
_wizParams.box.right = pop();
@@ -503,26 +500,26 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.box.left = pop();
adjustRect(_wizParams.box);
break;
- case 40: // HE99+
+ case 86: // HE99+
_wizParams.processFlags |= kWPFPaletteNum;
_wizParams.img.palette = pop();
break;
- case 46:
+ case 92:
_wizParams.processFlags |= kWPFScaled;
_wizParams.scale = pop();
break;
- case 52:
+ case 98:
_wizParams.processFlags |= kWPFShadow;
_wizParams.img.shadow = pop();
break;
- case 85: // HE99+
+ case 131: // HE99+
_wizParams.processFlags |= 0x1000 | 0x100 | 0x2;
_wizParams.processMode = 7;
_wizParams.polygonId2 = pop();
_wizParams.polygonId1 = pop();
_wizParams.compType = pop();
break;
- case 87: // HE99+
+ case 133: // HE99+
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
_wizParams.processMode = 9;
_wizParams.fillColor = pop();
@@ -531,7 +528,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.box2.top = pop();
_wizParams.box2.left = pop();
break;
- case 88: // HE99+
+ case 134: // HE99+
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
_wizParams.processMode = 10;
_wizParams.fillColor = pop();
@@ -540,33 +537,33 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.box2.top = pop();
_wizParams.box2.left = pop();
break;
- case 89: // HE99+
+ case 135: // 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+
+ case 136: // 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+
+ case 137: // HE99+
_wizParams.processFlags |= kWPFDstResNum;
_wizParams.dstResNum = pop();
break;
- case 93: // HE99+
+ case 139: // HE99+
_wizParams.processFlags |= kWPFThickLine;
_wizParams.lineUnk1 = pop();
_wizParams.lineUnk2 = pop();
break;
- case 95: // HE99+
+ case 141: // HE99+
_wizParams.processMode = 13;
break;
- case 96: // HE99+
+ case 142: // HE99+
_wizParams.field_239D = pop();
_wizParams.field_2399 = pop();
_wizParams.field_23A5 = pop();
@@ -574,13 +571,13 @@ void ScummEngine_v90he::o90_wizImageOps() {
copyScriptString(_wizParams.string2, sizeof(_wizParams.string2));
_wizParams.processMode = 15;
break;
- case 97: // HE99+
+ case 143: // HE99+
_wizParams.processMode = 16;
_wizParams.field_23AD = pop();
_wizParams.field_23A9 = pop();
copyScriptString(_wizParams.string1, sizeof(_wizParams.string1));
break;
- case 143: // HE99+
+ case 189: // HE99+
_wizParams.processMode = 17;
_wizParams.field_23CD = pop();
_wizParams.field_23C9 = pop();
@@ -591,18 +588,18 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.field_23B5 = pop();
_wizParams.field_23B1 = pop();
break;
- case 150: // HE99+
+ case 196: // HE99+
_wizParams.processMode = 14;
break;
- case 171: // HE99+
+ case 217: // HE99+
_wizParams.processMode = 8;
break;
- case 200:
+ case 246:
_wizParams.processFlags |= kWPFNewFlags | kWPFSetPos | 2;
_wizParams.img.flags |= kWIFIsPolygon;
_wizParams.polygonId1 = _wizParams.img.y1 = _wizParams.img.x1 = pop();
break;
- case 209:
+ case 255:
if (_wizParams.img.resNum)
_wiz->processWizImage(&_wizParams);
break;
@@ -724,10 +721,9 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
int32 x, y;
byte subOp = fetchScriptByte();
- subOp -= 30;
switch (subOp) {
- case 0:
+ case 30:
spriteId = pop();
if (spriteId) {
_sprite->getSpritePosition(spriteId, x, y);
@@ -736,7 +732,7 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 1:
+ case 31:
spriteId = pop();
if (spriteId) {
_sprite->getSpritePosition(spriteId, x, y);
@@ -745,7 +741,7 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 2:
+ case 32:
spriteId = pop();
if (spriteId) {
_sprite->getSpriteImageDim(spriteId, x, y);
@@ -754,7 +750,7 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 3:
+ case 33:
spriteId = pop();
if (spriteId) {
_sprite->getSpriteImageDim(spriteId, x, y);
@@ -763,7 +759,7 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 4:
+ case 34:
spriteId = pop();
if (spriteId) {
_sprite->getSpriteDist(spriteId, x, y);
@@ -772,7 +768,7 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 5:
+ case 35:
spriteId = pop();
if (spriteId) {
_sprite->getSpriteDist(spriteId, x, y);
@@ -781,35 +777,35 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 6:
+ case 36:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteImageStateCount(spriteId));
else
push(0);
break;
- case 7:
+ case 37:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteGroup(spriteId));
else
push(0);
break;
- case 8:
+ case 38:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteDisplayX(spriteId));
else
push(0);
break;
- case 9:
+ case 39:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteDisplayY(spriteId));
else
push(0);
break;
- case 12:
+ case 42:
flags = pop();
spriteId = pop();
if (spriteId) {
@@ -836,14 +832,14 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 13:
+ case 43:
spriteId = pop();
if (spriteId)
push(_sprite->getSpritePriority(spriteId));
else
push(0);
break;
- case 15:
+ case 45:
if (_game.heversion == 99) {
flags = getStackList(args, ARRAYSIZE(args));
type = pop();
@@ -864,77 +860,77 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(_sprite->findSpriteWithClassOf(x, y, groupId, 0, 0, 0));
}
break;
- case 22:
+ case 52:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteImageState(spriteId));
else
push(0);
break;
- case 32:
+ case 62:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteSourceImage(spriteId));
else
push(0);
break;
- case 33:
+ case 63:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteImage(spriteId));
else
push(0);
break;
- case 38:
+ case 68:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteFlagEraseType(spriteId));
else
push(1);
break;
- case 52:
+ case 82:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteFlagAutoAnim(spriteId));
else
push(0);
break;
- case 56:
+ case 86:
spriteId = pop();
if (spriteId)
push(_sprite->getSpritePalette(spriteId));
else
push(0);
break;
- case 62:
+ case 92:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteScale(spriteId));
else
push(0);
break;
- case 67:
+ case 97:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteAnimSpeed(spriteId));
else
push(1);
break;
- case 68:
+ case 98:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteShadow(spriteId));
else
push(0);
break;
- case 94:
+ case 124:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteFlagUpdateType(spriteId));
else
push(0);
break;
- case 95:
+ case 125:
flags = getStackList(args, ARRAYSIZE(args));
spriteId = pop();
if (spriteId) {
@@ -943,7 +939,7 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
push(0);
}
break;
- case 109:
+ case 139:
flags = pop();
spriteId = pop();
if (spriteId)
@@ -951,14 +947,14 @@ void ScummEngine_v90he::o90_getSpriteInfo() {
else
push(0);
break;
- case 110:
+ case 140:
spriteId = pop();
if (spriteId)
push(_sprite->getSpriteMaskImage(spriteId));
else
push(0);
break;
- case 168:
+ case 198:
pop();
spriteId = pop();
if (spriteId)
@@ -978,10 +974,9 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
int n;
byte subOp = fetchScriptByte();
- subOp -= 34;
switch (subOp) {
- case 0:
+ case 34:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -994,7 +989,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
_sprite->setSpriteDist(spriteId, args[0], tmp[1]);
}
break;
- case 1:
+ case 35:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1007,7 +1002,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
_sprite->setSpriteDist(spriteId, tmp[0], args[0]);
}
break;
- case 3:
+ case 37:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1018,7 +1013,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteGroup(spriteId, args[0]);
break;
- case 8:
+ case 42:
args[1] = pop();
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
@@ -1048,7 +1043,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
break;
}
break;
- case 9:
+ case 43:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1059,7 +1054,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpritePriority(spriteId, args[0]);
break;
- case 10:
+ case 44:
args[1] = pop();
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
@@ -1071,7 +1066,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->moveSprite(spriteId, args[0], args[1]);
break;
- case 18:
+ case 52:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1082,7 +1077,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteImageState(spriteId, args[0]);
break;
- case 19:
+ case 53:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1093,7 +1088,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteAngle(spriteId, args[0]);
break;
- case 23:
+ case 57:
if (_game.features & GF_HE_985 || _game.heversion >= 99) {
_curMaxSpriteId = pop();
_curSpriteId = pop();
@@ -1105,7 +1100,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
_curMaxSpriteId = _curSpriteId; // to make all functions happy
}
break;
- case 28: // HE99+
+ case 62: // HE99+
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1116,7 +1111,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteSourceImage(spriteId, args[0]);
break;
- case 29:
+ case 63:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1127,7 +1122,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteImage(spriteId, args[0]);
break;
- case 31:
+ case 65:
args[1] = pop();
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
@@ -1139,7 +1134,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpritePosition(spriteId, args[0], args[1]);
break;
- case 34:
+ case 68:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1150,7 +1145,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteFlagEraseType(spriteId, args[0]);
break;
- case 43:
+ case 77:
args[1] = pop();
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
@@ -1162,7 +1157,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteDist(spriteId, args[0], args[1]);
break;
- case 48:
+ case 82:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1173,7 +1168,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteFlagAutoAnim(spriteId, args[0]);
break;
- case 52: // HE 98+
+ case 86: // HE 98+
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1184,7 +1179,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpritePalette(spriteId, args[0]);
break;
- case 58: // HE 99+
+ case 92: // HE 99+
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1195,7 +1190,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteScale(spriteId, args[0]);
break;
- case 63: // HE 98+
+ case 97: // HE 98+
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1206,7 +1201,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteAnimSpeed(spriteId, args[0]);
break;
- case 64:
+ case 98:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1217,7 +1212,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteShadow(spriteId, args[0]);
break;
- case 90:
+ case 124:
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1228,7 +1223,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteFlagUpdateType(spriteId, args[0]);
break;
- case 91:
+ case 125:
n = getStackList(args, ARRAYSIZE(args));
if (_curSpriteId != 0 && _curMaxSpriteId != 0 && n != 0) {
int *p = &args[n - 1];
@@ -1251,7 +1246,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
} while (--n);
}
break;
- case 105: // HE 99+
+ case 139: // HE 99+
args[1] = pop();
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
@@ -1263,7 +1258,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteGeneralProperty(spriteId, args[0], args[1]);
break;
- case 106: // HE 99+
+ case 140: // HE 99+
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
break;
@@ -1274,10 +1269,10 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteMaskImage(spriteId, args[0]);
break;
- case 124:
+ case 158:
_sprite->resetTables(true);
break;
- case 164:
+ case 198:
args[1] = pop();
args[0] = pop();
if (_curSpriteId > _curMaxSpriteId)
@@ -1289,7 +1284,7 @@ void ScummEngine_v90he::o90_setSpriteInfo() {
for (; spriteId <= _curMaxSpriteId; spriteId++)
_sprite->setSpriteUserValue(spriteId, args[0], args[1]);
break;
- case 183:
+ case 217:
if (_curSpriteId > _curMaxSpriteId)
break;
spriteId = _curSpriteId;
@@ -1389,10 +1384,9 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
int type, value1, value2, value3, value4;
byte subOp = fetchScriptByte();
- subOp -= 37;
switch (subOp) {
- case 0:
+ case 37:
type = pop() - 1;
switch (type) {
case 0:
@@ -1455,7 +1449,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
error("o90_setSpriteGroupInfo subOp 0: Unknown case %d", subOp);
}
break;
- case 5:
+ case 42:
type = pop();
value1 = pop();
if (!_curSpriteGroupId)
@@ -1478,14 +1472,14 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
error("o90_setSpriteGroupInfo subOp 5: Unknown case %d", subOp);
}
break;
- case 6:
+ case 43:
value1 = pop();
if (!_curSpriteGroupId)
break;
_sprite->setGroupPriority(_curSpriteGroupId, value1);
break;
- case 7:
+ case 44:
value2 = pop();
value1 = pop();
if (!_curSpriteGroupId)
@@ -1493,17 +1487,17 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
_sprite->moveGroup(_curSpriteGroupId, value1, value2);
break;
- case 20:
+ case 57:
_curSpriteGroupId = pop();
break;
- case 26:
+ case 63:
value1 = pop();
if (!_curSpriteGroupId)
break;
_sprite->setGroupImage(_curSpriteGroupId, value1);
break;
- case 28:
+ case 65:
value2 = pop();
value1 = pop();
if (!_curSpriteGroupId)
@@ -1511,7 +1505,7 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
_sprite->setGroupPosition(_curSpriteGroupId, value1, value2);
break;
- case 30:
+ case 67:
value4 = pop();
value3 = pop();
value2 = pop();
@@ -1521,13 +1515,13 @@ void ScummEngine_v90he::o90_setSpriteGroupInfo() {
_sprite->setGroupBounds(_curSpriteGroupId, value1, value2, value3, value4);
break;
- case 56:
+ case 93:
if (!_curSpriteGroupId)
break;
_sprite->resetGroupBounds(_curSpriteGroupId);
break;
- case 180:
+ case 217:
if (!_curSpriteGroupId)
break;
@@ -1545,52 +1539,51 @@ void ScummEngine_v90he::o90_getWizData() {
int32 x, y;
byte subOp = fetchScriptByte();
- subOp -= 30;
switch (subOp) {
- case 0:
+ case 30:
state = pop();
resId = pop();
_wiz->getWizImageSpot(resId, state, x, y);
push(x);
break;
- case 1:
+ case 31:
state = pop();
resId = pop();
_wiz->getWizImageSpot(resId, state, x, y);
push(y);
break;
- case 2:
+ case 32:
state = pop();
resId = pop();
_wiz->getWizImageDim(resId, state, w, h);
push(w);
break;
- case 3:
+ case 33:
state = pop();
resId = pop();
_wiz->getWizImageDim(resId, state, w, h);
push(h);
break;
- case 6:
+ case 36:
resId = pop();
push(_wiz->getWizImageStates(resId));
break;
- case 15:
+ case 45:
y = pop();
x = pop();
state = pop();
resId = pop();
push(_wiz->isWizPixelNonTransparent(resId, state, x, y, 0));
break;
- case 36:
+ case 66:
y = pop();
x = pop();
state = pop();
resId = pop();
push(_wiz->getWizPixelColor(resId, state, x, y, 0));
break;
- case 100:
+ case 130:
h = pop();
w = pop();
y = pop();
@@ -1604,12 +1597,12 @@ void ScummEngine_v90he::o90_getWizData() {
}
push(computeWizHistogram(resId, state, x, y, w, h));
break;
- case 109:
+ case 139:
pop();
pop();
push(0);
break;
- case 111:
+ case 141:
pop();
copyScriptString(filename, sizeof(filename));
pop();
@@ -1622,13 +1615,13 @@ void ScummEngine_v90he::o90_getWizData() {
}
void ScummEngine_v90he::o90_getActorData() {
- Actor *a;
+ ActorHE *a;
int subOp = pop();
int val = pop();
int act = pop();
- a = derefActor(act, "o90_getActorData");
+ a = (ActorHE *)derefActor(act, "o90_getActorData");
switch (subOp) {
case 1:
@@ -1730,30 +1723,29 @@ void ScummEngine_v90he::o90_videoOps() {
void ScummEngine_v90he::o90_getVideoData() {
// Uses Smacker video
byte subOp = fetchScriptByte();
- subOp -= 32;
switch (subOp) {
- case 0: // Get width
+ case 32: // Get width
pop();
push(_moviePlay->getWidth());
break;
- case 1: // Get height
+ case 33: // Get height
pop();
push(_moviePlay->getHeight());
break;
- case 4: // Get frame count
+ case 36: // Get frame count
pop();
push(_moviePlay->getFrameCount());
break;
- case 20: // Get current frame
+ case 52: // Get current frame
pop();
push(_moviePlay->getCurFrame());
break;
- case 31: // Get image number
+ case 63: // Get image number
pop();
push(_moviePlay->getImageNum());
break;
- case 107: // Get statistics
+ case 139: // Get statistics
debug(0, "o90_getVideoData: subOp 107 stub (%d, %d)", pop(), pop());
push(0);
break;
@@ -1764,33 +1756,32 @@ void ScummEngine_v90he::o90_getVideoData() {
void ScummEngine_v90he::o90_floodFill() {
byte subOp = fetchScriptByte();
- subOp -= 54;
switch (subOp) {
- case 0:
+ case 54:
pop();
break;
- case 3:
+ case 57:
memset(&_floodFillParams, 0, sizeof(_floodFillParams));
_floodFillParams.box.left = 0;
_floodFillParams.box.top = 0;
_floodFillParams.box.right = 639;
_floodFillParams.box.bottom = 479;
break;
- case 11:
+ case 65:
_floodFillParams.y = pop();
_floodFillParams.x = pop();
break;
- case 12:
+ case 66:
_floodFillParams.flags = pop();
break;
- case 13:
+ case 67:
_floodFillParams.box.bottom = pop();
_floodFillParams.box.right = pop();
_floodFillParams.box.top = pop();
_floodFillParams.box.left = pop();
break;
- case 201:
+ case 255:
floodFill(&_floodFillParams, this);
break;
default:
@@ -2336,47 +2327,46 @@ void ScummEngine_v90he::o90_sortArray() {
void ScummEngine_v90he::o90_getObjectData() {
byte subOp = fetchScriptByte();
- subOp -= 32;
switch (subOp) {
- case 0:
+ case 32:
if (_heObjectNum == -1)
push(0);
else
push(_objs[_heObjectNum].width);
break;
- case 1:
+ case 33:
if (_heObjectNum == -1)
push(0);
else
push(_objs[_heObjectNum].height);
break;
- case 4:
+ case 36:
if (_heObjectNum == -1)
push(0);
else
push(getObjectImageCount(_heObject));
break;
- case 6:
+ case 38:
if (_heObjectNum == -1)
push(0);
else
push(_objs[_heObjectNum].x_pos);
break;
- case 7:
+ case 39:
if (_heObjectNum == -1)
push(0);
else
push(_objs[_heObjectNum].y_pos);
break;
- case 20:
+ case 52:
push(getState(_heObject));
break;
- case 25:
+ case 57:
_heObject = pop();
_heObjectNum = getObjectIndex(_heObject);
break;
- case 107:
+ case 139:
// Dummy case
pop();
push(0);
@@ -2391,10 +2381,9 @@ void ScummEngine_v90he::o90_getPaletteData() {
int palSlot, color;
byte subOp = fetchScriptByte();
- subOp -= 45;
switch (subOp) {
- case 0:
+ case 45:
e = pop();
d = pop();
palSlot = pop();
@@ -2403,23 +2392,23 @@ void ScummEngine_v90he::o90_getPaletteData() {
b = pop();
push(getHEPaletteSimilarColor(palSlot, b, c, d, e));
break;
- case 7:
+ case 52:
c = pop();
b = pop();
palSlot = pop();
push(getHEPaletteColorComponent(palSlot, b, c));
break;
- case 21:
+ case 66:
color = pop();
palSlot = pop();
push(getHEPaletteColor(palSlot, color));
break;
- case 87:
+ case 132:
c = pop();
b = pop();
push(getHEPaletteColorComponent(1, b, c));
break;
- case 172:
+ case 217:
pop();
c = pop();
c = MAX(0, c);
@@ -2438,20 +2427,19 @@ void ScummEngine_v90he::o90_paletteOps() {
int a, b, c, d, e;
byte subOp = fetchScriptByte();
- subOp -= 57;
switch (subOp) {
- case 0:
+ case 57:
_hePaletteNum = pop();
break;
- case 6:
+ case 63:
b = pop();
a = pop();
if (_hePaletteNum != 0) {
setHEPaletteFromImage(_hePaletteNum, a, b);
}
break;
- case 9:
+ case 66:
e = pop();
d = pop();
c = pop();
@@ -2463,7 +2451,7 @@ void ScummEngine_v90he::o90_paletteOps() {
}
}
break;
- case 13:
+ case 70:
c = pop();
b = pop();
a = pop();
@@ -2473,31 +2461,31 @@ void ScummEngine_v90he::o90_paletteOps() {
}
}
break;
- case 19: //HE99+
+ case 76: //HE99+
a = pop();
if (_hePaletteNum != 0) {
setHEPaletteFromCostume(_hePaletteNum, a);
}
break;
- case 29:
+ case 86:
a = pop();
if (_hePaletteNum != 0) {
copyHEPalette(_hePaletteNum, a);
}
break;
- case 118:
+ case 175:
b = pop();
a = pop();
if (_hePaletteNum != 0) {
setHEPaletteFromRoom(_hePaletteNum, a, b);
}
break;
- case 160:
+ case 217:
if (_hePaletteNum != 0) {
restoreHEPalette(_hePaletteNum);
}
break;
- case 198:
+ case 255:
_hePaletteNum = 0;
break;
default:
@@ -2580,13 +2568,13 @@ void ScummEngine_v90he::o90_kernelGetFunctions() {
void ScummEngine_v90he::o90_kernelSetFunctions() {
int args[29];
int num, tmp;
- Actor *a;
+ ActorHE *a;
num = getStackList(args, ARRAYSIZE(args));
switch (args[0]) {
case 20:
- a = derefActor(args[1], "o90_kernelSetFunctions: 20");
+ a = (ActorHE *)derefActor(args[1], "o90_kernelSetFunctions: 20");
queueAuxBlock(a);
break;
case 21:
@@ -2628,7 +2616,7 @@ void ScummEngine_v90he::o90_kernelSetFunctions() {
// Remote start script function
break;
case 1969:
- a = derefActor(args[1], "o90_kernelSetFunctions: 1969");
+ a = (ActorHE *)derefActor(args[1], "o90_kernelSetFunctions: 1969");
tmp = a->_heCondMask;
tmp ^= args[2];
tmp &= 0x7FFF0000;
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 35028c7e1c..bb67f2b31d 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -192,10 +192,6 @@ void ScummEngine::parseEvents() {
_keyPressed = Common::KeyState(Common::KEYCODE_6, 54); // '6'
break;
- case Common::EVENT_QUIT:
- _quit = true;
- break;
-
default:
break;
}
@@ -475,7 +471,7 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) {
if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT), 0, 0, 0);
- mainMenuDialog(); // Display NewGui
+ scummMenuDialog(); // Display NewGui
if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0)
runScript(VAR(VAR_SAVELOAD_SCRIPT2), 0, 0, 0);
@@ -514,7 +510,7 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) {
vol = Audio::Mixer::kMaxMixerVolume;
ConfMan.setInt("music_volume", vol);
- updateSoundSettings();
+ syncSoundSettings();
} else if (lastKeyHit.ascii == '-' || lastKeyHit.ascii == '+') { // Change text speed
if (lastKeyHit.ascii == '+' && _defaultTalkDelay > 0)
@@ -527,7 +523,7 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) {
_defaultTalkDelay = 9 - runDialog(dlg);
// Save the new talkspeed value to ConfMan
- setTalkspeed(_defaultTalkDelay);
+ setTalkDelay(_defaultTalkDelay);
if (VAR_CHARINC != 0xFF)
VAR(VAR_CHARINC) = _defaultTalkDelay;
diff --git a/engines/scumm/insane/insane.cpp b/engines/scumm/insane/insane.cpp
index 1771618822..77a01d54d0 100644
--- a/engines/scumm/insane/insane.cpp
+++ b/engines/scumm/insane/insane.cpp
@@ -39,7 +39,6 @@
#include "scumm/smush/smush_player.h"
#include "scumm/smush/smush_font.h"
-#include "scumm/smush/chunk.h"
#include "scumm/insane/insane.h"
@@ -1310,33 +1309,25 @@ void Insane::smlayer_showStatusMsg(int32 arg_0, byte *renderBitmap, int32 codecp
free (string);
}
-void Insane::procSKIP(Chunk &b) {
+void Insane::procSKIP(int32 subSize, Common::SeekableReadStream &b) {
int16 par1, par2;
_player->_skipNext = false;
if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) {
- _player->checkBlock(b, MKID_BE('SKIP'), 2);
+ assert(subSize >= 2);
par1 = b.readUint16LE();
- if (isBitSet(par1))
- _player->_skipNext = true;
- return;
+ par2 = 0;
+ } else {
+ assert(subSize >= 4);
+ par1 = b.readUint16LE();
+ par2 = b.readUint16LE();
}
- _player->checkBlock(b, MKID_BE('SKIP'), 4);
-
- par1 = b.readUint16LE();
- par2 = b.readUint16LE();
-
-
if (!par2) {
if (isBitSet(par1))
_player->_skipNext = true;
- return;
- }
-
- if (isBitSet(par1) != isBitSet(par2)) {
+ } else if (isBitSet(par1) != isBitSet(par2)) {
_player->_skipNext = true;
- return;
}
}
diff --git a/engines/scumm/insane/insane.h b/engines/scumm/insane/insane.h
index 28eafb6f73..50d8d057cf 100644
--- a/engines/scumm/insane/insane.h
+++ b/engines/scumm/insane/insane.h
@@ -31,7 +31,6 @@
#include "scumm/nut_renderer.h"
#include "scumm/smush/smush_player.h"
-#include "scumm/smush/chunk.h"
namespace Scumm {
@@ -67,9 +66,9 @@ class Insane {
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, int16 par1,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags, int16 par1,
int16 par2, int16 par3, int16 par4);
- void procSKIP(Chunk &b);
+ void procSKIP(int32 subSize, Common::SeekableReadStream &b);
void escapeKeyHandler(void);
private:
@@ -434,22 +433,22 @@ class Insane {
void ouchSoundEnemy(void);
bool weaponEnemyIsEffective(void);
void iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4);
void iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 command, int16 par1, int16, int16);
void iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4);
void iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4);
void iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4);
void iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4);
bool isBitSet(int n);
void setBit(int n);
diff --git a/engines/scumm/insane/insane_iact.cpp b/engines/scumm/insane/insane_iact.cpp
index c7f0c7220b..b6ce1091e8 100644
--- a/engines/scumm/insane/insane_iact.cpp
+++ b/engines/scumm/insane/insane_iact.cpp
@@ -30,14 +30,13 @@
#include "scumm/scumm.h"
#include "scumm/smush/smush_player.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,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4) {
if (_keyboardDisable)
return;
@@ -67,7 +66,7 @@ void Insane::procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12,
}
void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4) {
int16 par5, par6, par7, par9, par11, par13, tmp;
@@ -294,7 +293,7 @@ void Insane::removeEnemyFromMetList(int32 enemy1) {
}
void Insane::iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 command, int16 par1, int16, int16) {
int par2, par3;
if (command == 6) {
@@ -317,7 +316,7 @@ void Insane::iactScene3(byte *renderBitmap, int32 codecparam, int32 setupsan12,
}
void Insane::iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4) {
int16 par5;
@@ -393,7 +392,7 @@ void Insane::iactScene4(byte *renderBitmap, int32 codecparam, int32 setupsan12,
}
void Insane::iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4) {
int16 par5;
@@ -478,7 +477,7 @@ void Insane::iactScene6(byte *renderBitmap, int32 codecparam, int32 setupsan12,
}
void Insane::iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4) {
switch (par1) {
case 2:
@@ -524,7 +523,7 @@ void Insane::iactScene17(byte *renderBitmap, int32 codecparam, int32 setupsan12,
}
void Insane::iactScene21(byte *renderBitmap, int32 codecparam, int32 setupsan12,
- int32 setupsan13, Chunk &b, int32 size, int32 flags,
+ int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
int16 par1, int16 par2, int16 par3, int16 par4) {
// void implementation
}
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 7d52a02116..8d6a5453df 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -53,7 +53,6 @@ MODULE_OBJS := \
scumm.o \
sound.o \
string.o \
- thumbnail.o \
usage_bits.o \
util.o \
vars.o \
@@ -82,7 +81,6 @@ MODULE_OBJS += \
insane/insane_scenes.o \
insane/insane_iact.o \
smush/channel.o \
- smush/chunk.o \
smush/codec1.o \
smush/codec37.o \
smush/codec47.o \
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index 8bcd92fd3b..eaffbd04bb 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -109,6 +109,13 @@ void ScummEngine::setOwnerOf(int obj, int owner) {
int arg = (_game.version >= 6) ? obj : 0;
+ // WORKAROUND for bug #1917981: Game crash when finishing Indy3 demo.
+ // Script 94 tries to empty the inventory but does so in a bogus way.
+ // This causes it to try to remove object 0 from the inventory.
+ if (_game.id == GID_PASS && obj == 0 && vm.slot[_currentScript].number == 94)
+ return;
+ assert(obj > 0);
+
if (owner == 0) {
clearOwnerOf(obj);
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 6bd62c1761..50e0d221ca 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -226,7 +226,7 @@ void ScummEngine::askForDisk(const char *filename, int disknum) {
#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());
+ sprintf(buf, "Cannot find file: '%s'\nInsert disc %d into drive %s\nPress OK to retry, Quit to exit", filename, disknum, _gameDataDir.getPath().c_str());
#endif
result = displayMessage("Quit", buf);
@@ -253,7 +253,7 @@ void ScummEngine::readIndexFile() {
if (_game.version <= 5) {
// Figure out the sizes of various resources
- while (!_fileHandle->eof()) {
+ while (!_fileHandle->eos()) {
blocktype = _fileHandle->readUint32BE();
itemsize = _fileHandle->readUint32BE();
if (_fileHandle->ioFailed())
@@ -291,7 +291,7 @@ void ScummEngine::readIndexFile() {
if (checkTryMedia(_fileHandle)) {
displayMessage(NULL, "You're trying to run game encrypted by ActiveMark. This is not supported.");
- _quit = true;
+ quitGame();
return;
}
@@ -809,7 +809,7 @@ byte *ResourceManager::createResource(int type, int idx, uint32 size) {
ptr = (byte *)calloc(size + sizeof(MemBlkHeader) + SAFETY_AREA, 1);
if (ptr == NULL) {
- error("Out of memory while allocating %d", size);
+ error("createResource(%s,%d): Out of memory while allocating %d", resTypeFromId(type), idx, size);
}
_allocatedSize += size;
diff --git a/engines/scumm/resource_v4.cpp b/engines/scumm/resource_v4.cpp
index 0ced00e254..29d7c5d25d 100644
--- a/engines/scumm/resource_v4.cpp
+++ b/engines/scumm/resource_v4.cpp
@@ -62,7 +62,7 @@ void ScummEngine_v4::readIndexFile() {
closeRoom();
openRoom(0);
- while (!_fileHandle->eof()) {
+ while (!_fileHandle->eos()) {
// Figure out the sizes of various resources
itemsize = _fileHandle->readUint32LE();
blocktype = _fileHandle->readUint16LE();
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index f9e4eb415c..267e06dafd 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -46,6 +46,8 @@
#include "sound/audiocd.h"
#include "sound/mixer.h"
+#include "graphics/thumbnail.h"
+
namespace Scumm {
struct SaveGameHeader {
@@ -71,6 +73,8 @@ struct SaveInfoSection {
#define INFOSECTION_VERSION 2
+#pragma mark -
+
void ScummEngine::requestSave(int slot, const char *name, bool temporary) {
_saveLoadSlot = slot;
_saveTemporaryState = temporary;
@@ -99,34 +103,36 @@ static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) {
}
bool ScummEngine::saveState(int slot, bool compat) {
- char filename[256];
+ Common::String filename;
Common::OutSaveFile *out;
SaveGameHeader hdr;
if (_saveLoadSlot == 255) {
// Allow custom filenames for save game system in HE Games
- memcpy(filename, _saveLoadFileName, sizeof(_saveLoadFileName));
+ filename = _saveLoadFileName;
} else {
- makeSavegameName(filename, slot, compat);
+ filename = makeSavegameName(slot, compat);
}
- if (!(out = _saveFileMan->openForSaving(filename)))
+ if (!(out = _saveFileMan->openForSaving(filename.c_str())))
return false;
memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
saveSaveGameHeader(out, hdr);
- saveThumbnail(out);
+#if !defined(__DS__)
+ Graphics::saveThumbnail(*out);
+#endif
saveInfos(out);
Serializer ser(0, out, CURRENT_VER);
saveOrLoad(&ser);
out->finalize();
- if (out->ioFailed()) {
+ if (out->err()) {
delete out;
- debug(1, "State save as '%s' FAILED", filename);
+ debug(1, "State save as '%s' FAILED", filename.c_str());
return false;
}
delete out;
- debug(1, "State saved as '%s'", filename);
+ debug(1, "State saved as '%s'", filename.c_str());
return true;
}
@@ -135,11 +141,11 @@ static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &h
hdr.size = in->readUint32LE();
hdr.ver = in->readUint32LE();
in->read(hdr.name, sizeof(hdr.name));
- return !in->ioFailed() && hdr.type == MKID_BE('SCVM');
+ return !in->err() && hdr.type == MKID_BE('SCVM');
}
bool ScummEngine::loadState(int slot, bool compat) {
- char filename[256];
+ Common::String filename;
Common::SeekableReadStream *in;
int i, j;
SaveGameHeader hdr;
@@ -147,15 +153,15 @@ bool ScummEngine::loadState(int slot, bool compat) {
if (_saveLoadSlot == 255) {
// Allow custom filenames for save game system in HE Games
- memcpy(filename, _saveLoadFileName, sizeof(_saveLoadFileName));
+ filename = _saveLoadFileName;
} else {
- makeSavegameName(filename, slot, compat);
+ filename = makeSavegameName(slot, compat);
}
- if (!(in = _saveFileMan->openForLoading(filename)))
+ if (!(in = _saveFileMan->openForLoading(filename.c_str())))
return false;
if (!loadSaveGameHeader(in, hdr)) {
- warning("Invalid savegame '%s'", filename);
+ warning("Invalid savegame '%s'", filename.c_str());
delete in;
return false;
}
@@ -171,30 +177,30 @@ bool ScummEngine::loadState(int slot, bool compat) {
// 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);
+ warning("Invalid version of '%s'", filename.c_str());
delete in;
return false;
}
// We (deliberately) broke HE savegame compatibility at some point.
if (hdr.ver < VER(50) && _game.heversion >= 71) {
- warning("Unsupported version of '%s'", filename);
+ warning("Unsupported version of '%s'", filename.c_str());
delete in;
return false;
}
// Since version 52 a thumbnail is saved directly after the header.
if (hdr.ver >= VER(52)) {
- uint32 type = in->readUint32BE();
- // 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_BE('THMB') || (hdr.ver < VER(55) && type == MKID_BE('BMHT')))){
- warning("Can not load thumbnail");
- delete in;
- return false;
+ // Prior to version 75 we always required an thumbnail to be present
+ if (hdr.ver <= VER(74)) {
+ if (!Graphics::checkThumbnailHeader(*in)) {
+ warning("Can not load thumbnail");
+ delete in;
+ return false;
+ }
}
- uint32 size = in->readUint32BE();
- in->skip(size - 8);
+
+ Graphics::skipThumbnailHeader(*in);
}
// Since version 56 we save additional information about the creation of
@@ -275,7 +281,7 @@ bool ScummEngine::loadState(int slot, bool compat) {
delete in;
// Update volume settings
- updateSoundSettings();
+ syncSoundSettings();
// Init NES costume data
if (_game.platform == Common::kPlatformNES) {
@@ -385,7 +391,7 @@ bool ScummEngine::loadState(int slot, bool compat) {
if (VAR_VOICE_MODE != 0xFF)
VAR(VAR_VOICE_MODE) = ConfMan.getBool("subtitles");
- debug(1, "State loaded from '%s'", filename);
+ debug(1, "State loaded from '%s'", filename.c_str());
_sound->pauseSounds(false);
@@ -401,23 +407,24 @@ bool ScummEngine::loadState(int slot, bool compat) {
return true;
}
-void ScummEngine::makeSavegameName(char *out, int slot, bool temporary) {
- sprintf(out, "%s.%c%.2d", _targetName.c_str(), temporary ? 'c' : 's', slot);
+Common::String ScummEngine::makeSavegameName(const Common::String &target, int slot, bool temporary) {
+ char extension[6];
+ snprintf(extension, sizeof(extension), ".%c%02d", temporary ? 'c' : 's', slot);
+ return (target + extension);
}
void ScummEngine::listSavegames(bool *marks, int num) {
assert(marks);
- char prefix[256];
char slot[3];
int slotNum;
Common::StringList files;
- makeSavegameName(prefix, 99, false);
- prefix[strlen(prefix)-2] = '*';
- prefix[strlen(prefix)-1] = 0;
+ Common::String prefix = makeSavegameName(99, false);
+ prefix.setChar('*', prefix.size()-2);
+ prefix.setChar(0, prefix.size()-1);
memset(marks, false, num * sizeof(bool)); //assume no savegames for this title
- files = _saveFileMan->listSavefiles(prefix);
+ files = _saveFileMan->listSavefiles(prefix.c_str());
for (Common::StringList::const_iterator file = files.begin(); file != files.end(); ++file) {
//Obtain the last 2 digits of the filename, since they correspond to the save slot
@@ -436,11 +443,10 @@ bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion
bool ScummEngine::getSavegameName(int slot, Common::String &desc) {
Common::InSaveFile *in = 0;
bool result = false;
- char filename[256];
desc.clear();
- makeSavegameName(filename, slot, false);
- in = _saveFileMan->openForLoading(filename);
+ Common::String filename = makeSavegameName(slot, false);
+ in = _saveFileMan->openForLoading(filename.c_str());
if (in) {
result = Scumm::getSavegameName(in, desc, _game.heversion);
delete in;
@@ -474,13 +480,15 @@ bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion
return true;
}
-Graphics::Surface *ScummEngine::loadThumbnailFromSlot(int slot) {
- char filename[256];
+Graphics::Surface *ScummEngine::loadThumbnailFromSlot(const char *target, int slot) {
Common::SeekableReadStream *in;
SaveGameHeader hdr;
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
+ if (slot < 0)
+ return 0;
+
+ Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename.c_str()))) {
return 0;
}
@@ -496,19 +504,29 @@ Graphics::Surface *ScummEngine::loadThumbnailFromSlot(int slot) {
return 0;
}
- Graphics::Surface *thumb = loadThumbnail(in);
+ Graphics::Surface *thumb = 0;
+ if (Graphics::checkThumbnailHeader(*in)) {
+ thumb = new Graphics::Surface();
+ assert(thumb);
+ if (!Graphics::loadThumbnail(*in, *thumb)) {
+ delete thumb;
+ thumb = 0;
+ }
+ }
delete in;
return thumb;
}
-bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
- char filename[256];
+bool ScummEngine::loadInfosFromSlot(const char *target, int slot, InfoStuff *stuff) {
Common::SeekableReadStream *in;
SaveGameHeader hdr;
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
+ if (slot < 0)
+ return 0;
+
+ Common::String filename = makeSavegameName(target, slot, false);
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename.c_str()))) {
return false;
}
@@ -524,16 +542,8 @@ bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
return false;
}
- uint32 type = in->readUint32BE();
-
- // 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_BE('THMB') || (hdr.ver < VER(55) && type == MKID_BE('BMHT')))){
- delete in;
+ if (!Graphics::skipThumbnailHeader(*in))
return false;
- }
- uint32 size = in->readUint32BE();
- in->skip(size - 8);
if (!loadInfos(in, stuff)) {
delete in;
@@ -588,14 +598,13 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff)
stuff->playtime = section.playtime;
// Skip over the remaining (unsupported) data
- if (section.size > SaveInfoSectionSize) {
+ if (section.size > SaveInfoSectionSize)
file->skip(section.size - SaveInfoSectionSize);
- }
return true;
}
-void ScummEngine::saveInfos(Common::OutSaveFile* file) {
+void ScummEngine::saveInfos(Common::WriteStream* file) {
SaveInfoSection section;
section.type = MKID_BE('INFO');
section.version = INFOSECTION_VERSION;
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 0ddb4e5d2a..4f9899f961 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -31,7 +31,7 @@
namespace Common {
class SeekableReadStream;
- class OutSaveFile;
+ class WriteStream;
}
namespace Scumm {
@@ -50,7 +50,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 73
+#define CURRENT_VER 75
/**
* An auxillary macro, used to specify savegame versions. We use this instead
@@ -125,7 +125,7 @@ struct SaveLoadEntry {
class Serializer {
public:
- Serializer(Common::SeekableReadStream *in, Common::OutSaveFile *out, uint32 savegameVersion)
+ Serializer(Common::SeekableReadStream *in, Common::WriteStream *out, uint32 savegameVersion)
: _loadStream(in), _saveStream(out),
_savegameVersion(savegameVersion)
{ }
@@ -151,7 +151,7 @@ public:
protected:
Common::SeekableReadStream *_loadStream;
- Common::OutSaveFile *_saveStream;
+ Common::WriteStream *_saveStream;
uint32 _savegameVersion;
void saveArrayOf(void *b, int len, int datasize, byte filetype);
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 9268768f2e..642627d649 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -625,10 +625,10 @@ void ScummEngine::writeVar(uint var, int value) {
if (var == VAR_CHARINC) {
if (ConfMan.hasKey("talkspeed")) {
- value = getTalkspeed();
+ value = getTalkDelay();
} else {
// Save the new talkspeed value to ConfMan
- setTalkspeed(value);
+ setTalkDelay(value);
}
}
@@ -769,14 +769,14 @@ void ScummEngine::runInventoryScript(int i) {
args[0] = i;
if (VAR(VAR_INVENTORY_SCRIPT)) {
if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh) {
- inventoryScript();
+ inventoryScriptIndy3Mac();
} else {
runScript(VAR(VAR_INVENTORY_SCRIPT), 0, 0, args);
}
}
}
-void ScummEngine::inventoryScript() {
+void ScummEngine::inventoryScriptIndy3Mac() {
VerbSlot *vs;
int args[24];
int j, slot;
@@ -1201,11 +1201,11 @@ void ScummEngine::runInputScript(int clickArea, int val, int mode) {
if (clickArea == kVerbClickArea && (val >= 101 && val <= 108)) {
if (val == 107) {
VAR(67) -= 2;
- inventoryScript();
+ inventoryScriptIndy3Mac();
return;
} else if (val == 108) {
VAR(67) += 2;
- inventoryScript();
+ inventoryScriptIndy3Mac();
return;
} else {
args[0] = 3;
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 431321f459..c5c055249e 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1402,7 +1402,7 @@ void ScummEngine_v5::o5_ifClassOfIs() {
while ((_opcode = fetchScriptByte()) != 0xFF) {
cls = getVarOrDirectWord(PARAM_1);
b = getClass(act, cls);
- if (cls & 0x80 && !b || !(cls & 0x80) && b)
+ if (((cls & 0x80) && !b) || (!(cls & 0x80) && b))
cond = false;
}
if (cond)
@@ -1769,7 +1769,7 @@ void ScummEngine_v5::o5_systemOps() {
pauseGame();
break;
case 3: // SO_QUIT
- shutDown();
+ quitGame();
break;
default:
error("o5_systemOps: unknown subopcode %d", subOp);
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index 04ea53137b..c8534396db 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -2310,7 +2310,7 @@ void ScummEngine_v6::o6_systemOps() {
pauseGame();
break;
case 160: // SO_QUIT
- shutDown();
+ quitGame();
break;
default:
error("o6_systemOps invalid case %d", subOp);
@@ -2374,7 +2374,7 @@ void ScummEngine_v6::o6_printEgo() {
void ScummEngine_v6::o6_talkActor() {
int offset = _scriptPointer - _scriptOrgPointer;
- // WORKAROUNDfor bug #896489: see below for detailed description
+ // WORKAROUND for bug #896489: see below for detailed description
if (_forcedWaitForMessage) {
if (VAR(VAR_HAVE_MSG)) {
_scriptPointer--;
@@ -2390,6 +2390,15 @@ void ScummEngine_v6::o6_talkActor() {
_actorToPrintStrFor = pop();
+ // WORKAROUND for bug #2016521: "DOTT: Bernard impersonating LaVerne"
+ // Original script did not check for VAR_EGO == 2 before executing
+ // a talkActor opcode.
+ if (_game.id == GID_TENTACLE && vm.slot[_currentScript].number == 307
+ && VAR(VAR_EGO) != 2 && _actorToPrintStrFor == 2) {
+ _scriptPointer += resStrLen(_scriptPointer) + 1;
+ return;
+ }
+
_string[0].loadDefault();
actorTalk(_scriptPointer);
diff --git a/engines/scumm/script_v8.cpp b/engines/scumm/script_v8.cpp
index 08629afb07..8859435dc9 100644
--- a/engines/scumm/script_v8.cpp
+++ b/engines/scumm/script_v8.cpp
@@ -424,10 +424,10 @@ void ScummEngine_v8::writeVar(uint var, int value) {
if (var == VAR_CHARINC) {
if (ConfMan.hasKey("talkspeed")) {
- value = getTalkspeed();
+ value = getTalkDelay();
} else {
// Save the new talkspeed value to ConfMan
- setTalkspeed(value);
+ setTalkDelay(value);
}
}
@@ -1170,7 +1170,7 @@ void ScummEngine_v8::o8_systemOps() {
restart();
break;
case 0x29: // SO_SYSTEM_QUIT Quit game
- shutDown();
+ quitGame();
break;
default:
error("o8_systemOps: invalid case 0x%x", subOp);
@@ -1289,7 +1289,7 @@ void ScummEngine_v8::o8_kernelSetFunctions() {
if (ConfMan.getBool("confirm_exit"))
confirmExitDialog();
else
- _quit = true;
+ quitGame();
break;
case 108: // buildPaletteShadow
setShadowPalette(args[1], args[2], args[3], args[4], args[5], args[6]);
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index ce8f0a4d9a..b220779c55 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Mon Jul 28 00:13:01 2008
+ This file was generated by the md5table tool on Tue Sep 23 12:32:31 2008
DO NOT EDIT MANUALLY!
*/
@@ -54,6 +54,7 @@ static const MD5Table md5table[] = {
{ "0f5935bd5e88ba6f09e558d64459746d", "thinker1", "", "Demo", 30919, Common::EN_USA, Common::kPlatformWindows },
{ "0f6f2e716ba896a44e5059bba1de7ca9", "samnmax", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "0f9c7a76657f0840b8f7ccb5bffeb9f4", "indy3", "No Adlib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST },
+ { "0f9d3317910ac7a9f449243118884ada", "puttzoo", "", "", 42070, Common::DE_DEU, Common::kPlatformWindows },
{ "0fb73eddfcf584c02ba097984df131ba", "samnmax", "", "CD", 9080, Common::DE_DEU, Common::kPlatformUnknown },
{ "1005456bfe351c1b679e1ff2dc2849e9", "puttzoo", "", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "100b4c8403ad6a83d4bf7dbf83e44dc4", "spyfox", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
@@ -63,6 +64,7 @@ static const MD5Table md5table[] = {
{ "11e6e244078ff09b0f3832e35420e0a7", "catalog", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "132bff65e6367c09cc69318ce1b59333", "monkey2", "", "", 11155, Common::EN_ANY, Common::kPlatformAmiga },
{ "1387d16aa620dc1c2d1fd87f8a9e7a09", "puttcircus", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
+ { "13d2a86a7290813a1c386490447d72db", "fbear", "HE 61", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "145bd3373574feb668cc2eea2ec6cf86", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "14d48c95b43ddeb983254cf6c43851f1", "freddi4", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "151071053a1d0021198216713939521d", "freddi2", "HE 80", "", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -98,6 +100,7 @@ static const MD5Table md5table[] = {
{ "1ff5997c78fbd0a841a75ef15a05d9d5", "BluesBirthday", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "2012f854d83d9cc6f73b2b544cd8bbf8", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "20176076d708bf14407bcc9bdcd7a418", "pajama3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows },
+ { "204453e33456c4faa26e276229fe5b76", "spyfox2", "", "Demo", 14689, Common::DE_DEU, Common::kPlatformWindows },
{ "20da6fce37805423966aaa8f3c2426aa", "atlantis", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "2108d83dcf09f8adb4bc524669c8cf51", "PuttTime", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "21a6592322f92550f144f68a8a4e685e", "dig", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
@@ -106,6 +109,7 @@ static const MD5Table md5table[] = {
{ "225e18566e810c634bf7de63e7568e3e", "mustard", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "22c9eb04455440131ffc157aeb8d40a8", "fbear", "HE 70", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "22d07d6c386c9c25aca5dac2a0c0d94b", "maniac", "NES", "", 262144, Common::SE_SWE, Common::kPlatformNES },
+ { "22de86b2f7ec6e5db745ed1123310b44", "spyfox2", "", "Demo", 15832, Common::FR_FRA, Common::kPlatformWindows },
{ "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "23394c8d29cc63c61313959431a12476", "spyfox", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "257f8c14d8c584f7ddd601bcb00920c7", "maniac", "NES", "", 262144, Common::DE_DEU, Common::kPlatformNES },
@@ -144,6 +148,7 @@ static const MD5Table md5table[] = {
{ "362c1d281fb9899254cda66ad246c66a", "dig", "Demo", "Demo", 3472, Common::EN_ANY, Common::kPlatformUnknown },
{ "3686cf8f89e102ececf4366e1d2c8126", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformPC },
{ "36a6750e03fb505fc19fc2bf3e4dbe91", "pajama2", "", "Demo", 58749, Common::EN_ANY, Common::kPlatformUnknown },
+ { "3769b56c9a22f5521d74525ee459f88d", "puttrace", "HE 99", "Demo", 13108, Common::DE_DEU, Common::kPlatformWindows },
{ "37aed3f91c1ef959e0bd265f9b13781f", "pajama", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "37f56ceb13e401a7ac7d9e6b37fecaf7", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformPC },
{ "37ff1b308999c4cca7319edfcc1280a0", "puttputt", "HE 70", "Demo", 8269, Common::EN_ANY, Common::kPlatformWindows },
@@ -201,6 +206,7 @@ static const MD5Table md5table[] = {
{ "4edbf9d03550f7ba01e7f34d69b678dd", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "4f04b321a95d4315ce6d65f8e1dd0368", "maze", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "4f138ac6f9b2ac5a41bc68b2c3296064", "freddi4", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
+ { "4f1d6f8b38343dba405472538b5037ed", "fbear", "HE 61", "", 7717, Common::EN_ANY, Common::kPlatformPC },
{ "4f267a901719623de7dde83e47d5b474", "atlantis", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "4f580a021eee026f3b4589e17d130d78", "freddi4", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown },
{ "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
@@ -208,6 +214,7 @@ static const MD5Table md5table[] = {
{ "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows },
+ { "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
{ "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "51305e929e330e24a75a0351c8f9975e", "freddi2", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "513f91a9dbe8d5490b39e56a3ac5bbdf", "pajama2", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
@@ -219,8 +226,10 @@ static const MD5Table md5table[] = {
{ "55d3987641bf229c83bc729210173383", "zak", "V1", "", -1, Common::EN_ANY, Common::kPlatformC64 },
{ "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows },
+ { "5719fc8a13b4638b78d9d8d12f091f94", "puttrace", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "5798972220cd458be2626d54c80f71d7", "atlantis", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "57a17febe2183f521250e55d55b83e60", "PuttTime", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
+ { "57a5cfec9ef231a007043cc1917e8988", "freddi", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
{ "57b0d89af79befe1cabce3bece869e7f", "tentacle", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
{ "58436e634f4fae1d9973591c2ffa1fcb", "spyfox", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "589601b676c98b1c0c987bc031ab68b3", "chase", "HE 95", "", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -244,6 +253,7 @@ static const MD5Table md5table[] = {
{ "6269b8fbf51a353e5b501e4ad98cdc67", "arttime", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "6271130f440066830eca9056c1d7926f", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "62b8c16b6db226ba95aaa8be73f9885c", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformAmiga },
+ { "632d2fddb8ba97723fa15334763ae857", "thinker1", "", "", 33270, Common::EN_ANY, Common::kPlatformWindows },
{ "63fdcdc95cdeea00060883aed38e5504", "PuttTime", "HE 85", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "6508fd55530e6915507e1cc37f7f045d", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "65563295c3a06493351870f20a1630cf", "spyozon", "HE CUP", "Preview", 5235008, Common::UNK_LANG, Common::kPlatformUnknown },
@@ -272,6 +282,7 @@ static const MD5Table md5table[] = {
{ "6b27dbcd8d5697d5c918eeca0f68ef6a", "puttrace", "HE CUP", "Preview", 3901484, Common::UNK_LANG, Common::kPlatformUnknown },
{ "6b3ec67da214f558dc5ceaa2acd47453", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "6b5a3fef241e90d4b2e77f1e222773ee", "maniac", "NES", "extracted", -1, Common::SE_SWE, Common::kPlatformNES },
+ { "6bca7a1a96d16e52b8f3c42b50dbdca3", "fbear", "HE 61", "", -1, Common::JA_JPN, Common::kPlatform3DO },
{ "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", "", "", 49221, Common::UNK_LANG, Common::kPlatformWindows },
{ "6c2bff0e327f2962e809c2e1a82d7309", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
@@ -296,14 +307,17 @@ static const MD5Table md5table[] = {
{ "73e5ab7dbb9a8061cc6d25df02dbd1e7", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "7410a8ba9795020cd42f171c4320659e", "pajama3", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "746e88c172a5b7a1ae89ac0ee3ee681a", "freddi", "HE 90", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
+ { "74da3494fbe1a7d20213b0afe0954755", "catalog", "HE CUP", "Preview", 10841544, Common::FR_FRA, Common::kPlatformUnknown },
{ "754feb59d3bf86b8a00840df74fd7b26", "freddi3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "75ba23fff4fd63fa446c02864f2a5a4b", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "75bff95816b84672b877d22a911ab811", "freddi3", "HE 99", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "76b66b43e593ad4d2f1dfb5cc8f19700", "spyfox", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "771bc18ec6f93837b839c992b211904b", "monkey", "Demo", "EGA Demo", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "7766c9487f9d53a8cb0edabda5119c3d", "puttputt", "HE 60", "", 8022, Common::EN_ANY, Common::kPlatformPC },
{ "77f5c9cc0986eb729c1a6b4c8823bbae", "zak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "780e4a0ae2ff17dc296f4a79543b44f8", "puttmoon", "", "", -1, Common::UNK_LANG, Common::kPlatformPC },
{ "782393c5934ecd0b536eaf5fd541bd26", "pajama", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "784b499c98d07260a30952685758636b", "pajama3", "", "Demo", 13911, Common::DE_DEU, Common::kPlatformWindows },
{ "78bd5f036ea35a878b74e4f47941f784", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformPC },
@@ -322,6 +336,7 @@ static const MD5Table md5table[] = {
{ "81bbfa181184cb494e7a81dcfa94fbd9", "maniac", "NES", "", 262144, Common::FR_FRA, Common::kPlatformNES },
{ "8299d9b8a1b0e7b881bae7a9971dc5e2", "zak", "V2", "Demo", 1916, Common::EN_ANY, Common::kPlatformAtariST },
{ "8368f552b1e3eba559f8d559bcc4cadb", "freddi3", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown },
+ { "839a658f7d22de00787ebc945348cdb6", "dog", "", "", 19681, Common::DE_DEU, Common::kPlatformWindows },
{ "83cedbe26aa8b58988e984e3d34cac8e", "freddi3", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "84e3c23a49ded8a6f9197735c8eb3de7", "PuttTime", "HE 85", "", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "8539c0ff89868e55a08e652ac44daaae", "water", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
@@ -330,6 +345,7 @@ static const MD5Table md5table[] = {
{ "86c9902b7bec1a17926d4dae85beaa45", "airport", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "870d1e3c86bc50846d808d14a36b4e08", "monkey", "VGA", "VGA", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "8776caed014c321272af407c1502a2df", "monkey", "CD", "", 8955, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "87df3e0074624040407764b7c5e710b9", "pajama", "", "Demo", 18354, Common::NL_NLD, Common::kPlatformWindows },
{ "87f6e8037b7cc996e13474b491a7a98e", "maniac", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "8801fb4a1200b347f7a38523339526dd", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
@@ -394,12 +410,14 @@ static const MD5Table md5table[] = {
{ "a0a7dea72003933b8b3f8b99b9f7ddeb", "loom", "No Adlib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
{ "a194f15f51ee62badab74b9e7da97693", "baseball2001", "", "Demo", 20507, Common::EN_ANY, Common::kPlatformUnknown },
{ "a197a87ae77f3b3333f09a7a2c448fe2", "freddi", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
+ { "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows },
{ "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows },
{ "a3036878840720fbefa41e6965fa4a0a", "samnmax", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAtariST },
+ { "a5c5388da9bf0e6662fdca8813a79d13", "farm", "", "", 86962, Common::EN_ANY, Common::kPlatformWindows },
{ "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "a85856675429fe88051744f755b72f93", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -429,10 +447,13 @@ static const MD5Table md5table[] = {
{ "b886b0a5d909c7158a914e1d7c1c6c65", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC },
{ "b8955d7d23b4972229060d1592489fef", "freddicove", "HE 100", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "b9ba19ce376efc69be78ef3baef8d2b9", "monkey", "CD", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "b9bb68c5d2c9b6e2d9c513a29a754a57", "puttmoon", "", "", 7828, Common::EN_ANY, Common::kPlatformPC },
{ "ba888e6831517597859e91aa173f945c", "spyfox", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown },
+ { "bab0fb81dcb12b8930c5d850b8f2a7de", "balloon", "HE 80", "", 12800, Common::DE_DEU, Common::kPlatformWindows },
{ "bbadf7309c4a2c2763e4bbba3c3be634", "freddi3", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "bc4700bc0e12879f6d25d14d6be6cfdd", "spyfox2", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "bd126753de619a495f9f22adc951c8d5", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "bd5fd7835335dfce03064d5f77b7f0ae", "dog", "", "", 19681, Common::NL_NLD, Common::kPlatformWindows },
{ "be2abe172f58db170de3a037daa1dd27", "puttputt", "HE 61", "", -1, Common::JA_JPN, Common::kPlatform3DO },
{ "be39a5d4db60e8aa736b9086778cb45c", "spyozon", "", "", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "be83e882b44f2767bc08d4f766ebc347", "maniac", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAtariST },
@@ -441,6 +462,7 @@ static const MD5Table md5table[] = {
{ "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "c0d5c89550381ac433624fedad5e1100", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine },
{ "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD },
+ { "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
{ "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "c30ef068add4277104243c31ce46c12b", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformAmiga },
@@ -546,6 +568,7 @@ static const MD5Table md5table[] = {
{ "ed361270102e355afe5236954216aba2", "lost", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "edfdb24a499d92c59f824c52987c0eec", "atlantis", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "ee41f6afbc5b26fa475754b56fe92048", "puttputt", "HE 61", "", 8032, Common::JA_JPN, Common::kPlatform3DO },
{ "ee785fe2569bc9965526e774f7ab86f1", "spyfox", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "ef347474f3c7be3b29584eaa133cca05", "samnmax", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
@@ -566,6 +589,7 @@ static const MD5Table md5table[] = {
{ "f8be685007a8b425ba2a455da732f59f", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "fa127d7c4bb47d05bb1c33ddcaa9f767", "loom", "EGA", "EGA", 5748, Common::DE_DEU, Common::kPlatformPC },
{ "fa30c4a7a806629626269b6dcab59a15", "BluesBirthday", "HE CUP", "Preview", 7819264, Common::UNK_LANG, Common::kPlatformUnknown },
+ { "fa84cb1018103a4ee4e5fa8041c1d0d1", "freddi4", "", "Demo", 13609, Common::DE_DEU, Common::kPlatformWindows },
{ "fb66aa42de21675116346213f176a366", "monkey", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "fbb697d89d2beca87360a145f467bdae", "PuttTime", "HE 90", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "fbbbb38a81fc9d6a61d509278390a290", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 2f0593dca8..a10af41145 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -109,7 +109,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_language(dr.language),
_debugger(0),
_currentScript(0xFF), // Let debug() work on init stage
- _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0) {
+ _pauseDialog(0), _scummMenuDialog(0), _versionDialog(0) {
if (_game.platform == Common::kPlatformNES) {
_gdi = new GdiNES(this);
@@ -143,9 +143,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_objs = NULL;
_sound = NULL;
memset(&vm, 0, sizeof(vm));
- _quit = false;
_pauseDialog = NULL;
- _mainMenuDialog = NULL;
+ _scummMenuDialog = NULL;
_versionDialog = NULL;
_fastMode = 0;
_actors = NULL;
@@ -561,7 +560,7 @@ ScummEngine::~ScummEngine() {
delete _2byteFontPtr;
delete _charset;
delete _pauseDialog;
- delete _mainMenuDialog;
+ delete _scummMenuDialog;
delete _versionDialog;
delete _fileHandle;
@@ -815,7 +814,6 @@ ScummEngine_vCUPhe::ScummEngine_vCUPhe(OSystem *syst, const DetectorResult &dr)
_syst = syst;
_game = dr.game;
_filenamePattern = dr.fp,
- _quit = false;
_cupPlayer = new CUP_Player(syst, this, _mixer);
}
@@ -845,14 +843,13 @@ void ScummEngine_vCUPhe::parseEvents() {
Common::Event event;
while (_eventMan->pollEvent(event)) {
+#if 0
switch (event.type) {
- case Common::EVENT_QUIT:
- _quit = true;
- break;
default:
break;
}
+#endif
}
}
@@ -916,20 +913,20 @@ int ScummEngine::init() {
// Add default file directories.
if (((_game.platform == Common::kPlatformAmiga) || (_game.platform == Common::kPlatformAtariST)) && (_game.version <= 4)) {
// This is for the Amiga version of Indy3/Loom/Maniac/Zak
- File::addDefaultDirectory(_gameDataPath + "ROOMS/");
- File::addDefaultDirectory(_gameDataPath + "rooms/");
+ File::addDefaultDirectory(_gameDataDir.getChild("ROOMS"));
+ File::addDefaultDirectory(_gameDataDir.getChild("rooms"));
}
if ((_game.platform == Common::kPlatformMacintosh) && (_game.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/");
+ File::addDefaultDirectory(_gameDataDir.getChild("Rooms 1"));
+ File::addDefaultDirectory(_gameDataDir.getChild("Rooms 2"));
+ File::addDefaultDirectory(_gameDataDir.getChild("Rooms 3"));
}
#ifdef ENABLE_SCUMM_7_8
#ifdef MACOSX
- if (_game.version == 8 && !memcmp(_gameDataPath.c_str(), "/Volumes/MONKEY3_", 17)) {
+ if (_game.version == 8 && !memcmp(_gameDataDir.getPath().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)
@@ -946,16 +943,16 @@ int ScummEngine::init() {
#endif
if (_game.version == 8) {
// This is for COMI
- File::addDefaultDirectory(_gameDataPath + "RESOURCE/");
- File::addDefaultDirectory(_gameDataPath + "resource/");
+ File::addDefaultDirectory(_gameDataDir.getChild("RESOURCE"));
+ File::addDefaultDirectory(_gameDataDir.getChild("resource"));
}
if (_game.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/");
+ File::addDefaultDirectory(_gameDataDir.getChild("VIDEO"));
+ File::addDefaultDirectory(_gameDataDir.getChild("video"));
+ File::addDefaultDirectory(_gameDataDir.getChild("DATA"));
+ File::addDefaultDirectory(_gameDataDir.getChild("data"));
}
#endif
@@ -1108,7 +1105,7 @@ int ScummEngine::init() {
if (_game.version >= 5 && _game.version <= 7)
_sound->setupSound();
- updateSoundSettings();
+ syncSoundSettings();
return 0;
}
@@ -1310,6 +1307,8 @@ void ScummEngine::resetScumm() {
_actors[i] = new Actor_v2(this, i);
else if (_game.version == 3)
_actors[i] = new Actor_v3(this, i);
+ else if (_game.heversion != 0)
+ _actors[i] = new ActorHE(this, i);
else
_actors[i] = new Actor(this, i);
_actors[i]->initActor(-1);
@@ -1533,6 +1532,12 @@ void ScummEngine_v99he::resetScumm() {
byte *data = defineArray(129, kStringArray, 0, 0, 0, len);
memcpy(data, _filenamePattern.pattern, len);
}
+
+void ScummEngine_v100he::resetScumm() {
+ ScummEngine_v99he::resetScumm();
+
+ memset(_debugInputBuffer, 0, sizeof(_debugInputBuffer));
+}
#endif
void ScummEngine::setupMusic(int midi) {
@@ -1667,7 +1672,7 @@ void ScummEngine::setupMusic(int midi) {
}
}
-void ScummEngine::updateSoundSettings() {
+void ScummEngine::syncSoundSettings() {
// Sync the engine with the config manager
int soundVolumeMusic = ConfMan.getInt("music_volume");
@@ -1690,17 +1695,17 @@ void ScummEngine::updateSoundSettings() {
if (VAR_VOICE_MODE != 0xFF)
VAR(VAR_VOICE_MODE) = _voiceMode;
- _defaultTalkDelay = getTalkspeed();
+ _defaultTalkDelay = getTalkDelay();
if (VAR_CHARINC != 0xFF)
VAR(VAR_CHARINC) = _defaultTalkDelay;
}
-void ScummEngine::setTalkspeed(int talkspeed) {
- ConfMan.setInt("talkspeed", (talkspeed * 255 + 9 / 2) / 9);
+void ScummEngine::setTalkDelay(int talkdelay) {
+ ConfMan.setInt("talkspeed", ((9 - talkdelay) * 255 + 9 / 2) / 9);
}
-int ScummEngine::getTalkspeed() {
- return (ConfMan.getInt("talkspeed") * 9 + 255 / 2) / 255;
+int ScummEngine::getTalkDelay() {
+ return 9 - (ConfMan.getInt("talkspeed") * 9 + 255 / 2) / 255;
}
@@ -1721,7 +1726,7 @@ int ScummEngine::go() {
int diff = 0; // Duration of one loop iteration
- while (!_quit) {
+ while (!quit()) {
if (_debugger->isAttached())
_debugger->onFrame();
@@ -1754,7 +1759,7 @@ int ScummEngine::go() {
diff = _system->getMillis() - diff;
- if (_quit) {
+ if (quit()) {
// TODO: Maybe perform an autosave on exit?
}
}
@@ -1772,7 +1777,7 @@ void ScummEngine::waitForTimer(int msec_delay) {
start_time = _system->getMillis();
- while (!_quit) {
+ while (!quit()) {
_sound->updateCD(); // Loop CD Audio if needed
parseEvents();
_system->updateScreen();
@@ -1895,7 +1900,7 @@ load_game:
checkExecVerbs();
checkAndRunSentenceScript();
- if (_quit)
+ if (quit())
return;
// HACK: If a load was requested, immediately perform it. This avoids
@@ -2011,7 +2016,6 @@ void ScummEngine::scummLoop_handleSaveLoad() {
if (_saveLoadFlag) {
bool success;
const char *errMsg = 0;
- char filename[256];
if (_game.version == 8 && _saveTemporaryState)
VAR(VAR_GAME_LOADED) = 0;
@@ -2032,13 +2036,13 @@ void ScummEngine::scummLoop_handleSaveLoad() {
VAR(VAR_GAME_LOADED) = (_game.version == 8) ? 1 : 203;
}
- makeSavegameName(filename, _saveLoadSlot, _saveTemporaryState);
+ Common::String filename = makeSavegameName(_saveLoadSlot, _saveTemporaryState);
if (!success) {
- displayMessage(0, errMsg, filename);
+ displayMessage(0, errMsg, filename.c_str());
} 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);
+ snprintf(buf, sizeof(buf), "Successfully saved game state in file:\n\n%s", filename.c_str());
GUI::TimedMessageDialog dialog(buf, 1500);
runDialog(dialog);
@@ -2160,10 +2164,6 @@ 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
@@ -2305,18 +2305,18 @@ void ScummEngine::versionDialog() {
runDialog(*_versionDialog);
}
-void ScummEngine::mainMenuDialog() {
- if (!_mainMenuDialog)
- _mainMenuDialog = new MainMenuDialog(this);
- runDialog(*_mainMenuDialog);
- updateSoundSettings();
+void ScummEngine::scummMenuDialog() {
+ if (!_scummMenuDialog)
+ _scummMenuDialog = new ScummMenuDialog(this);
+ runDialog(*_scummMenuDialog);
+ syncSoundSettings();
}
void ScummEngine::confirmExitDialog() {
ConfirmDialog d(this, 6);
if (runDialog(d)) {
- _quit = true;
+ quitGame();
}
}
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 20824ffe74..ec733d32f4 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -46,7 +46,7 @@ namespace GUI {
using GUI::Dialog;
namespace Common {
class SeekableReadStream;
- class OutSaveFile;
+ class WriteStream;
}
namespace Scumm {
@@ -462,9 +462,9 @@ protected:
virtual void loadLanguageBundle() {}
void loadCJKFont();
void setupMusic(int midi);
- void updateSoundSettings();
- void setTalkspeed(int talkspeed);
- int getTalkspeed();
+ virtual void syncSoundSettings();
+ void setTalkDelay(int talkdelay);
+ int getTalkDelay();
// Scumm main loop & helper functions.
virtual void scummLoop(int delta);
@@ -496,22 +496,18 @@ protected:
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;
+ Dialog *_scummMenuDialog;
virtual int runDialog(Dialog &dialog);
void confirmExitDialog();
void confirmRestartDialog();
void pauseDialog();
void versionDialog();
- void mainMenuDialog();
+ void scummMenuDialog();
char displayMessage(const char *altButton, const char *message, ...);
@@ -560,7 +556,7 @@ protected:
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
+ int32 _numCharsets; // FIXME - should be protected, used by CharsetRenderer
BaseCostumeLoader *_costumeLoader;
BaseCostumeRenderer *_costumeRenderer;
@@ -618,11 +614,16 @@ protected:
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);
+
+ Common::String makeSavegameName(int slot, bool temporary) const {
+ return makeSavegameName(_targetName, slot, temporary);
+ }
int getKeyState(int key);
public:
+ static Common::String makeSavegameName(const Common::String &target, int slot, bool temporary);
+
bool getSavegameName(int slot, Common::String &desc);
void listSavegames(bool *marks, int num);
@@ -631,14 +632,19 @@ public:
// thumbnail + info stuff
public:
- Graphics::Surface *loadThumbnailFromSlot(int slot);
- bool loadInfosFromSlot(int slot, InfoStuff *stuff);
+ Graphics::Surface *loadThumbnailFromSlot(int slot) {
+ return loadThumbnailFromSlot(_targetName.c_str(), slot);
+ }
+ static Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot);
+
+ bool loadInfosFromSlot(int slot, InfoStuff *stuff) {
+ return loadInfosFromSlot(_targetName.c_str(), slot, stuff);
+ }
+ static bool loadInfosFromSlot(const char *target, int slot, InfoStuff *stuff);
protected:
- Graphics::Surface *loadThumbnail(Common::SeekableReadStream *file);
- bool loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff);
- void saveThumbnail(Common::OutSaveFile *file);
- void saveInfos(Common::OutSaveFile* file);
+ void saveInfos(Common::WriteStream* file);
+ static bool loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff);
int32 _engineStartTime;
int32 _pauseStartTime;
@@ -673,7 +679,7 @@ protected:
void executeScript();
void updateScriptPtr();
virtual void runInventoryScript(int i);
- void inventoryScript();
+ void inventoryScriptIndy3Mac();
void checkAndRunSentenceScript();
void runExitScript();
void runEntryScript();
@@ -912,7 +918,7 @@ public:
// Generic costume code
bool isCostumeInUse(int i) const;
- Common::Rect _actorClipOverride;
+ Common::Rect _actorClipOverride; // HE specific
protected:
/* Should be in Graphics class? */
diff --git a/engines/scumm/smush/channel.h b/engines/scumm/smush/channel.h
index 52fec22e0e..1e023e08ff 100644
--- a/engines/scumm/smush/channel.h
+++ b/engines/scumm/smush/channel.h
@@ -28,10 +28,11 @@
#include "common/util.h"
-namespace Scumm {
+namespace Common {
+ class SeekableReadStream;
+}
-class Chunk;
-class ContChunk;
+namespace Scumm {
class SmushChannel {
protected:
@@ -55,7 +56,7 @@ protected:
public:
SmushChannel(int32 track);
virtual ~SmushChannel();
- virtual bool appendData(Chunk &b, int32 size) = 0;
+ virtual bool appendData(Common::SeekableReadStream &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;
@@ -83,7 +84,7 @@ public:
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);
+ bool appendData(Common::SeekableReadStream &b, int32 size);
byte *getSoundData();
int32 getRate() { return 22050; }
bool getParameters(bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) {
@@ -105,7 +106,7 @@ private:
protected:
void decode();
- bool handleMap(Chunk &c);
+ bool handleMap(byte *data);
bool handleSubTags(int32 &offset);
public:
@@ -113,7 +114,7 @@ public:
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);
+ bool appendData(Common::SeekableReadStream &b, int32 size);
byte *getSoundData();
int32 getRate() { return _rate; }
bool getParameters(bool &stereo, bool &is_16bit, int32 &vol, int32 &pan) {
diff --git a/engines/scumm/smush/chunk.cpp b/engines/scumm/smush/chunk.cpp
deleted file mode 100644
index 5e6f05b3e4..0000000000
--- a/engines/scumm/smush/chunk.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-
-#include "scumm/smush/chunk.h"
-#include "scumm/scumm.h"
-#include "scumm/file.h"
-
-#include "common/file.h"
-#include "common/str.h"
-#include "common/util.h"
-
-namespace Scumm {
-
-BaseChunk::BaseChunk() :
- _type(0),
- _size(0),
- _curPos(0),
- _name("") {
-}
-
-bool BaseChunk::eos() const {
- return _curPos >= _size;
-}
-
-uint32 BaseChunk::pos() const {
- return _curPos;
-}
-
-Chunk::type BaseChunk::getType() const {
- return _type;
-}
-
-uint32 BaseChunk::size() const {
- return _size;
-}
-
-void BaseChunk::seek(int32 delta, int dir) {
- switch (dir) {
- case SEEK_CUR:
- _curPos += delta;
- break;
- case SEEK_SET:
- 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;
- default:
- break;
- }
-
- if (_curPos > _size) {
- // It may happen that user misused our SAN compression tool
- // and ignored FLU index for videos which are used by INSANE.
- // This will lead to incorrect seek requests
- //
- // In fact it may happen only within INSANE, so do not even check for it
- warning("Looks like you compressed file %s in wrong way. It has FLU index which was not updated", _name.c_str());
- error("invalid seek request : %d > %d (delta == %d)", _curPos, _size, delta);
- }
-}
-
-FileChunk::FileChunk(BaseScummFile *data, int offset) {
- _data = data;
- _deleteData = false;
-
- _data->seek(offset, SEEK_SET);
- _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))
- error("FileChunk: Unable to open file %s", name.c_str());
-
- _data->seek(offset, SEEK_SET);
- _type = _data->readUint32BE();
- _size = _data->readUint32BE();
- _offset = _data->pos();
- _curPos = 0;
- _name = name;
-}
-
-FileChunk::~FileChunk() {
- if (_deleteData)
- delete _data;
-}
-
-Chunk *FileChunk::subBlock() {
- FileChunk *ptr = new FileChunk(_data, _offset + _curPos);
- skip(sizeof(Chunk::type) + sizeof(uint32) + ptr->size());
- return ptr;
-}
-
-void FileChunk::reseek() {
- _data->seek(_offset + _curPos, SEEK_SET);
-}
-
-uint32 FileChunk::read(void *buffer, uint32 dataSize) {
- if (dataSize <= 0 || (_curPos + dataSize) > _size)
- error("invalid buffer read request");
-
- dataSize = _data->read(buffer, dataSize);
- _curPos += dataSize;
-
- return dataSize;
-}
-
-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);
- skip(sizeof(Chunk::type) + sizeof(uint32) + ptr->size());
- return ptr;
-}
-
-void MemoryChunk::reseek() {
-}
-
-uint32 MemoryChunk::read(void *buffer, uint32 dataSize) {
- if (dataSize <= 0 || (_curPos + dataSize) > _size)
- error("invalid buffer read request");
-
- memcpy(buffer, _data + _curPos, dataSize);
- _curPos += dataSize;
- return dataSize;
-}
-
-} // End of namespace Scumm
diff --git a/engines/scumm/smush/chunk.h b/engines/scumm/smush/chunk.h
deleted file mode 100644
index ca4a3cdd99..0000000000
--- a/engines/scumm/smush/chunk.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifndef SCUMM_SMUSH_CHUNK_H
-#define SCUMM_SMUSH_CHUNK_H
-
-#include "common/scummsys.h"
-#include "common/str.h"
-#include "common/stream.h"
-
-namespace Scumm {
-
-class BaseScummFile;
-
-class Chunk : public Common::SeekableReadStream {
-public:
- typedef uint32 type;
-
- virtual type getType() const = 0;
- virtual Chunk *subBlock() = 0;
- virtual void reseek() = 0;
-};
-
-// Common functionality for concrete chunks (FileChunk, MemoryChunk)
-class BaseChunk : public Chunk {
-protected:
- Chunk::type _type;
- uint32 _size;
- uint32 _curPos;
- Common::String _name;
-
- BaseChunk();
-
-public:
- Chunk::type getType() const;
- uint32 size() const;
- bool eos() const;
- uint32 pos() const;
- void seek(int32 delta, int dir);
-};
-
-class FileChunk : public BaseChunk {
-private:
- BaseScummFile *_data;
- bool _deleteData;
- uint32 _offset;
-
- FileChunk(BaseScummFile *data, int offset);
-public:
- FileChunk(const Common::String &name, int offset = 0);
- virtual ~FileChunk();
- Chunk *subBlock();
- void reseek();
- uint32 read(void *buffer, uint32 size);
-};
-
-class MemoryChunk : public BaseChunk {
-private:
- byte *_data;
-
-public:
- MemoryChunk(byte *data);
- Chunk *subBlock();
- void reseek();
- uint32 read(void *buffer, uint32 size);
-};
-
-} // End of namespace Scumm
-
-#endif
diff --git a/engines/scumm/smush/imuse_channel.cpp b/engines/scumm/smush/imuse_channel.cpp
index 822f32a896..fd34a8f60d 100644
--- a/engines/scumm/smush/imuse_channel.cpp
+++ b/engines/scumm/smush/imuse_channel.cpp
@@ -29,7 +29,6 @@
#include "scumm/scumm.h" // For DEBUG_SMUSH
#include "scumm/util.h"
#include "scumm/smush/channel.h"
-#include "scumm/smush/chunk.h"
namespace Scumm {
@@ -60,10 +59,10 @@ bool ImuseChannel::checkParameters(int32 index, int32 nbframes, int32 size, int3
return true;
}
-bool ImuseChannel::appendData(Chunk &b, int32 size) {
+bool ImuseChannel::appendData(Common::SeekableReadStream &b, int32 size) {
if (_dataSize == -1) {
assert(size > 8);
- Chunk::type imus_type = b.readUint32BE();
+ uint32 imus_type = b.readUint32BE();
/*uint32 imus_size =*/ b.readUint32BE();
if (imus_type != MKID_BE('iMUS'))
error("Invalid Chunk for imuse_channel");
@@ -104,35 +103,45 @@ bool ImuseChannel::appendData(Chunk &b, int32 size) {
return true;
}
-bool ImuseChannel::handleMap(Chunk &map) {
- while (!map.eos()) {
- Chunk *sub = map.subBlock();
- switch (sub->getType()) {
+bool ImuseChannel::handleMap(byte *data) {
+ // Read the chunk size & skip over the chunk header
+ int32 size = READ_BE_UINT32(data + 4);
+ data += 8;
+
+ while (size > 0) {
+ uint32 subType = READ_BE_UINT32(data);
+ int32 subSize = READ_BE_UINT32(data + 4);
+ data += 8;
+ size -= 8;
+
+ switch (subType) {
case MKID_BE('FRMT'):
- if (sub->size() != 20)
+ if (subSize != 20)
error("invalid size for FRMT Chunk");
- /*uint32 imuse_start =*/ sub->readUint32BE();
- sub->skip(4);
- _bitsize = sub->readUint32BE();
- _rate = sub->readUint32BE();
- _channels = sub->readUint32BE();
+ //uint32 imuse_start = READ_BE_UINT32(data);
+ //uint32 unk = READ_BE_UINT32(data+4);
+ _bitsize = READ_BE_UINT32(data+8);
+ _rate = READ_BE_UINT32(data+12);
+ _channels = READ_BE_UINT32(data+16);
assert(_channels == 1 || _channels == 2);
break;
case MKID_BE('TEXT'):
// Ignore this
break;
case MKID_BE('REGN'):
- if (sub->size() != 8)
+ if (subSize != 8)
error("invalid size for REGN Chunk");
break;
case MKID_BE('STOP'):
- if (sub->size() != 4)
+ if (subSize != 4)
error("invalid size for STOP Chunk");
break;
default:
- error("Unknown iMUS subChunk found : %s, %d", tag2str(sub->getType()), sub->size());
+ error("Unknown iMUS subChunk found : %s, %d", tag2str(subType), subSize);
}
- delete sub;
+
+ data += subSize;
+ size -= subSize;
}
return true;
}
@@ -187,15 +196,14 @@ void ImuseChannel::decode() {
bool ImuseChannel::handleSubTags(int32 &offset) {
if (_tbufferSize - offset >= 8) {
- Chunk::type type = READ_BE_UINT32(_tbuffer + offset);
+ uint32 type = READ_BE_UINT32(_tbuffer + offset);
uint32 size = READ_BE_UINT32(_tbuffer + offset + 4);
uint32 available_size = _tbufferSize - offset;
switch (type) {
case MKID_BE('MAP '):
_inData = false;
if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- handleMap(c);
+ handleMap((byte *)_tbuffer + offset);
}
break;
case MKID_BE('DATA'):
diff --git a/engines/scumm/smush/saud_channel.cpp b/engines/scumm/smush/saud_channel.cpp
index 2fe34efe29..a56afa8f44 100644
--- a/engines/scumm/smush/saud_channel.cpp
+++ b/engines/scumm/smush/saud_channel.cpp
@@ -25,10 +25,10 @@
#include "common/endian.h"
+#include "common/stream.h"
#include "scumm/util.h"
#include "scumm/smush/channel.h"
-#include "scumm/smush/chunk.h"
namespace Scumm {
@@ -45,7 +45,7 @@ bool SaudChannel::isTerminated() const {
bool SaudChannel::handleSubTags(int32 &offset) {
if (_tbufferSize - offset >= 8) {
- Chunk::type type = READ_BE_UINT32(_tbuffer + offset);
+ uint32 type = READ_BE_UINT32(_tbuffer + offset);
uint32 size = READ_BE_UINT32(_tbuffer + offset + 4);
uint32 available_size = _tbufferSize - offset;
@@ -53,9 +53,9 @@ bool SaudChannel::handleSubTags(int32 &offset) {
case MKID_BE('STRK'):
_inData = false;
if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- if (c.size() != 14 && c.size() != 10) {
- error("STRK has an invalid size : %d", c.size());
+ int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
+ if (subSize != 14 && subSize != 10) {
+ error("STRK has an invalid size : %d", subSize);
}
} else
return false;
@@ -63,7 +63,9 @@ bool SaudChannel::handleSubTags(int32 &offset) {
case MKID_BE('SMRK'):
_inData = false;
if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
+ int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
+ if (subSize != 0)
+ error("SMRK has an invalid size : %d", subSize);
_markReached = true;
} else
return false;
@@ -71,9 +73,9 @@ bool SaudChannel::handleSubTags(int32 &offset) {
case MKID_BE('SHDR'):
_inData = false;
if (available_size >= (size + 8)) {
- MemoryChunk c((byte *)_tbuffer + offset);
- if (c.size() != 4)
- error("SHDR has an invalid size : %d", c.size());
+ int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
+ if (subSize != 4)
+ error("SHDR has an invalid size : %d", subSize);
} else
return false;
break;
@@ -119,10 +121,10 @@ bool SaudChannel::checkParameters(int32 index, int32 nb, int32 flags, int32 volu
return true;
}
-bool SaudChannel::appendData(Chunk &b, int32 size) {
+bool SaudChannel::appendData(Common::SeekableReadStream &b, int32 size) {
if (_dataSize == -1) {
assert(size > 8);
- Chunk::type saud_type = b.readUint32BE();
+ uint32 saud_type = b.readUint32BE();
/*uint32 saud_size =*/ b.readUint32BE();
if (saud_type != MKID_BE('SAUD'))
error("Invalid Chunk for SaudChannel : %X", saud_type);
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 494357a90c..6b79b7e2c4 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "engines/engine.h"
#include "common/config-manager.h"
@@ -42,7 +40,6 @@
#include "scumm/sound.h"
#include "scumm/util.h"
#include "scumm/smush/channel.h"
-#include "scumm/smush/chunk.h"
#include "scumm/smush/codec37.h"
#include "scumm/smush/codec47.h"
#include "scumm/smush/smush_font.h"
@@ -55,10 +52,6 @@
#include "sound/vorbis.h"
#include "sound/mp3.h"
-#ifdef DUMP_SMUSH_FRAMES
-#include <png.h>
-#endif
-
#include "common/zlib.h"
namespace Scumm {
@@ -212,10 +205,6 @@ static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_enc
void SmushPlayer::timerCallback() {
parseNextFrame();
-#ifdef _WIN32_WCE
- _inTimer = true;
- _inTimerCount++;
-#endif
}
SmushPlayer::SmushPlayer(ScummEngine_v7 *scumm) {
@@ -252,11 +241,6 @@ SmushPlayer::SmushPlayer(ScummEngine_v7 *scumm) {
_paused = false;
_pauseStartTime = 0;
_pauseTime = 0;
-#ifdef _WIN32_WCE
- _inTimer = false;
- _inTimerCount = 0;
- _inTimerCountRedraw = ConfMan.getInt("Smush_force_redraw");
-#endif
}
SmushPlayer::~SmushPlayer() {
@@ -328,16 +312,7 @@ void SmushPlayer::release() {
_codec47 = 0;
}
-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.size()) {
- error("Chunk size is inferior than minimum required size : %d < %d", b.size(), min_size);
- }
-}
-
-void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frames, int32 flags, int32 vol, int32 pan, Chunk &b, int32 size) {
+void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frames, int32 flags, int32 vol, int32 pan, Common::SeekableReadStream &b, int32 size) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleSoundBuffer(%d, %d)", track_id, index);
// if ((flags & 128) == 128) {
// return;
@@ -360,8 +335,7 @@ void SmushPlayer::handleSoundBuffer(int32 track_id, int32 index, int32 max_frame
c->appendData(b, size);
}
-void SmushPlayer::handleSoundFrame(Chunk &b) {
- checkBlock(b, MKID_BE('PSAD'));
+void SmushPlayer::handleSoundFrame(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleSoundFrame()");
int32 track_id = b.readUint16LE();
@@ -373,28 +347,28 @@ void SmushPlayer::handleSoundFrame(Chunk &b) {
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.size() - 10;
+ int32 size = subSize - 10;
handleSoundBuffer(track_id, index, max_frames, flags, vol, pan, b, size);
}
-void SmushPlayer::handleStore(Chunk &b) {
+void SmushPlayer::handleStore(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleStore()");
- checkBlock(b, MKID_BE('STOR'), 4);
+ assert(subSize >= 4);
_storeFrame = true;
}
-void SmushPlayer::handleFetch(Chunk &b) {
+void SmushPlayer::handleFetch(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleFetch()");
- checkBlock(b, MKID_BE('FTCH'), 6);
+ assert(subSize >= 6);
if (_frameBuffer != NULL) {
memcpy(_dst, _frameBuffer, _width * _height);
}
}
-void SmushPlayer::handleIACT(Chunk &b) {
- checkBlock(b, MKID_BE('IACT'), 8);
+void SmushPlayer::handleIACT(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::IACT()");
+ assert(subSize >= 8);
int code = b.readUint16LE();
int flags = b.readUint16LE();
@@ -415,7 +389,7 @@ void SmushPlayer::handleIACT(Chunk &b) {
int index = b.readUint16LE();
int nbframes = b.readUint16LE();
int32 size = b.readUint32LE();
- int32 bsize = b.size() - 18;
+ int32 bsize = subSize - 18;
if (_vm->_game.id != GID_CMI) {
int32 track = track_id;
@@ -519,7 +493,7 @@ void SmushPlayer::handleIACT(Chunk &b) {
}
}
-void SmushPlayer::handleTextResource(Chunk &b) {
+void SmushPlayer::handleTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &b) {
int pos_x = b.readSint16LE();
int pos_y = b.readSint16LE();
int flags = b.readSint16LE();
@@ -531,10 +505,10 @@ void SmushPlayer::handleTextResource(Chunk &b) {
const char *str;
char *string = NULL, *string2 = NULL;
- if (b.getType() == MKID_BE('TEXT')) {
- string = (char *)malloc(b.size() - 16);
+ if (subType == MKID_BE('TEXT')) {
+ string = (char *)malloc(subSize - 16);
str = string;
- b.read(string, b.size() - 16);
+ b.read(string, subSize - 16);
} else {
int string_id = b.readUint16LE();
if (!_strings)
@@ -702,7 +676,7 @@ bool SmushPlayer::readString(const char *file) {
return false;
}
-void SmushPlayer::readPalette(byte *out, Chunk &in) {
+void SmushPlayer::readPalette(byte *out, Common::SeekableReadStream &in) {
in.read(out, 0x300);
}
@@ -711,11 +685,10 @@ static byte delta_color(byte org_color, int16 delta_color) {
return CLIP(t, 0, 255);
}
-void SmushPlayer::handleDeltaPalette(Chunk &b) {
- checkBlock(b, MKID_BE('XPAL'));
+void SmushPlayer::handleDeltaPalette(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleDeltaPalette()");
- if (b.size() == 0x300 * 3 + 4) {
+ if (subSize == 0x300 * 3 + 4) {
b.readUint16LE();
b.readUint16LE();
@@ -725,7 +698,7 @@ void SmushPlayer::handleDeltaPalette(Chunk &b) {
}
readPalette(_pal, b);
setDirtyColors(0, 255);
- } else if (b.size() == 6) {
+ } else if (subSize == 6) {
b.readUint16LE();
b.readUint16LE();
@@ -740,9 +713,9 @@ void SmushPlayer::handleDeltaPalette(Chunk &b) {
}
}
-void SmushPlayer::handleNewPalette(Chunk &b) {
- checkBlock(b, MKID_BE('NPAL'), 0x300);
+void SmushPlayer::handleNewPalette(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleNewPalette()");
+ assert(subSize >= 0x300);
if (_skipPalette)
return;
@@ -805,21 +778,20 @@ void SmushPlayer::decodeFrameObject(int codec, const uint8 *src, int left, int t
}
#ifdef USE_ZLIB
-void SmushPlayer::handleZlibFrameObject(Chunk &b) {
+void SmushPlayer::handleZlibFrameObject(int32 subSize, Common::SeekableReadStream &b) {
if (_skipNext) {
_skipNext = false;
return;
}
- int32 chunkSize = b.size();
+ int32 chunkSize = subSize;
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 = Common::uncompress(fobjBuffer, &decompressedSize, chunkBuffer + 4, chunkSize - 4);
- if (result != Common::ZLIB_OK)
+ if (!Common::uncompress(fobjBuffer, &decompressedSize, chunkBuffer + 4, chunkSize - 4))
error("SmushPlayer::handleZlibFrameObject() Zlib uncompress error");
free(chunkBuffer);
@@ -836,8 +808,8 @@ void SmushPlayer::handleZlibFrameObject(Chunk &b) {
}
#endif
-void SmushPlayer::handleFrameObject(Chunk &b) {
- checkBlock(b, MKID_BE('FOBJ'), 14);
+void SmushPlayer::handleFrameObject(int32 subSize, Common::SeekableReadStream &b) {
+ assert(subSize >= 14);
if (_skipNext) {
_skipNext = false;
return;
@@ -852,7 +824,7 @@ void SmushPlayer::handleFrameObject(Chunk &b) {
b.readUint16LE();
b.readUint16LE();
- int32 chunk_size = b.size() - 14;
+ int32 chunk_size = subSize - 14;
byte *chunk_buffer = (byte *)malloc(chunk_size);
assert(chunk_buffer);
b.read(chunk_buffer, chunk_size);
@@ -862,8 +834,7 @@ void SmushPlayer::handleFrameObject(Chunk &b) {
free(chunk_buffer);
}
-void SmushPlayer::handleFrame(Chunk &b) {
- checkBlock(b, MKID_BE('FRME'));
+void SmushPlayer::handleFrame(int32 frameSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleFrame(%d)", _frame);
_skipNext = false;
@@ -871,54 +842,57 @@ void SmushPlayer::handleFrame(Chunk &b) {
_vm->_insane->procPreRendering();
}
- while (!b.eos()) {
- Chunk *sub = b.subBlock();
- switch (sub->getType()) {
+ while (frameSize > 0) {
+ const uint32 subType = b.readUint32BE();
+ const int32 subSize = b.readUint32BE();
+ const int32 subOffset = b.pos();
+ switch (subType) {
case MKID_BE('NPAL'):
- handleNewPalette(*sub);
+ handleNewPalette(subSize, b);
break;
case MKID_BE('FOBJ'):
- handleFrameObject(*sub);
+ handleFrameObject(subSize, b);
break;
#ifdef USE_ZLIB
case MKID_BE('ZFOB'):
- handleZlibFrameObject(*sub);
+ handleZlibFrameObject(subSize, b);
break;
#endif
case MKID_BE('PSAD'):
if (!_compressedFileMode)
- handleSoundFrame(*sub);
+ handleSoundFrame(subSize, b);
break;
case MKID_BE('TRES'):
- handleTextResource(*sub);
+ handleTextResource(subType, subSize, b);
break;
case MKID_BE('XPAL'):
- handleDeltaPalette(*sub);
+ handleDeltaPalette(subSize, b);
break;
case MKID_BE('IACT'):
- handleIACT(*sub);
+ handleIACT(subSize, b);
break;
case MKID_BE('STOR'):
- handleStore(*sub);
+ handleStore(subSize, b);
break;
case MKID_BE('FTCH'):
- handleFetch(*sub);
+ handleFetch(subSize, b);
break;
case MKID_BE('SKIP'):
- _vm->_insane->procSKIP(*sub);
+ _vm->_insane->procSKIP(subSize, b);
break;
case MKID_BE('TEXT'):
- handleTextResource(*sub);
+ handleTextResource(subType, subSize, b);
break;
default:
- error("Unknown frame subChunk found : %s, %d", tag2str(sub->getType()), sub->size());
+ error("Unknown frame subChunk found : %s, %d", tag2str(subType), subSize);
}
- b.reseek();
- if (sub->size() & 1)
+ frameSize -= subSize + 8;
+ b.seek(subOffset + subSize, SEEK_SET);
+ if (subSize & 1) {
b.skip(1);
-
- delete sub;
+ frameSize--;
+ }
}
if (_insanity) {
@@ -926,23 +900,16 @@ void SmushPlayer::handleFrame(Chunk &b) {
}
if (_width != 0 && _height != 0) {
-#ifdef _WIN32_WCE
- if (!_inTimer || _inTimerCount == _inTimerCountRedraw) {
- updateScreen();
- _inTimerCount = 0;
- }
-#else
updateScreen();
-#endif
}
_smixer->handleFrame();
_frame++;
}
-void SmushPlayer::handleAnimHeader(Chunk &b) {
- checkBlock(b, MKID_BE('AHDR'), 0x300 + 6);
+void SmushPlayer::handleAnimHeader(int32 subSize, Common::SeekableReadStream &b) {
debugC(DEBUG_SMUSH, "SmushPlayer::handleAnimHeader()");
+ assert(subSize >= 0x300 + 6);
/* _version = */ b.readUint16LE();
_nbframes = b.readUint16LE();
@@ -1004,7 +971,6 @@ SmushFont *SmushPlayer::getFont(int font) {
}
void SmushPlayer::parseNextFrame() {
- Chunk *sub;
if (_seekPos >= 0) {
if (_smixer)
@@ -1012,15 +978,23 @@ void SmushPlayer::parseNextFrame() {
if (_seekFile.size() > 0) {
delete _base;
- _base = new FileChunk(_seekFile);
+
+ ScummFile *tmp = new ScummFile();
+ if (!g_scumm->openFile(*tmp, _seekFile))
+ error("SmushPlayer: Unable to open file %s", _seekFile.c_str());
+ _base = tmp;
+ _base->readUint32BE();
+ _base->readUint32BE();
if (_seekPos > 0) {
assert(_seekPos > 8);
// In this case we need to get palette and number of frames
- sub = _base->subBlock();
- checkBlock(*sub, MKID_BE('AHDR'));
- handleAnimHeader(*sub);
- delete sub;
+ const uint32 subType = _base->readUint32BE();
+ const int32 subSize = _base->readUint32BE();
+ const int32 subOffset = _base->pos();
+ assert(subType == MKID_BE('AHDR'));
+ handleAnimHeader(subSize, *_base);
+ _base->seek(subOffset + subSize, SEEK_SET);
_middleAudio = true;
_seekPos -= 8;
@@ -1034,7 +1008,7 @@ void SmushPlayer::parseNextFrame() {
_skipPalette = true;
}
- _base->seek(_seekPos, SEEK_SET);
+ _base->seek(_seekPos + 8, SEEK_SET);
_frame = _seekFrame;
_startFrame = _frame;
_startTime = _vm->_system->getMillis();
@@ -1049,21 +1023,22 @@ void SmushPlayer::parseNextFrame() {
return;
}
- sub = _base->subBlock();
+ const uint32 subType = _base->readUint32BE();
+ const int32 subSize = _base->readUint32BE();
+ const int32 subOffset = _base->pos();
- switch (sub->getType()) {
+ switch (subType) {
case MKID_BE('AHDR'): // FT INSANE may seek file to the beginning
- handleAnimHeader(*sub);
+ handleAnimHeader(subSize, *_base);
break;
case MKID_BE('FRME'):
- handleFrame(*sub);
+ handleFrame(subSize, *_base);
break;
default:
- error("Unknown Chunk found at %x: %x, %d", _base->pos(), sub->getType(), sub->size());
+ error("Unknown Chunk found at %x: %x, %d", subOffset, subType, subSize);
}
- delete sub;
- _base->reseek();
+ _base->seek(subOffset + subSize, SEEK_SET);
if (_insanity)
_vm->_sound->processSound();
@@ -1098,57 +1073,6 @@ void SmushPlayer::warpMouse(int x, int y, int 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();
@@ -1326,14 +1250,10 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
_vm->_system->updateScreen();
_updateNeeded = false;
}
-#ifdef _WIN32_WCE
- _inTimer = false;
- _inTimerCount = 0;
-#endif
}
if (_endOfFile)
break;
- if (_vm->_quit || _vm->_saveLoadFlag || _vm->_smushVideoShouldFinish) {
+ if (_vm->quit() || _vm->_saveLoadFlag || _vm->_smushVideoShouldFinish) {
_smixer->stop();
_vm->_mixer->stopHandle(_compressedFileSoundHandle);
_vm->_mixer->stopHandle(_IACTchannel);
diff --git a/engines/scumm/smush/smush_player.h b/engines/scumm/smush/smush_player.h
index 413a5895d3..2e2996009c 100644
--- a/engines/scumm/smush/smush_player.h
+++ b/engines/scumm/smush/smush_player.h
@@ -27,7 +27,6 @@
#define SCUMM_SMUSH_PLAYER_H
#include "common/util.h"
-#include "scumm/smush/chunk.h"
#include "scumm/sound.h"
namespace Scumm {
@@ -51,7 +50,7 @@ private:
StringResource *_strings;
Codec37Decoder *_codec37;
Codec47Decoder *_codec47;
- FileChunk *_base;
+ Common::SeekableReadStream *_base;
byte *_frameBuffer;
byte *_specialBuffer;
@@ -84,11 +83,6 @@ private:
bool _insanity;
bool _middleAudio;
bool _skipPalette;
-#ifdef _WIN32_WCE
- bool _inTimer;
- int16 _inTimerCount;
- int16 _inTimerCountRedraw;
-#endif
public:
SmushPlayer(ScummEngine_v7 *scumm);
@@ -126,22 +120,21 @@ private:
bool readString(const char *file);
void decodeFrameObject(int codec, const uint8 *src, int left, int top, int width, int height);
- void checkBlock(const Chunk &, Chunk::type, uint32 = 0);
- void handleAnimHeader(Chunk &);
- void handleFrame(Chunk &);
- void handleNewPalette(Chunk &);
+ void handleAnimHeader(int32 subSize, Common::SeekableReadStream &);
+ void handleFrame(int32 frameSize, Common::SeekableReadStream &);
+ void handleNewPalette(int32 subSize, Common::SeekableReadStream &);
#ifdef USE_ZLIB
- void handleZlibFrameObject(Chunk &b);
+ void handleZlibFrameObject(int32 subSize, Common::SeekableReadStream &b);
#endif
- void handleFrameObject(Chunk &);
- void handleSoundBuffer(int32, int32, int32, int32, int32, int32, Chunk &, int32);
- void handleSoundFrame(Chunk &);
- void handleStore(Chunk &);
- void handleFetch(Chunk &);
- void handleIACT(Chunk &);
- void handleTextResource(Chunk &);
- void handleDeltaPalette(Chunk &);
- void readPalette(byte *, Chunk &);
+ void handleFrameObject(int32 subSize, Common::SeekableReadStream &);
+ void handleSoundBuffer(int32, int32, int32, int32, int32, int32, Common::SeekableReadStream &, int32);
+ void handleSoundFrame(int32 subSize, Common::SeekableReadStream &);
+ void handleStore(int32 subSize, Common::SeekableReadStream &);
+ void handleFetch(int32 subSize, Common::SeekableReadStream &);
+ void handleIACT(int32 subSize, Common::SeekableReadStream &);
+ void handleTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &);
+ void handleDeltaPalette(int32 subSize, Common::SeekableReadStream &);
+ void readPalette(byte *, Common::SeekableReadStream &);
void timerCallback();
};
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index f039e2ca23..700632e4b3 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -279,7 +279,7 @@ bool ScummEngine::handleNextCharsetCode(Actor *a, int *code) {
}
c = *buffer++;
- if (c == _newLineCharacter) {
+ if (_newLineCharacter != 0 && c == _newLineCharacter) {
c = 13;
break;
}
diff --git a/engines/scumm/thumbnail.cpp b/engines/scumm/thumbnail.cpp
deleted file mode 100644
index 40f1ee48e5..0000000000
--- a/engines/scumm/thumbnail.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed 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/system.h"
-#include "common/savefile.h"
-#include "graphics/scaler.h"
-#include "scumm/scumm.h"
-
-namespace Scumm {
-
-#define THMB_VERSION 1
-
-struct ThumbnailHeader {
- uint32 type;
- uint32 size;
- byte version;
- uint16 width, height;
- byte bpp;
-};
-
-#define ThumbnailHeaderSize (4+4+1+2+2+1)
-
-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::SeekableReadStream *file) {
- ThumbnailHeader header;
-
- header.type = file->readUint32BE();
- // 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_BE('THMB') && header.type != MKID_BE('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(OverlayColor));
-
- OverlayColor* pixels = (OverlayColor *)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;
-
-#if !defined(__DS__)
- if (!createThumbnailFromScreen(&thumb))
-#endif
- thumb.create(kThumbnailWidth, kThumbnailHeight2, sizeof(uint16));
-
- ThumbnailHeader header;
- header.type = MKID_BE('THMB');
- header.size = ThumbnailHeaderSize + thumb.w*thumb.h*thumb.bytesPerPixel;
- header.version = THMB_VERSION;
- header.width = thumb.w;
- header.height = thumb.h;
- header.bpp = thumb.bytesPerPixel;
-
- file->writeUint32BE(header.type);
- 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