[Scummvm-git-logs] scummvm master -> 87966be0e7c7a63e6075daccab32bf7a8019727d
neuromancer
noreply at scummvm.org
Fri Mar 28 13:32:59 UTC 2025
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0fc3fccf8b PRIVATE: Track game events in diary
85466a2e7f PRIVATE: Fix memory movie playback and memory saving
87966be0e7 PRIVATE: Fix unpausing crash, empty memory location crash, and bust movie tracking
Commit: 0fc3fccf8bb5fe655f578b36a0ba97aee8db7a3f
https://github.com/scummvm/scummvm/commit/0fc3fccf8bb5fe655f578b36a0ba97aee8db7a3f
Author: ellm135 (ellm13531 at gmail.com)
Date: 2025-03-28T14:32:55+01:00
Commit Message:
PRIVATE: Track game events in diary
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index aa0573958ca..4ade0a73363 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -77,6 +77,8 @@ static void fDiaryLocList(ArgArray args) {
assert(args[2].type == NUM);
assert(args[3].type == NUM);
+ g_private->_currentDiaryPage = -1;
+
debugC(1, kPrivateDebugScript, "DiaryLocList(%d, %d, %d, %d)", args[0].u.val, args[1].u.val, args[2].u.val, args[3].u.val);
x2 = args[0].u.val;
@@ -90,12 +92,62 @@ static void fDiaryLocList(ArgArray args) {
}
static void fDiaryGoLoc(ArgArray args) {
- debugC(1, kPrivateDebugScript, "WARNING: DiaryGoLoc not implemented");
+ debugC(1, kPrivateDebugScript, "DiaryGoLoc(%d, ..)", args[0].u.val);
+
+ ExitInfo e;
+
+ e.rect = *args[1].u.rect;
+ e.nextSetting = "kDiaryMiddle";
+
+ if (args[0].u.val) {
+ e.cursor = "kTurnRight";
+ g_private->_diaryNextPageExit = e;
+ } else {
+ e.cursor = "kTurnLeft";
+ g_private->_diaryPrevPageExit = e;
+ }
+
+ g_private->_exits.push_front(e);
+}
+
+static void fDiaryPageTurn(ArgArray args) {
+ debugC(1, kPrivateDebugScript, "DiaryPageTurn(%d, ..)", args[0].u.val);
+
+ ExitInfo e;
+ e.nextSetting = "kDiaryMiddle";
+ e.rect = *args[1].u.rect;
+
+ if (args[0].u.val == 1) {
+ e.cursor = "kTurnRight";
+
+ if (g_private->_currentDiaryPage == g_private->_diaryPages.size() - 1) {
+ e.nextSetting = "kDiaryLastPage";
+ }
+
+ g_private->_diaryNextPageExit = e;
+ } else {
+ e.cursor = "kTurnLeft";
+
+ if (g_private->_currentDiaryPage == 0) {
+ e.nextSetting = "kDiaryTOC";
+ }
+
+ g_private->_diaryPrevPageExit = e;
+ }
+
+ g_private->_exits.push_front(e);
+}
+
+static void fDiaryPage(ArgArray args) {
+ debugC(1, kPrivateDebugScript, "DiaryPage(%d, %d, %d, %d, ..)", args[0].u.rect->left, args[0].u.rect->top, args[0].u.rect->right, args[0].u.rect->bottom);
+ g_private->loadMemories(*args[0].u.rect, args[1].u.val, args[2].u.val);
}
static void fDiaryInvList(ArgArray args) {
debugC(1, kPrivateDebugScript, "DiaryInvList(%d, ..)", args[0].u.val);
+ g_private->_currentDiaryPage = g_private->_diaryPages.size();
+
const Common::Rect *r1 = args[1].u.rect;
const Common::Rect *r2 = args[2].u.rect;
@@ -524,6 +576,7 @@ static void fMovie(ArgArray args) {
Common::String nextSetting = *args[1].u.sym->name;
if (!g_private->_playedMovies.contains(movie) && movie != "\"\"") {
+ g_private->addMemory(movie);
g_private->_nextMovie = movie;
g_private->_playedMovies.setVal(movie, true);
g_private->_nextSetting = nextSetting;
@@ -791,6 +844,8 @@ const FuncTable funcTable[] = {
// Diary
{fDiaryLocList, "DiaryLocList"},
+ {fDiaryPageTurn, "DiaryPageTurn"},
+ {fDiaryPage, "DiaryPage"},
{fDiaryInvList, "DiaryInvList"},
{fDiaryGoLoc, "DiaryGoLoc"},
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index c7b5d75cc4d..00331ef2a3e 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -108,6 +108,7 @@ PrivateEngine::PrivateEngine(OSystem *syst, const ADGameDescription *gd)
// Diary
_diaryLocPrefix = "inface/diary/loclist/";
+ _currentDiaryPage = 0;
// Safe
_safeNumberPath = "sg/search_s/sgsaf%d.bmp";
@@ -239,6 +240,8 @@ Common::Error PrivateEngine::run() {
_compositeSurface->create(_screenW, _screenH, _pixelFormat);
_compositeSurface->setTransparentColor(_transparentColor);
+ _currentDiaryPage = 0;
+
// Load the game frame once
byte *palette;
_frameImage = decodeImage(_framePath, nullptr);
@@ -293,6 +296,14 @@ Common::Error PrivateEngine::run() {
break;
else if (selectSafeDigit(mousePos))
break;
+ else if (selectDiaryNextPage(mousePos))
+ break;
+ else if (selectDiaryPrevPage(mousePos))
+ break;
+ else if (selectLocation(mousePos))
+ break;
+ else if (selectMemory(mousePos))
+ break;
selectPauseGame(mousePos);
selectPhoneArea(mousePos);
@@ -391,6 +402,8 @@ void PrivateEngine::initFuncs() {
void PrivateEngine::clearAreas() {
_exits.clear();
_masks.clear();
+ _locationMasks.clear();
+ _memoryMasks.clear();
if (_loadGameMask.surf)
_loadGameMask.surf->free();
@@ -737,6 +750,158 @@ void PrivateEngine::selectMask(Common::Point mousePos) {
}
}
+bool PrivateEngine::selectLocation(Common::Point mousePos) {
+ if (_locationMasks.size() == 0) {
+ return false;
+ }
+
+ uint i = 0;
+ uint totalLocations = 0;
+ for (NameList::const_iterator it = maps.locationList.begin(); it != maps.locationList.end(); ++it) {
+ const Private::Symbol *sym = maps.locations.getVal(*it);
+ if (sym->u.val) {
+ if (inMask(_locationMasks[i].surf, mousePos)) {
+ for (uint j = 0; j < _diaryPages.size(); j++) {
+ if (_diaryPages[j].locationID == totalLocations + 1) {
+ _currentDiaryPage = j;
+ break;
+ }
+ }
+
+ _numberClicks++;
+ _nextSetting = _locationMasks[i].nextSetting;
+
+ return true;
+ }
+ i++;
+ }
+ totalLocations++;
+ }
+
+ return false;
+}
+
+bool PrivateEngine::selectDiaryNextPage(Common::Point mousePos) {
+ mousePos = mousePos - _origin;
+ if (mousePos.x < 0 || mousePos.y < 0)
+ return false;
+
+ if (_diaryNextPageExit.rect.contains(mousePos)) {
+ _currentDiaryPage++;
+ _nextSetting = _diaryNextPageExit.nextSetting;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool PrivateEngine::selectDiaryPrevPage(Common::Point mousePos) {
+ mousePos = mousePos - _origin;
+ if (mousePos.x < 0 || mousePos.y < 0)
+ return false;
+
+ if (_diaryPrevPageExit.rect.contains(mousePos)) {
+ _currentDiaryPage--;
+ _nextSetting = _diaryPrevPageExit.nextSetting;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool PrivateEngine::selectMemory(Common::Point mousePos) {
+ if (_memoryMasks.size() == 0) {
+ return false;
+ }
+
+ for (uint i = 0; i < _memoryMasks.size(); i++) {
+ if (inMask(_memoryMasks[i].surf, mousePos)) {
+ _masks.clear();
+ _memoryMasks.clear();
+ _exits.clear();
+ _nextMovie = _diaryPages[_currentDiaryPage].memories[i].movie;
+ _nextSetting = "kDiaryMiddle";
+ loadImage("inface\\general\\inface2.bmp", 0, 0);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void PrivateEngine::addMemory(Common::String path) {
+ size_t index = path.findLastOf('\\');
+ Common::String location = path.substr(index + 2, 2);
+
+ Common::String imagePath;
+
+ // Paths to the global folder have a different pattern from other paths
+ if (path.contains("global")) {
+ if (path.contains("spoc00xs")) {
+ imagePath = "inface\\diary\\ss_icons\\global\\transiti\\ipoc00.bmp";
+ } else {
+ imagePath = "inface\\diary\\ss_icons\\global\\transiti\\animatio\\mo\\imo" + path.substr(index + 4, 3) + ".bmp";
+ }
+ } else {
+ // First letter after the last \ is an s, which isn't needed; next 2 are location; and the next 3 are what image to use
+ imagePath = "inface\\diary\\ss_icons\\" + location + "\\i" + location + path.substr(index + 4, 3) + ".bmp";
+ }
+
+
+ if (!Common::File::exists(convertPath(imagePath))) {
+ return;
+ }
+
+ MemoryInfo memory;
+ memory.movie = path;
+ memory.image = imagePath;
+
+ for (int i = _diaryPages.size() - 1; i >= 0; i--) {
+ if (_diaryPages[i].locationName == location) {
+ if (_diaryPages[i].memories.size() == 6) {
+ DiaryPage diaryPage = DiaryPage();
+ diaryPage.locationName = location;
+ diaryPage.locationID = _diaryPages[i].locationID;
+ diaryPage.memories.push_back(memory);
+ _diaryPages.insert_at(i + 1, diaryPage);
+ return;
+ }
+ _diaryPages[i].memories.push_back(memory);
+
+ return;
+ }
+ }
+
+ DiaryPage diaryPage = DiaryPage();
+ diaryPage.locationName = location;
+
+ uint locationIndex = 0;
+ for (NameList::const_iterator it = maps.locationList.begin(); it != maps.locationList.end(); ++it) {
+ const Private::Symbol *sym = maps.locations.getVal(*it);
+ locationIndex++;
+
+ Common::String currentLocation = it->substr(9);
+ currentLocation.toLowercase();
+ if (sym->u.val && currentLocation == location) {
+ diaryPage.locationID = locationIndex;
+ break;
+ }
+ }
+
+ diaryPage.memories.push_back(memory);
+
+ for (int i = _diaryPages.size() - 1; i >= 0; i--) {
+ if (_diaryPages[i].locationID < diaryPage.locationID) {
+ _diaryPages.insert_at(i + 1, diaryPage);
+ return;
+ }
+ }
+
+ _diaryPages.insert_at(0, diaryPage);
+}
+
void PrivateEngine::selectAMRadioArea(Common::Point mousePos) {
if (_AMRadioArea.surf == nullptr)
return;
@@ -969,6 +1134,7 @@ void PrivateEngine::restartGame() {
}
inventory.clear();
_dossiers.clear();
+ _diaryPages.clear();
// Sounds
_AMRadio.clear();
@@ -1497,8 +1663,14 @@ void PrivateEngine::loadLocations(const Common::Rect &rect) {
Common::String s =
Common::String::format("%sdryloc%d.bmp", _diaryLocPrefix.c_str(), i);
- Graphics::Surface *surface = loadMask(s, rect.left + 120, rect.top + offset, true);
- delete surface;
+ MaskInfo m;
+ m.surf = loadMask(s, rect.left + 120, rect.top + offset, true);
+ m.cursor = g_private->getExitCursor();
+ m.nextSetting = "kDiaryMiddle";
+ m.flag1 = nullptr;
+ m.flag2 = nullptr;
+ _masks.push_front(m);
+ _locationMasks.push_back(m);
}
}
}
@@ -1512,4 +1684,32 @@ void PrivateEngine::loadInventory(uint32 x, const Common::Rect &r1, const Common
}
}
+void PrivateEngine::loadMemories(const Common::Rect &rect, uint rightPageOffset, uint verticalOffset) {
+ Common::String s = Common::String::format("inface\\diary\\loctabs\\drytab%d.bmp", _diaryPages[_currentDiaryPage].locationID);
+ loadImage(s, 0, 0);
+
+ uint memoriesLoaded = 0;
+ uint currentVerticalOffset = 0;
+ uint horizontalOffset = 0;
+
+ for (uint i = 0; i < _diaryPages[_currentDiaryPage].memories.size(); i++) {
+ MaskInfo m;
+ m.surf = loadMask(_diaryPages[_currentDiaryPage].memories[i].image, rect.left + horizontalOffset, rect.top + currentVerticalOffset, true);
+ m.cursor = g_private->getExitCursor();
+ m.nextSetting = "kDiaryMiddle";
+ m.flag1 = nullptr;
+ m.flag2 = nullptr;
+ _masks.push_front(m);
+ _memoryMasks.push_back(m);
+
+ currentVerticalOffset += verticalOffset;
+ memoriesLoaded++;
+
+ if (memoriesLoaded == 3) {
+ horizontalOffset = rightPageOffset;
+ currentVerticalOffset = 0;
+ }
+ }
+}
+
} // End of namespace Private
diff --git a/engines/private/private.h b/engines/private/private.h
index 874deeaa6db..d730c8168a3 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -112,6 +112,17 @@ typedef struct CursorInfo {
Graphics::WinCursorGroup *winCursorGroup;
} CursorInfo;
+typedef struct MemoryInfo {
+ Common::String image;
+ Common::String movie;
+} MemoryInfo;
+
+typedef struct DiaryPage {
+ Common::String locationName;
+ Common::Array<MemoryInfo> memories;
+ uint locationID;
+} DiaryPage;
+
// funcs
typedef struct FuncTable {
@@ -133,6 +144,7 @@ typedef Common::List<Common::String> InvList;
// arrays
typedef Common::Array<DossierInfo> DossierArray;
+typedef Common::Array<DiaryPage> DiaryPages;
// hash tables
@@ -284,6 +296,18 @@ public:
void loadLocations(const Common::Rect &);
void loadInventory(uint32, const Common::Rect &, const Common::Rect &);
bool _toTake;
+ DiaryPages _diaryPages;
+ uint _currentDiaryPage;
+ ExitInfo _diaryNextPageExit;
+ ExitInfo _diaryPrevPageExit;
+ bool selectDiaryNextPage(Common::Point mousePos);
+ bool selectDiaryPrevPage(Common::Point mousePos);
+ void addMemory(Common::String path);
+ void loadMemories(const Common::Rect &rect, uint rightPageOffset, uint verticalOffset);
+ bool selectLocation(Common::Point mousePos);
+ Common::Array<MaskInfo> _locationMasks;
+ Common::Array<MaskInfo> _memoryMasks;
+ bool selectMemory(Common::Point mousePos);
// Save/Load games
MaskInfo _saveGameMask;
Commit: 85466a2e7f369ce881aceb54e5090a063443d325
https://github.com/scummvm/scummvm/commit/85466a2e7f369ce881aceb54e5090a063443d325
Author: ellm135 (ellm13531 at gmail.com)
Date: 2025-03-28T14:32:55+01:00
Commit Message:
PRIVATE: Fix memory movie playback and memory saving
Changed paths:
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 00331ef2a3e..d293cbb9f03 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -261,6 +261,7 @@ Common::Error PrivateEngine::run() {
Common::Event event;
Common::Point mousePos;
_videoDecoder = nullptr;
+ _pausedVideo = nullptr;
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0) { // load the savegame
loadGameState(saveSlot);
@@ -268,6 +269,8 @@ Common::Error PrivateEngine::run() {
_nextSetting = getGoIntroSetting();
}
+ _isMemoryMoviePlaying = false;
+
while (!shouldQuit()) {
checkPhoneCall();
@@ -302,8 +305,10 @@ Common::Error PrivateEngine::run() {
break;
else if (selectLocation(mousePos))
break;
- else if (selectMemory(mousePos))
+ else if (selectMemory(mousePos)) {
+ _isMemoryMoviePlaying = true;
break;
+ }
selectPauseGame(mousePos);
selectPhoneArea(mousePos);
@@ -352,13 +357,21 @@ Common::Error PrivateEngine::run() {
}
if (_videoDecoder && !_videoDecoder->isPaused()) {
- if (_videoDecoder->getCurFrame() == 0)
+ if (_videoDecoder->getCurFrame() == 0) {
stopSound(true);
+
+ if (_isMemoryMoviePlaying) {
+ const byte *videoPalette = _videoDecoder->getPalette();
+ g_system->getPaletteManager()->setPalette(videoPalette, 0, 256);
+ drawScreenFrame(videoPalette);
+ }
+ }
if (_videoDecoder->endOfVideo()) {
_videoDecoder->close();
delete _videoDecoder;
_videoDecoder = nullptr;
_currentMovie = "";
+ _isMemoryMoviePlaying = false;
} else if (_videoDecoder->needsUpdate()) {
drawScreen();
}
@@ -659,6 +672,7 @@ void PrivateEngine::selectPauseGame(Common::Point mousePos) {
_nextSetting = getPauseMovieSetting();
if (_videoDecoder) {
_videoDecoder->pauseVideo(true);
+ _pausedVideo = _videoDecoder;
}
_compositeSurface->fillRect(_screenRect, 0);
_compositeSurface->setPalette(_framePalette, 0, 256);
@@ -675,6 +689,12 @@ void PrivateEngine::resumeGame() {
_pausedSetting = "";
_mode = 1;
_origin = Common::Point(kOriginOne[0], kOriginOne[1]);
+
+ if (_pausedVideo != nullptr) {
+ _videoDecoder = _pausedVideo;
+ _pausedVideo = nullptr;
+ }
+
if (_videoDecoder) {
_videoDecoder->pauseVideo(false);
const byte *videoPalette = g_private->_videoDecoder->getPalette();
@@ -750,15 +770,15 @@ void PrivateEngine::selectMask(Common::Point mousePos) {
}
}
-bool PrivateEngine::selectLocation(Common::Point mousePos) {
+bool PrivateEngine::selectLocation(const Common::Point &mousePos) {
if (_locationMasks.size() == 0) {
return false;
}
uint i = 0;
uint totalLocations = 0;
- for (NameList::const_iterator it = maps.locationList.begin(); it != maps.locationList.end(); ++it) {
- const Private::Symbol *sym = maps.locations.getVal(*it);
+ for (auto &it : maps.locationList) {
+ const Private::Symbol *sym = maps.locations.getVal(it);
if (sym->u.val) {
if (inMask(_locationMasks[i].surf, mousePos)) {
for (uint j = 0; j < _diaryPages.size(); j++) {
@@ -811,11 +831,7 @@ bool PrivateEngine::selectDiaryPrevPage(Common::Point mousePos) {
return false;
}
-bool PrivateEngine::selectMemory(Common::Point mousePos) {
- if (_memoryMasks.size() == 0) {
- return false;
- }
-
+bool PrivateEngine::selectMemory(const Common::Point &mousePos) {
for (uint i = 0; i < _memoryMasks.size(); i++) {
if (inMask(_memoryMasks[i].surf, mousePos)) {
_masks.clear();
@@ -823,7 +839,6 @@ bool PrivateEngine::selectMemory(Common::Point mousePos) {
_exits.clear();
_nextMovie = _diaryPages[_currentDiaryPage].memories[i].movie;
_nextSetting = "kDiaryMiddle";
- loadImage("inface\\general\\inface2.bmp", 0, 0);
return true;
}
}
@@ -831,7 +846,7 @@ bool PrivateEngine::selectMemory(Common::Point mousePos) {
return false;
}
-void PrivateEngine::addMemory(Common::String path) {
+void PrivateEngine::addMemory(const Common::String &path) {
size_t index = path.findLastOf('\\');
Common::String location = path.substr(index + 2, 2);
@@ -840,16 +855,15 @@ void PrivateEngine::addMemory(Common::String path) {
// Paths to the global folder have a different pattern from other paths
if (path.contains("global")) {
if (path.contains("spoc00xs")) {
- imagePath = "inface\\diary\\ss_icons\\global\\transiti\\ipoc00.bmp";
+ imagePath = "inface/diary/ss_icons/global/transiti/ipoc00.bmp";
} else {
- imagePath = "inface\\diary\\ss_icons\\global\\transiti\\animatio\\mo\\imo" + path.substr(index + 4, 3) + ".bmp";
+ imagePath = "inface/diary/ss_icons/global/transiti/animatio/mo/imo" + path.substr(index + 4, 3) + ".bmp";
}
} else {
// First letter after the last \ is an s, which isn't needed; next 2 are location; and the next 3 are what image to use
- imagePath = "inface\\diary\\ss_icons\\" + location + "\\i" + location + path.substr(index + 4, 3) + ".bmp";
+ imagePath = "inface/diary/ss_icons/" + location + "/i" + location + path.substr(index + 4, 3) + ".bmp";
}
-
if (!Common::File::exists(convertPath(imagePath))) {
return;
}
@@ -861,7 +875,7 @@ void PrivateEngine::addMemory(Common::String path) {
for (int i = _diaryPages.size() - 1; i >= 0; i--) {
if (_diaryPages[i].locationName == location) {
if (_diaryPages[i].memories.size() == 6) {
- DiaryPage diaryPage = DiaryPage();
+ DiaryPage diaryPage;
diaryPage.locationName = location;
diaryPage.locationID = _diaryPages[i].locationID;
diaryPage.memories.push_back(memory);
@@ -874,15 +888,15 @@ void PrivateEngine::addMemory(Common::String path) {
}
}
- DiaryPage diaryPage = DiaryPage();
+ DiaryPage diaryPage;
diaryPage.locationName = location;
uint locationIndex = 0;
- for (NameList::const_iterator it = maps.locationList.begin(); it != maps.locationList.end(); ++it) {
- const Private::Symbol *sym = maps.locations.getVal(*it);
+ for (auto &it : maps.locationList) {
+ const Private::Symbol *sym = maps.locations.getVal(it);
locationIndex++;
- Common::String currentLocation = it->substr(9);
+ Common::String currentLocation = it.substr(9);
currentLocation.toLowercase();
if (sym->u.val && currentLocation == location) {
diaryPage.locationID = locationIndex;
@@ -1135,6 +1149,7 @@ void PrivateEngine::restartGame() {
inventory.clear();
_dossiers.clear();
_diaryPages.clear();
+ _isMemoryMoviePlaying = false;
// Sounds
_AMRadio.clear();
@@ -1145,6 +1160,7 @@ void PrivateEngine::restartGame() {
// Movies
_repeatedMovieExit = "";
_playedMovies.clear();
+ _pausedVideo = nullptr;
// Pause
_pausedSetting = "";
@@ -1156,6 +1172,7 @@ void PrivateEngine::restartGame() {
Common::Error PrivateEngine::loadGameStream(Common::SeekableReadStream *stream) {
// We don't want to continue with any sound from a previous game
stopSound(true);
+ _pausedVideo = nullptr;
Common::Serializer s(stream, nullptr);
debugC(1, kPrivateDebugFunction, "loadGameStream");
@@ -1181,6 +1198,25 @@ Common::Error PrivateEngine::loadGameStream(Common::SeekableReadStream *stream)
inventory.push_back(stream->readString());
}
+ // Diary pages
+ _diaryPages.clear();
+ uint32 diaryPagesSize = stream->readUint32LE();
+ for (uint32 i = 0; i < diaryPagesSize; i++) {
+ DiaryPage diaryPage;
+ diaryPage.locationName = stream->readString();
+ diaryPage.locationID = stream->readUint32LE();
+
+ uint32 memoriesSize = stream->readUint32LE();
+ for (uint32 j = 0; j < memoriesSize; j++) {
+ MemoryInfo memory;
+ memory.image = stream->readString();
+ memory.movie = stream->readString();
+ diaryPage.memories.push_back(memory);
+ }
+
+ _diaryPages.push_back(diaryPage);
+ }
+
// Dossiers
_dossiers.clear();
size = stream->readUint32LE();
@@ -1280,6 +1316,22 @@ Common::Error PrivateEngine::saveGameStream(Common::WriteStream *stream, bool is
stream->writeByte(0);
}
+ stream->writeUint32LE(_diaryPages.size());
+ for (uint i = 0; i < _diaryPages.size(); i++) {
+ stream->writeString(_diaryPages[i].locationName);
+ stream->writeByte(0);
+
+ stream->writeUint32LE(_diaryPages[i].locationID);
+ stream->writeUint32LE(_diaryPages[i].memories.size());
+
+ for (uint j = 0; j < _diaryPages[i].memories.size(); j++) {
+ stream->writeString(_diaryPages[i].memories[j].image);
+ stream->writeByte(0);
+ stream->writeString(_diaryPages[i].memories[j].movie);
+ stream->writeByte(0);
+ }
+ }
+
// Dossiers
stream->writeUint32LE(_dossiers.size());
for (DossierArray::const_iterator it = _dossiers.begin(); it != _dossiers.end(); ++it) {
@@ -1415,6 +1467,7 @@ void PrivateEngine::skipVideo() {
delete _videoDecoder;
_videoDecoder = nullptr;
_currentMovie = "";
+ _isMemoryMoviePlaying = false;
}
void PrivateEngine::stopSound(bool all) {
@@ -1685,7 +1738,7 @@ void PrivateEngine::loadInventory(uint32 x, const Common::Rect &r1, const Common
}
void PrivateEngine::loadMemories(const Common::Rect &rect, uint rightPageOffset, uint verticalOffset) {
- Common::String s = Common::String::format("inface\\diary\\loctabs\\drytab%d.bmp", _diaryPages[_currentDiaryPage].locationID);
+ Common::String s = Common::String::format("inface/diary/loctabs/drytab%d.bmp", _diaryPages[_currentDiaryPage].locationID);
loadImage(s, 0, 0);
uint memoriesLoaded = 0;
diff --git a/engines/private/private.h b/engines/private/private.h
index d730c8168a3..0210a026c0a 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -172,6 +172,7 @@ public:
Audio::SoundHandle _fgSoundHandle;
Audio::SoundHandle _bgSoundHandle;
Video::SmackerDecoder *_videoDecoder;
+ Video::SmackerDecoder *_pausedVideo;
Common::InstallShieldV3 _installerArchive;
Common::Error run() override;
@@ -302,12 +303,13 @@ public:
ExitInfo _diaryPrevPageExit;
bool selectDiaryNextPage(Common::Point mousePos);
bool selectDiaryPrevPage(Common::Point mousePos);
- void addMemory(Common::String path);
+ void addMemory(const Common::String &path);
void loadMemories(const Common::Rect &rect, uint rightPageOffset, uint verticalOffset);
- bool selectLocation(Common::Point mousePos);
+ bool selectLocation(const Common::Point &mousePos);
Common::Array<MaskInfo> _locationMasks;
Common::Array<MaskInfo> _memoryMasks;
- bool selectMemory(Common::Point mousePos);
+ bool selectMemory(const Common::Point &mousePos);
+ bool _isMemoryMoviePlaying;
// Save/Load games
MaskInfo _saveGameMask;
Commit: 87966be0e7c7a63e6075daccab32bf7a8019727d
https://github.com/scummvm/scummvm/commit/87966be0e7c7a63e6075daccab32bf7a8019727d
Author: ellm135 (ellm13531 at gmail.com)
Date: 2025-03-28T14:32:55+01:00
Commit Message:
PRIVATE: Fix unpausing crash, empty memory location crash, and bust movie tracking
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index 4ade0a73363..64d1208b7e5 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -266,6 +266,10 @@ static void fBustMovie(ArgArray args) {
g_private->_nextMovie = pv;
g_private->_nextSetting = args[0].u.sym->name->c_str();
+
+ Common::String memoryPath = pv;
+ memoryPath.replace('/', '\\');
+ g_private->addMemory(memoryPath);
}
static void fDossierAdd(ArgArray args) {
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index d293cbb9f03..fdacbbf4093 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -269,7 +269,7 @@ Common::Error PrivateEngine::run() {
_nextSetting = getGoIntroSetting();
}
- _isMemoryMoviePlaying = false;
+ _needToDrawScreenFrame = false;
while (!shouldQuit()) {
checkPhoneCall();
@@ -306,7 +306,7 @@ Common::Error PrivateEngine::run() {
else if (selectLocation(mousePos))
break;
else if (selectMemory(mousePos)) {
- _isMemoryMoviePlaying = true;
+ _needToDrawScreenFrame = true;
break;
}
@@ -359,19 +359,20 @@ Common::Error PrivateEngine::run() {
if (_videoDecoder && !_videoDecoder->isPaused()) {
if (_videoDecoder->getCurFrame() == 0) {
stopSound(true);
+ }
+
+ if (_needToDrawScreenFrame && _videoDecoder->getCurFrame() >= 0) {
+ const byte *videoPalette = _videoDecoder->getPalette();
+ g_system->getPaletteManager()->setPalette(videoPalette, 0, 256);
+ drawScreenFrame(videoPalette);
+ _needToDrawScreenFrame = false;
+ }
- if (_isMemoryMoviePlaying) {
- const byte *videoPalette = _videoDecoder->getPalette();
- g_system->getPaletteManager()->setPalette(videoPalette, 0, 256);
- drawScreenFrame(videoPalette);
- }
- }
if (_videoDecoder->endOfVideo()) {
_videoDecoder->close();
delete _videoDecoder;
_videoDecoder = nullptr;
_currentMovie = "";
- _isMemoryMoviePlaying = false;
} else if (_videoDecoder->needsUpdate()) {
drawScreen();
}
@@ -697,9 +698,7 @@ void PrivateEngine::resumeGame() {
if (_videoDecoder) {
_videoDecoder->pauseVideo(false);
- const byte *videoPalette = g_private->_videoDecoder->getPalette();
- g_system->getPaletteManager()->setPalette(videoPalette, 0, 256);
- drawScreenFrame(videoPalette);
+ _needToDrawScreenFrame = true;
}
}
@@ -781,14 +780,22 @@ bool PrivateEngine::selectLocation(const Common::Point &mousePos) {
const Private::Symbol *sym = maps.locations.getVal(it);
if (sym->u.val) {
if (inMask(_locationMasks[i].surf, mousePos)) {
+ bool diaryPageSet = false;
for (uint j = 0; j < _diaryPages.size(); j++) {
if (_diaryPages[j].locationID == totalLocations + 1) {
_currentDiaryPage = j;
+ diaryPageSet = true;
break;
}
}
-
+
_numberClicks++;
+
+ // Prevent crash if there are no memories for this location
+ if (!diaryPageSet) {
+ return true;
+ }
+
_nextSetting = _locationMasks[i].nextSetting;
return true;
@@ -1149,7 +1156,6 @@ void PrivateEngine::restartGame() {
inventory.clear();
_dossiers.clear();
_diaryPages.clear();
- _isMemoryMoviePlaying = false;
// Sounds
_AMRadio.clear();
@@ -1467,7 +1473,6 @@ void PrivateEngine::skipVideo() {
delete _videoDecoder;
_videoDecoder = nullptr;
_currentMovie = "";
- _isMemoryMoviePlaying = false;
}
void PrivateEngine::stopSound(bool all) {
diff --git a/engines/private/private.h b/engines/private/private.h
index 0210a026c0a..9b47861ef62 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -249,6 +249,7 @@ public:
Common::String _currentVS;
Common::Point _origin;
void drawScreen();
+ bool _needToDrawScreenFrame;
// settings
Common::String _nextSetting;
@@ -309,7 +310,6 @@ public:
Common::Array<MaskInfo> _locationMasks;
Common::Array<MaskInfo> _memoryMasks;
bool selectMemory(const Common::Point &mousePos);
- bool _isMemoryMoviePlaying;
// Save/Load games
MaskInfo _saveGameMask;
More information about the Scummvm-git-logs
mailing list