diff options
-rw-r--r-- | README | 29 | ||||
-rw-r--r-- | common/hashmap.h | 2 | ||||
-rw-r--r-- | devtools/create_xeen/constants.cpp | 4 | ||||
-rw-r--r-- | dists/engine-data/xeen.ccs | bin | 55550 -> 55594 bytes | |||
-rw-r--r-- | engines/mohawk/myst_state.cpp | 16 | ||||
-rw-r--r-- | engines/mohawk/riven_saveload.cpp | 3 | ||||
-rw-r--r-- | engines/sludge/builtin.cpp | 35 | ||||
-rw-r--r-- | engines/sludge/functionlist.h | 338 | ||||
-rw-r--r-- | engines/sludge/sludger.cpp | 7 | ||||
-rw-r--r-- | engines/sludge/sludger.h | 1 | ||||
-rw-r--r-- | engines/sludge/timing.cpp | 54 | ||||
-rw-r--r-- | engines/sludge/timing.h | 24 | ||||
-rw-r--r-- | engines/xeen/dialogs/dialogs_create_char.cpp | 3 | ||||
-rw-r--r-- | engines/xeen/interface.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/map.h | 2 | ||||
-rw-r--r-- | engines/xeen/party.cpp | 4 | ||||
-rw-r--r-- | engines/xeen/resources.cpp | 1 | ||||
-rw-r--r-- | engines/xeen/resources.h | 1 | ||||
-rw-r--r-- | engines/xeen/scripts.cpp | 17 |
19 files changed, 296 insertions, 247 deletions
@@ -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 Binary files differindex d4c6dd68a8..88671fb669 100644 --- a/dists/engine-data/xeen.ccs +++ b/dists/engine-data/xeen.ccs 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; } } |