aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README29
-rw-r--r--common/hashmap.h2
-rw-r--r--devtools/create_xeen/constants.cpp4
-rw-r--r--dists/engine-data/xeen.ccsbin55550 -> 55594 bytes
-rw-r--r--engines/mohawk/myst_state.cpp16
-rw-r--r--engines/mohawk/riven_saveload.cpp3
-rw-r--r--engines/sludge/builtin.cpp35
-rw-r--r--engines/sludge/functionlist.h338
-rw-r--r--engines/sludge/sludger.cpp7
-rw-r--r--engines/sludge/sludger.h1
-rw-r--r--engines/sludge/timing.cpp54
-rw-r--r--engines/sludge/timing.h24
-rw-r--r--engines/xeen/dialogs/dialogs_create_char.cpp3
-rw-r--r--engines/xeen/interface.cpp2
-rw-r--r--engines/xeen/map.h2
-rw-r--r--engines/xeen/party.cpp4
-rw-r--r--engines/xeen/resources.cpp1
-rw-r--r--engines/xeen/resources.h1
-rw-r--r--engines/xeen/scripts.cpp17
19 files changed, 296 insertions, 247 deletions
diff --git a/README b/README
index b89b981d66..700811828d 100644
--- a/README
+++ b/README
@@ -964,6 +964,9 @@ Space: Pause the game
Esc: Skip cutscene
F5: Menu
+Myst will autosave to slot 0 if no save or an autosave is present in
+slot 0.
+
3.17) Nippon Safes Inc. Amiga notes:
----- ------------------------------
@@ -1010,6 +1013,9 @@ F5: Menu
Ctrl-o: Load game
Ctrl-s: Save game
+Riven will autosave to slot 0 if no save or an autosave is present in
+slot 0.
+
3.20) Simon the Sorcerer games notes:
----- -------------------------------
@@ -1985,11 +1991,24 @@ saved games from the old default location, to the new default location.
6.1) Autosaves:
---- ----------
-For some games (namely "Beneath a Steel Sky", "Flight of the Amazon
-Queen", all AGI games, and all SCUMM games), ScummVM will by default
-automatically save the current state every five minutes (adjustable via
-the "autosave_period" config setting). For the AGI and SCUMM engines, it
-will save in Slot 0. For the SCUMM engine, this saved game can then be
+For some games ScummVM will by default automatically save the current state
+every five minutes (adjustable via the "autosave_period" config setting).
+The default autosave slot for many engines is slot 0.
+
+The games/engines listed below have autosave support.
+
+AGI games
+Beneath a Steel Sky
+Bud Tucker in Double Trouble
+COMPOSER games
+Flight of the Amazon Queen
+Myst
+Riven
+SCUMM games
+The Legend of Kyrandia I (slot 999)
+ZVISION games
+
+For the SCUMM engine, this saved game can then be
loaded again via Ctrl-0, or the F5 menu.
diff --git a/common/hashmap.h b/common/hashmap.h
index 56e80b89aa..1f93b68455 100644
--- a/common/hashmap.h
+++ b/common/hashmap.h
@@ -406,7 +406,7 @@ void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
if (shrinkArray && _mask >= HASHMAP_MIN_CAPACITY) {
delete[] _storage;
- _mask = HASHMAP_MIN_CAPACITY;
+ _mask = HASHMAP_MIN_CAPACITY - 1;
_storage = new Node *[HASHMAP_MIN_CAPACITY];
assert(_storage != nullptr);
memset(_storage, 0, HASHMAP_MIN_CAPACITY * sizeof(Node *));
diff --git a/devtools/create_xeen/constants.cpp b/devtools/create_xeen/constants.cpp
index 92e0d1f82d..7210759908 100644
--- a/devtools/create_xeen/constants.cpp
+++ b/devtools/create_xeen/constants.cpp
@@ -627,7 +627,7 @@ const int MONSTER_GRID_BITMASK[12] = {
};
const int INDOOR_OBJECT_X[2][12] = {
- { 5, -7, -112, 98, -8, -65, 49, -9, -34, 16, -58, 40 },
+ { -5, -7, -112, 98, -8, -65, 49, -9, -34, 16, -58, 40 },
{ -35, -35, -142, 68, -35, -95, 19, -35, -62, -14, -98, 16 }
};
@@ -1694,6 +1694,7 @@ const char *const SELECT_CLASS_BEFORE_SAVING =
const char *const EXCHANGE_ATTR_WITH = "Exchange %s with...";
const int NEW_CHAR_SKILLS[10] = { 1, 5, -1, -1, 4, 0, 0, -1, 6, 11 };
+const int NEW_CHAR_SKILLS_OFFSET[10] = { 0, 0, 0, 5, 0, 0, 0, 0, 0, 0 };
const int NEW_CHAR_SKILLS_LEN[10] = { 11, 8, 0, 0, 12, 8, 8, 0, 9, 11 };
const int NEW_CHAR_RACE_SKILLS[10] = { 14, -1, 17, 16, -1, 0, 0, 0, 0, 0 };
@@ -2255,6 +2256,7 @@ void writeConstants(CCArchive &cc) {
file.syncString(SELECT_CLASS_BEFORE_SAVING);
file.syncString(EXCHANGE_ATTR_WITH);
file.syncNumbers((const int *)NEW_CHAR_SKILLS, 10);
+ file.syncNumbers((const int *)NEW_CHAR_SKILLS_OFFSET, 10);
file.syncNumbers((const int *)NEW_CHAR_SKILLS_LEN, 10);
file.syncNumbers((const int *)NEW_CHAR_RACE_SKILLS, 10);
file.syncNumbers((const int *)RACE_MAGIC_RESISTENCES, 5);
diff --git a/dists/engine-data/xeen.ccs b/dists/engine-data/xeen.ccs
index d4c6dd68a8..88671fb669 100644
--- a/dists/engine-data/xeen.ccs
+++ b/dists/engine-data/xeen.ccs
Binary files differ
diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp
index efc5025de5..c65ece55d5 100644
--- a/engines/mohawk/myst_state.cpp
+++ b/engines/mohawk/myst_state.cpp
@@ -259,12 +259,19 @@ bool MystGameState::saveMetadata(int slot) {
bool MystGameState::isAutoSaveAllowed() {
// Open autosave slot and see if it an autosave
// Autosaving will be enabled if it is an autosave or if there is no save in that slot
- Common::String filename = buildMetadataFilename(kAutoSaveSlot);
- Common::ScopedPtr<Common::InSaveFile> metadataFile(g_system->getSavefileManager()->openForLoading(filename));
- if (!metadataFile) { // There is no save in the autosave slot, enable autosave
+
+ Common::String dataFilename = buildSaveFilename(kAutoSaveSlot);
+ Common::ScopedPtr<Common::InSaveFile> dataFile(g_system->getSavefileManager()->openForLoading(dataFilename));
+ if (!dataFile) { // Cannot load non-meta file, enable autosave
return true;
}
+ Common::String metaFilename = buildMetadataFilename(kAutoSaveSlot);
+ Common::ScopedPtr<Common::InSaveFile> metadataFile(g_system->getSavefileManager()->openForLoading(metaFilename));
+ if (!metadataFile) { // Can load non-meta file, but not metafile, could be a save from the original, disable autosave
+ return false;
+ }
+
Common::Serializer m(metadataFile.get(), nullptr);
// Read the metadata file
@@ -302,7 +309,8 @@ SaveStateDescriptor MystGameState::querySaveMetaInfos(int slot) {
desc.setSaveDate(metadata.saveYear, metadata.saveMonth, metadata.saveDay);
desc.setSaveTime(metadata.saveHour, metadata.saveMinute);
desc.setPlayTime(metadata.totalPlayTime);
- desc.setDeletableFlag(slot != kAutoSaveSlot);
+ if (metadata.autoSave) // Allow non-saves to be deleted, but not autosaves
+ desc.setDeletableFlag(slot != kAutoSaveSlot);
Graphics::Surface *thumbnail;
if (!Graphics::loadThumbnail(*metadataFile, thumbnail)) {
diff --git a/engines/mohawk/riven_saveload.cpp b/engines/mohawk/riven_saveload.cpp
index 5ba0e51f8c..e8d29a0c24 100644
--- a/engines/mohawk/riven_saveload.cpp
+++ b/engines/mohawk/riven_saveload.cpp
@@ -142,7 +142,8 @@ SaveStateDescriptor RivenSaveLoad::querySaveMetaInfos(const int slot) {
descriptor.setPlayTime(metadata.totalPlayTime);
descriptor.setSaveDate(metadata.saveYear, metadata.saveMonth, metadata.saveDay);
descriptor.setSaveTime(metadata.saveHour, metadata.saveMinute);
- descriptor.setDeletableFlag(slot != kAutoSaveSlot);
+ if (metadata.autoSave) // Allow non-saves to be deleted, but not autosaves
+ descriptor.setDeletableFlag(slot != kAutoSaveSlot);
delete metaStream;
diff --git a/engines/sludge/builtin.cpp b/engines/sludge/builtin.cpp
index e06cea204b..8646dd46a3 100644
--- a/engines/sludge/builtin.cpp
+++ b/engines/sludge/builtin.cpp
@@ -56,7 +56,6 @@ namespace Sludge {
Variable *launchResult = NULL;
-extern int lastFramesPerSecond;
extern bool allowAnyFilename;
extern VariableStack *noStack;
extern StatusStuff *nowStatus;
@@ -65,31 +64,6 @@ extern int numBIFNames, numUserFunc;
extern Common::String *allUserFunc;
extern Common::String *allBIFNames;
-int paramNum[] = { -1, 0, 1, 1, -1, -1, 1, 3, 4, 1, 0, 0, 8, -1, // SAY->MOVEMOUSE
- -1, 0, 0, -1, -1, 1, 1, 1, 1, 4, 1, 1, 2, 1,// FOCUS->REMOVEREGION
- 2, 2, 0, 0, 2, // ANIMATE->SETSCALE
- -1, 2, 1, 0, 0, 0, 1, 0, 3, // new/push/pop stack, status stuff
- 2, 0, 0, 3, 1, 0, 2, // delFromStack->completeTimers
- -1, -1, -1, 2, 2, 0, 3, 1, // anim, costume, pO, setC, wait, sS, substring, stringLength
- 0, 1, 1, 0, 2, // dark, save, load, quit, rename
- 1, 3, 3, 1, 2, 1, 1, 3, 1, 0, 0, 2, 1, // stackSize, pasteString, startMusic, defvol, vol, stopmus, stopsound, setfont, alignStatus, show x 2, pos'Status, setFloor
- -1, -1, 1, 1, 2, 1, 1, 1, -1, -1, -1, 1, 1, // force, jump, peekstart, peekend, enqueue, getSavedGames, inFont, loopSound, removeChar, stopCharacter
- 1, 0, 3, 3, 1, 2, 1, 2, 2, // launch, howFrozen, pastecol, litcol, checksaved, float, cancelfunc, walkspeed, delAll
- 2, 3, 1, 2, 2, 0, 0, 1, 2, 3, 1, -1, // extras, mixoverlay, pastebloke, getMScreenX/Y, setSound(Default/-)Volume, looppoints, speechMode, setLightMap
- -1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, // think, getCharacterDirection, is(char/region/moving), deleteGame, renameGame, hardScroll, stringWidth, speechSpeed, normalCharacter
- 2, 1, 2, 1, 3, 1, 1, 2, 1, // fetchEvent, setBrightness, spin, fontSpace, burnString, captureAll, cacheSound, setSpinSpeed, transitionMode
- 1, 0, 0, 1, 0, 2, 1, 1, 1, // movie(Start/Abort/Playing), updateDisplay, getSoundCache, savedata, loaddata, savemode, freeSound
- 3, 0, 3, 3, 2, 1, 1, // setParallax, clearParallax, setBlankColour, setBurnColour, getPixelColour, makeFastArray, getCharacterScale
- 0, 2, 0, // getLanguage, launchWith, getFramesPerSecond
- 3, 2, 2, 0, 0, 1, // readThumbnail, setThumbnailSize, hasFlag, snapshot, clearSnapshot, anyFilename
- 2, 1, // regGet, fatal
- 4, 3, -1, 0, // chr AA, max AA, setBackgroundEffect, doBackgroundEffect
- 2, // setCharacterAngleOffset
- 2, 5, // setCharacterTransparency, setCharacterColourise
- 1, // zoomCamera
- 1, 0, 0 // playMovie, stopMovie, pauseMovie
- };
-
bool failSecurityCheck(const Common::String &fn) {
if (fn.empty())
return true;
@@ -117,6 +91,7 @@ LoadedFunction *saverFunc;
typedef BuiltReturn (*builtInSludgeFunc)(int numParams, LoadedFunction *fun);
struct builtInFunctionData {
builtInSludgeFunc func;
+ int paramNum;
};
#define builtIn(a) static BuiltReturn builtIn_ ## a (int numParams, LoadedFunction *fun)
@@ -2427,7 +2402,7 @@ builtIn(_rem_launchWith) {
builtIn(getFramesPerSecond) {
UNUSEDALL
- setVariable(fun->reg, SVT_INT, lastFramesPerSecond);
+ setVariable(fun->reg, SVT_INT, g_sludge->_timer.getLastFps());
return BR_CONTINUE;
}
@@ -2574,9 +2549,9 @@ BuiltReturn callBuiltIn(int whichFunc, int numParams, LoadedFunction *fun) {
}
if (whichFunc < NUM_FUNCS) {
- if (paramNum[whichFunc] != -1) {
- if (paramNum[whichFunc] != numParams) {
- Common::String buff = Common::String::format("Built in function must have %i parameter%s", paramNum[whichFunc], (paramNum[whichFunc] == 1) ? "" : "s");
+ if (builtInFunctionArray[whichFunc].paramNum != -1) {
+ if (builtInFunctionArray[whichFunc].paramNum != numParams) {
+ Common::String buff = Common::String::format("Built in function must have %i parameter%s", builtInFunctionArray[whichFunc].paramNum, (builtInFunctionArray[whichFunc].paramNum == 1) ? "" : "s");
Common::String msg = buff;
fatal(msg);
return BR_ERROR;
diff --git a/engines/sludge/functionlist.h b/engines/sludge/functionlist.h
index 025f80a844..c7858a2d03 100644
--- a/engines/sludge/functionlist.h
+++ b/engines/sludge/functionlist.h
@@ -29,178 +29,178 @@
namespace Sludge {
-#define FUNC(special,name) {builtIn_ ## name},
+#define FUNC(special,name,paramNum) {builtIn_ ## name, paramNum},
static builtInFunctionData builtInFunctionArray[] = {
- FUNC(true, say)
- FUNC(true, skipSpeech)
- FUNC(true, statusText)
- FUNC(true, pause)
- FUNC(true, onLeftMouse)
- FUNC(true, onRightMouse)
- FUNC(true, setCursor)
- FUNC(true, addOverlay)
- FUNC(true, addCharacter)
- FUNC(true, playSound)
- FUNC(true, getMouseX)
- FUNC(true, getMouseY)
- FUNC(true, addScreenRegion)
- FUNC(true, onMoveMouse)
- FUNC(true, onFocusChange)
- FUNC(true, getOverObject)
- FUNC(true, blankScreen)
- FUNC(true, moveCharacter)
- FUNC(true, onKeyboard)
- FUNC(true, getObjectX)
- FUNC(true, getObjectY)
- FUNC(true, random)
- FUNC(true, spawnSub)
- FUNC(true, blankArea)
- FUNC(true, hideCharacter)
- FUNC(true, showCharacter)
- FUNC(true, callEvent)
- FUNC(true, removeScreenRegion)
- FUNC(true, animate)
- FUNC(true, turnCharacter)
- FUNC(true, removeAllCharacters)
- FUNC(true, removeAllScreenRegions)
- FUNC(true, setScale)
- FUNC(true, newStack)
- FUNC(true, pushToStack)
- FUNC(true, popFromStack)
- FUNC(true, clearStatus)
- FUNC(true, addStatus)
- FUNC(true, removeLastStatus)
- FUNC(true, lightStatus)
- FUNC(true, getStatusText)
- FUNC(true, setStatusColour)
- FUNC(true, deleteFromStack)
- FUNC(true, freeze)
- FUNC(true, unfreeze)
- FUNC(true, pasteImage)
- FUNC(true, copyStack)
- FUNC(true, completeTimers)
- FUNC(true, setCharacterDrawMode)
- FUNC(true, anim)
- FUNC(true, costume)
- FUNC(true, pickOne)
- FUNC(true, setCostume)
- FUNC(true, wait)
- FUNC(true, somethingSpeaking)
- FUNC(true, substring)
- FUNC(true, stringLength)
- FUNC(true, darkBackground)
- FUNC(true, saveGame)
- FUNC(true, loadGame)
- FUNC(true, quitGame)
- FUNC(true, rename)
- FUNC(true, stackSize)
- FUNC(true, pasteString)
- FUNC(true, startMusic)
- FUNC(true, setDefaultMusicVolume)
- FUNC(true, setMusicVolume)
- FUNC(true, stopMusic)
- FUNC(true, stopSound)
- FUNC(true, setFont)
- FUNC(true, alignStatus)
- FUNC(true, showFloor)
- FUNC(true, showBoxes)
- FUNC(true, positionStatus)
- FUNC(true, setFloor)
- FUNC(true, forceCharacter)
- FUNC(true, jumpCharacter)
- FUNC(true, peekStart)
- FUNC(true, peekEnd)
- FUNC(true, enqueue)
- FUNC(true, setZBuffer)
- FUNC(true, getMatchingFiles)
- FUNC(true, inFont)
- FUNC(true, onLeftMouseUp)
- FUNC(true, onRightMouseUp)
- FUNC(true, loopSound)
- FUNC(true, removeCharacter)
- FUNC(true, stopCharacter)
- FUNC(true, launch)
- FUNC(true, howFrozen)
- FUNC(true, setPasteColour)
- FUNC(true, setLitStatusColour)
- FUNC(true, fileExists)
- FUNC(true, floatCharacter)
- FUNC(true, cancelSub)
- FUNC(true, setCharacterWalkSpeed)
- FUNC(true, deleteAllFromStack)
- FUNC(true, setCharacterExtra)
- FUNC(true, mixOverlay)
- FUNC(true, pasteCharacter)
- FUNC(true, setSceneDimensions)
- FUNC(true, aimCamera)
- FUNC(true, getMouseScreenX)
- FUNC(true, getMouseScreenY)
- FUNC(true, setDefaultSoundVolume)
- FUNC(true, setSoundVolume)
- FUNC(true, setSoundLoopPoints)
- FUNC(true, setSpeechMode)
- FUNC(true, setLightMap)
- FUNC(true, think)
- FUNC(true, getCharacterDirection)
- FUNC(true, isCharacter)
- FUNC(true, isScreenRegion)
- FUNC(true, isMoving)
- FUNC(true, deleteFile)
- FUNC(true, renameFile)
- FUNC(true, hardScroll)
- FUNC(true, stringWidth)
- FUNC(true, setSpeechSpeed)
- FUNC(true, normalCharacter)
- FUNC(true, fetchEvent)
- FUNC(true, transitionLevel)
- FUNC(true, spinCharacter)
- FUNC(true, setFontSpacing)
- FUNC(true, burnString)
- FUNC(true, captureAllKeys)
- FUNC(true, cacheSound)
- FUNC(true, setCharacterSpinSpeed)
- FUNC(true, transitionMode)
- FUNC(false, _rem_movieStart)
- FUNC(false, _rem_movieAbort)
- FUNC(false, _rem_moviePlaying)
- FUNC(false, _rem_updateDisplay)
- FUNC(true, getSoundCache)
- FUNC(true, saveCustomData)
- FUNC(true, loadCustomData)
- FUNC(true, setCustomEncoding)
- FUNC(true, freeSound)
- FUNC(true, parallaxAdd)
- FUNC(true, parallaxClear)
- FUNC(true, setBlankColour)
- FUNC(true, setBurnColour)
- FUNC(true, getPixelColour)
- FUNC(true, makeFastArray)
- FUNC(true, getCharacterScale)
- FUNC(true, getLanguageID)
- FUNC(false, _rem_launchWith)
- FUNC(true, getFramesPerSecond)
- FUNC(true, showThumbnail)
- FUNC(true, setThumbnailSize)
- FUNC(true, hasFlag)
- FUNC(true, snapshotGrab)
- FUNC(true, snapshotClear)
- FUNC(true, bodgeFilenames)
- FUNC(false, _rem_registryGetString)
- FUNC(true, quitWithFatalError)
- FUNC(true, _rem_setCharacterAA)
- FUNC(true, _rem_setMaximumAA)
- FUNC(true, setBackgroundEffect)
- FUNC(true, doBackgroundEffect)
- FUNC(true, setCharacterAngleOffset)
- FUNC(true, setCharacterTransparency)
- FUNC(true, setCharacterColourise)
- FUNC(true, zoomCamera)
- FUNC(true, playMovie)
- FUNC(true, stopMovie)
- FUNC(true, pauseMovie)
+ FUNC(true, say, -1)
+ FUNC(true, skipSpeech, 0)
+ FUNC(true, statusText, 1)
+ FUNC(true, pause, 1)
+ FUNC(true, onLeftMouse, -1)
+ FUNC(true, onRightMouse, -1)
+ FUNC(true, setCursor, 1)
+ FUNC(true, addOverlay, 3)
+ FUNC(true, addCharacter, 4)
+ FUNC(true, playSound, 1)
+ FUNC(true, getMouseX, 0)
+ FUNC(true, getMouseY, 0)
+ FUNC(true, addScreenRegion, 8)
+ FUNC(true, onMoveMouse, -1)
+ FUNC(true, onFocusChange, -1)
+ FUNC(true, getOverObject, 0)
+ FUNC(true, blankScreen, 0)
+ FUNC(true, moveCharacter, -1)
+ FUNC(true, onKeyboard, -1)
+ FUNC(true, getObjectX, 1)
+ FUNC(true, getObjectY, 1)
+ FUNC(true, random, 1)
+ FUNC(true, spawnSub, 1)
+ FUNC(true, blankArea, 4)
+ FUNC(true, hideCharacter, 1)
+ FUNC(true, showCharacter, 1)
+ FUNC(true, callEvent, 2)
+ FUNC(true, removeScreenRegion, 1)
+ FUNC(true, animate, 2)
+ FUNC(true, turnCharacter, 2)
+ FUNC(true, removeAllCharacters, 0)
+ FUNC(true, removeAllScreenRegions, 0)
+ FUNC(true, setScale, 2)
+ FUNC(true, newStack, -1)
+ FUNC(true, pushToStack, 2)
+ FUNC(true, popFromStack, 1)
+ FUNC(true, clearStatus, 0)
+ FUNC(true, addStatus, 0)
+ FUNC(true, removeLastStatus, 0)
+ FUNC(true, lightStatus, 1)
+ FUNC(true, getStatusText, 0)
+ FUNC(true, setStatusColour, 3)
+ FUNC(true, deleteFromStack, 2)
+ FUNC(true, freeze, 0)
+ FUNC(true, unfreeze, 0)
+ FUNC(true, pasteImage, 3)
+ FUNC(true, copyStack, 1)
+ FUNC(true, completeTimers, 0)
+ FUNC(true, setCharacterDrawMode, 2)
+ FUNC(true, anim, -1)
+ FUNC(true, costume, -1)
+ FUNC(true, pickOne, -1)
+ FUNC(true, setCostume, 2)
+ FUNC(true, wait, 2)
+ FUNC(true, somethingSpeaking, 0)
+ FUNC(true, substring, 3)
+ FUNC(true, stringLength, 1)
+ FUNC(true, darkBackground, 0)
+ FUNC(true, saveGame, 1)
+ FUNC(true, loadGame, 1)
+ FUNC(true, quitGame, 0)
+ FUNC(true, rename, 2)
+ FUNC(true, stackSize, 1)
+ FUNC(true, pasteString, 3)
+ FUNC(true, startMusic, 3)
+ FUNC(true, setDefaultMusicVolume, 1)
+ FUNC(true, setMusicVolume, 2)
+ FUNC(true, stopMusic, 1)
+ FUNC(true, stopSound, 1)
+ FUNC(true, setFont, 3)
+ FUNC(true, alignStatus, 1)
+ FUNC(true, showFloor, 0)
+ FUNC(true, showBoxes, 0)
+ FUNC(true, positionStatus, 2)
+ FUNC(true, setFloor, 1)
+ FUNC(true, forceCharacter, -1)
+ FUNC(true, jumpCharacter, -1)
+ FUNC(true, peekStart, 1)
+ FUNC(true, peekEnd, 1)
+ FUNC(true, enqueue, 2)
+ FUNC(true, setZBuffer, 1)
+ FUNC(true, getMatchingFiles, 1)
+ FUNC(true, inFont, 1)
+ FUNC(true, onLeftMouseUp, -1)
+ FUNC(true, onRightMouseUp, -1)
+ FUNC(true, loopSound, -1)
+ FUNC(true, removeCharacter, 1)
+ FUNC(true, stopCharacter, 1)
+ FUNC(true, launch, 1)
+ FUNC(true, howFrozen, 0)
+ FUNC(true, setPasteColour, 3)
+ FUNC(true, setLitStatusColour, 3)
+ FUNC(true, fileExists, 1)
+ FUNC(true, floatCharacter, 2)
+ FUNC(true, cancelSub, 1)
+ FUNC(true, setCharacterWalkSpeed, 2)
+ FUNC(true, deleteAllFromStack, 2)
+ FUNC(true, setCharacterExtra, 2)
+ FUNC(true, mixOverlay, 3)
+ FUNC(true, pasteCharacter, 1)
+ FUNC(true, setSceneDimensions, 2)
+ FUNC(true, aimCamera, 2)
+ FUNC(true, getMouseScreenX, 0)
+ FUNC(true, getMouseScreenY, 0)
+ FUNC(true, setDefaultSoundVolume, 1)
+ FUNC(true, setSoundVolume, 2)
+ FUNC(true, setSoundLoopPoints, 3)
+ FUNC(true, setSpeechMode, 1)
+ FUNC(true, setLightMap, -1)
+ FUNC(true, think, -1)
+ FUNC(true, getCharacterDirection, 1)
+ FUNC(true, isCharacter, 1)
+ FUNC(true, isScreenRegion, 1)
+ FUNC(true, isMoving, 1)
+ FUNC(true, deleteFile, 1)
+ FUNC(true, renameFile, 2)
+ FUNC(true, hardScroll, 1)
+ FUNC(true, stringWidth, 1)
+ FUNC(true, setSpeechSpeed, 1)
+ FUNC(true, normalCharacter, 1)
+ FUNC(true, fetchEvent, 2)
+ FUNC(true, transitionLevel, 1)
+ FUNC(true, spinCharacter, 2)
+ FUNC(true, setFontSpacing, 1)
+ FUNC(true, burnString, 3)
+ FUNC(true, captureAllKeys, 1)
+ FUNC(true, cacheSound, 1)
+ FUNC(true, setCharacterSpinSpeed, 2)
+ FUNC(true, transitionMode, 1)
+ FUNC(false, _rem_movieStart, 1)
+ FUNC(false, _rem_movieAbort, 0)
+ FUNC(false, _rem_moviePlaying, 0)
+ FUNC(false, _rem_updateDisplay, 1)
+ FUNC(true, getSoundCache, 0)
+ FUNC(true, saveCustomData, 2)
+ FUNC(true, loadCustomData, 1)
+ FUNC(true, setCustomEncoding, 1)
+ FUNC(true, freeSound, 1)
+ FUNC(true, parallaxAdd, 3)
+ FUNC(true, parallaxClear, 0)
+ FUNC(true, setBlankColour, 3)
+ FUNC(true, setBurnColour, 3)
+ FUNC(true, getPixelColour, 2)
+ FUNC(true, makeFastArray, 1)
+ FUNC(true, getCharacterScale, 1)
+ FUNC(true, getLanguageID, 0)
+ FUNC(false, _rem_launchWith, 2)
+ FUNC(true, getFramesPerSecond, 0)
+ FUNC(true, showThumbnail, 3)
+ FUNC(true, setThumbnailSize, 2)
+ FUNC(true, hasFlag, 2)
+ FUNC(true, snapshotGrab, 0)
+ FUNC(true, snapshotClear, 0)
+ FUNC(true, bodgeFilenames, 1)
+ FUNC(false, _rem_registryGetString, 2)
+ FUNC(true, quitWithFatalError, 1)
+ FUNC(true, _rem_setCharacterAA, 4)
+ FUNC(true, _rem_setMaximumAA, 3)
+ FUNC(true, setBackgroundEffect, -1)
+ FUNC(true, doBackgroundEffect, 0)
+ FUNC(true, setCharacterAngleOffset, 2)
+ FUNC(true, setCharacterTransparency, 2)
+ FUNC(true, setCharacterColourise, 5)
+ FUNC(true, zoomCamera, 1)
+ FUNC(true, playMovie, 1)
+ FUNC(true, stopMovie, 0)
+ FUNC(true, pauseMovie, 0)
};
#undef FUNC
-int NUM_FUNCS = (sizeof (builtInFunctionArray) / sizeof (builtInFunctionArray[0]));
+const static int NUM_FUNCS = (sizeof (builtInFunctionArray) / sizeof (builtInFunctionArray[0]));
} // End of namespace Sludge
diff --git a/engines/sludge/sludger.cpp b/engines/sludge/sludger.cpp
index dd3b319d52..8bbf76e6ef 100644
--- a/engines/sludge/sludger.cpp
+++ b/engines/sludge/sludger.cpp
@@ -138,6 +138,7 @@ Common::File *openAndVerify(const Common::String &filename, char extra1, char ex
}
void initSludge() {
+ g_sludge->_timer.reset();
g_sludge->_languageMan->init();
g_sludge->_gfxMan->init();
g_sludge->_resMan->init();
@@ -161,7 +162,6 @@ void initSludge() {
numGlobals = 0;
launchResult = nullptr;
- lastFramesPerSecond = -1;
allowAnyFilename = true;
noStack = nullptr;
numBIFNames = numUserFunc = 0;
@@ -243,7 +243,7 @@ bool initSludge(const Common::String &filename) {
int specialSettings = fp->readByte();
debugC(2, kSludgeDebugDataLoad, "specialSettings : %i", specialSettings);
- g_sludge->_timer.setDesiredfps(1000 / fp->readByte());
+ g_sludge->_timer.setDesiredFPS(1000 / fp->readByte());
readString(fp); // Unused - was used for registration purposes.
@@ -1033,7 +1033,4 @@ int startNewFunctionNum(uint funcNum, uint numParamsExpected,
return 1;
}
-int lastFramesPerSecond = -1;
-int thisFramesPerSecond = -1;
-
} // End of namespace Sludge
diff --git a/engines/sludge/sludger.h b/engines/sludge/sludger.h
index 8f554f83cb..2351cb9057 100644
--- a/engines/sludge/sludger.h
+++ b/engines/sludge/sludger.h
@@ -67,7 +67,6 @@ void killSludge();
void displayBase();
void sludgeDisplay();
int startNewFunctionNum(uint, uint, LoadedFunction *, VariableStack*&, bool = true);
-bool handleInput();
void restartFunction(LoadedFunction *fun);
bool loadFunctionCode(LoadedFunction *newFunc);
void killAllFunctions();
diff --git a/engines/sludge/timing.cpp b/engines/sludge/timing.cpp
index 2e3865498a..c291f57a6b 100644
--- a/engines/sludge/timing.cpp
+++ b/engines/sludge/timing.cpp
@@ -25,31 +25,63 @@
namespace Sludge {
+Timer::Timer(){
+ reset();
+}
+
+void Timer::reset(void) {
+ _desiredFPS = 300;
+ _startTime = 0;
+ _endTime = 0;
+ _desiredFrameTime = 0;
+ _addNextTime = 0;
+
+ // FPS stats
+ _lastFPS = -1;
+ _thisFPS = -1;
+ _lastSeconds = 0;
+}
+
void Timer::init(void) {
- _desired_frame_time = 1000 / _desiredfps;
- _starttime = g_system->getMillis();
+ _desiredFrameTime = 1000 / _desiredFPS;
+ _startTime = g_system->getMillis();
}
void Timer::initSpecial(int t) {
- _desired_frame_time = 1000 / t;
- _starttime = g_system->getMillis();
+ _desiredFrameTime = 1000 / t;
+ _startTime = g_system->getMillis();
+}
+
+void Timer::updateFpsStats() {
+ uint32 currentSeconds = g_system->getMillis() / 1000;
+ if (_lastSeconds != currentSeconds) {
+ _lastSeconds = currentSeconds;
+ _lastFPS = _thisFPS;
+ _thisFPS = 1;
+ } else {
+ ++_thisFPS;
+ }
}
void Timer::waitFrame(void) {
- static uint32 addNextTime = 0;
uint32 timetaken;
for (;;) {
- _endtime = g_system->getMillis();
- timetaken = addNextTime + _endtime - _starttime;
- if (timetaken >= _desired_frame_time) break;
+ _endTime = g_system->getMillis();
+ timetaken = _addNextTime + _endTime - _startTime;
+ if (timetaken >= _desiredFrameTime)
+ break;
g_system->delayMillis(1);
}
- addNextTime = timetaken - _desired_frame_time;
- if (addNextTime > _desired_frame_time) addNextTime = _desired_frame_time;
+ _addNextTime = timetaken - _desiredFrameTime;
+ if (_addNextTime > _desiredFrameTime)
+ _addNextTime = _desiredFrameTime;
+
+ _startTime = _endTime;
- _starttime = _endtime;
+ // Stats
+ updateFpsStats();
}
} // End of namespace Sludge
diff --git a/engines/sludge/timing.h b/engines/sludge/timing.h
index 0d7ffece8d..e04ddf4732 100644
--- a/engines/sludge/timing.h
+++ b/engines/sludge/timing.h
@@ -25,18 +25,28 @@
namespace Sludge {
class Timer {
-private:
- int _desiredfps; // desired frames per second
- uint32 _starttime, _endtime;
- uint32 _desired_frame_time;
-
public:
- void setDesiredfps(int t) { _desiredfps = t; }
+ Timer();
+
+ void setDesiredFPS(int t) { _desiredFPS = t; }
+ void reset(void);
void init(void);
void initSpecial(int t);
void waitFrame(void);
- Timer():_desiredfps(300), _starttime(0), _endtime(0), _desired_frame_time(0){}
+ int getLastFps() const { return _lastFPS; }
+
+private:
+ int _desiredFPS; // desired frames per second
+ uint32 _startTime, _endTime;
+ uint32 _desiredFrameTime;
+ uint32 _addNextTime;
+
+ // FPS stats
+ void updateFpsStats();
+ int _lastFPS;
+ int _thisFPS;
+ uint32 _lastSeconds;
};
} // End of namespace Sludge
diff --git a/engines/xeen/dialogs/dialogs_create_char.cpp b/engines/xeen/dialogs/dialogs_create_char.cpp
index 9f3e2a51f1..ab86c4939a 100644
--- a/engines/xeen/dialogs/dialogs_create_char.cpp
+++ b/engines/xeen/dialogs/dialogs_create_char.cpp
@@ -389,7 +389,8 @@ int CreateCharacterDialog::newCharDetails(Race race, Sex sex, int classId,
// Set up default skill for the race, if any
if (Res.NEW_CHAR_RACE_SKILLS[race] != -1) {
- raceSkillStr = Res.SKILL_NAMES[Res.NEW_CHAR_RACE_SKILLS[race]];
+ const char *skillP = Res.SKILL_NAMES[Res.NEW_CHAR_RACE_SKILLS[race]];
+ raceSkillStr = Common::String(skillP + Res.NEW_CHAR_SKILLS_OFFSET[race]);
}
// Set up color to use for each skill string to be displayed, based
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index c1628da13f..6d8de93a42 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -1510,7 +1510,7 @@ void Interface::doCombat() {
// FIXME: I've had a rare issue where the loop starts with a non-party _whosTurn. Unfortunately,
// I haven't been able to consistently replicate and diagnose the problem, so for now,
// I'm simply detecting if it happens and resetting the combat round
- if (combat._whosTurn >= party._activeParty.size())
+ if (combat._whosTurn >= (int)party._activeParty.size())
goto new_round;
highlightChar(combat._whosTurn);
diff --git a/engines/xeen/map.h b/engines/xeen/map.h
index 1bb3cf288c..1c00e549c3 100644
--- a/engines/xeen/map.h
+++ b/engines/xeen/map.h
@@ -322,7 +322,6 @@ public:
};
private:
XeenEngine *_vm;
- Common::Array<SpriteResourceEntry> _objectSprites;
Common::Array<SpriteResourceEntry> _monsterSprites;
Common::Array<SpriteResourceEntry> _monsterAttackSprites;
Common::Array<SpriteResourceEntry> _wallItemSprites;
@@ -330,6 +329,7 @@ public:
Common::Array<MazeObject> _objects;
Common::Array<MazeMonster> _monsters;
Common::Array<MazeWallItem> _wallItems;
+ Common::Array<SpriteResourceEntry> _objectSprites;
public:
MonsterObjectData(XeenEngine *vm);
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index 5ae53d69c6..1fee0980d2 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -1498,14 +1498,14 @@ bool Party::giveExt(int mode1, uint val1, int mode2, uint val2, int mode3, uint
sound.playFX(10);
intf.draw3d(true, false);
Common::String msg = Common::String::format(Res.PICKS_THE_LOCK, c._name.c_str());
- ErrorScroll::show(g_vm, msg);
+ ErrorScroll::show(g_vm, msg, WT_NONFREEZED_WAIT);
} else {
sound.playFX(21);
obj._frame = 0;
scripts._animCounter = 0;
Common::String msg = Common::String::format(Res.UNABLE_TO_PICK_LOCK, c._name.c_str());
- ErrorScroll::show(g_vm, msg);
+ ErrorScroll::show(g_vm, msg, WT_NONFREEZED_WAIT);
scripts._animCounter = 255;
return true;
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 58f2926e9c..160c60a7a9 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -340,6 +340,7 @@ void Resources::loadData() {
file.syncString(SELECT_CLASS_BEFORE_SAVING);
file.syncString(EXCHANGE_ATTR_WITH);
file.syncNumbers((int *)NEW_CHAR_SKILLS, 10);
+ file.syncNumbers((int *)NEW_CHAR_SKILLS_OFFSET, 10);
file.syncNumbers((int *)NEW_CHAR_SKILLS_LEN, 10);
file.syncNumbers((int *)NEW_CHAR_RACE_SKILLS, 10);
file.syncNumbers((int *)RACE_MAGIC_RESISTENCES, 5);
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index f141a2eb75..55f0ed3413 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -395,6 +395,7 @@ public:
const char *SELECT_CLASS_BEFORE_SAVING;
const char *EXCHANGE_ATTR_WITH;
int NEW_CHAR_SKILLS[10];
+ int NEW_CHAR_SKILLS_OFFSET[10];
int NEW_CHAR_SKILLS_LEN[10];
int NEW_CHAR_RACE_SKILLS[10];
int RACE_MAGIC_RESISTENCES[5];
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 66e9013cda..bc0b179d4c 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -216,20 +216,23 @@ int Scripts::checkEvents() {
MazeObject &selectedObj = map._mobData._objects[intf._objNumber];
if (selectedObj._spriteId == (ccNum ? 15 : 16)) {
- for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
- MazeObject &obj = map._mobData._objects[idx];
- if (obj._spriteId == (ccNum ? 62 : 57)) {
+ // Treasure chests that were opened will be set to be in an open, empty state
+ for (uint idx = 0; idx < map._mobData._objectSprites.size(); ++idx) {
+ MonsterObjectData::SpriteResourceEntry &e = map._mobData._objectSprites[idx];
+ if (e._spriteId == (ccNum ? 57 : 62)) {
selectedObj._id = idx;
- selectedObj._spriteId = ccNum ? 62 : 57;
+ selectedObj._spriteId = ccNum ? 57 : 62;
+ selectedObj._sprites = &e._sprites;
break;
}
}
} else if (selectedObj._spriteId == 73) {
- for (int idx = 0; idx < MIN((int)map._mobData._objects.size(), 16); ++idx) {
- MazeObject &obj = map._mobData._objects[idx];
- if (obj._spriteId == 119) {
+ for (uint idx = 0; idx < map._mobData._objectSprites.size(); ++idx) {
+ MonsterObjectData::SpriteResourceEntry &e = map._mobData._objectSprites[idx];
+ if (e._spriteId == 119) {
selectedObj._id = idx;
selectedObj._spriteId = 119;
+ selectedObj._sprites = &e._sprites;
break;
}
}