[Scummvm-git-logs] scummvm master -> ff60aed2691447f2826a496cda247863f11e11c4

sdelamarre noreply at scummvm.org
Wed Apr 5 21:31:17 UTC 2023


This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
830e6b9465 GOB: implement Adibou1 opcodes related to application selection
f5f5da58ba GOB: fix the "fill" tool in Adibou1 paint game
82ed59a150 GOB: skipping copy protection of Adibou1 applications
de53ff1cae GOB: save application progress in Adibou1
bda696d019 GOB: workaround for some Adibou1 versions triggering the "quit" action instead of the chosen Read/Count app
f57d2b189c GOB: save/load drawings for "Paint" game in Adibou1
9fa5a30612 GOB: save/load scenes in Adibou1 construction game
ff60aed269 GOB: spriteOperation(0) is spriteOperation(DRAW_BLITSURF)


Commit: 830e6b9465464579bfeca16e5e52b325374cdb36
    https://github.com/scummvm/scummvm/commit/830e6b9465464579bfeca16e5e52b325374cdb36
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: implement Adibou1 opcodes related to application selection

This makes possible to select and play "Read/Count 4-5 years" (aka L5, C5) and "Read/Count 6-7 years" (aka L6, C6) applications, by clicking on the door of Adibou's house.

Remove also related previous Adibou1 stubs in inter_v2.

Changed paths:
  A engines/gob/inter_adibou1.cpp
    engines/gob/gob.cpp
    engines/gob/inter.h
    engines/gob/inter_v2.cpp
    engines/gob/module.mk


diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index a559d9da63d..9a7275ac595 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -637,7 +637,7 @@ Common::Error GobEngine::initGameParts() {
 	case kGameTypeAdibou1:
 		_init     = new Init_v2(this);
 		_video    = new Video_v2(this);
-		_inter    = new Inter_v2(this);
+		_inter    = new Inter_Adibou1(this);
 		_mult     = new Mult_v2(this);
 		_draw     = new Draw_v2(this);
 		_map      = new Map_v2(this);
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 8a2caa5cb3d..c062911aeae 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -448,8 +448,6 @@ protected:
 	void o2_writeData(OpFuncParams &params);
 	void o2_loadInfogramesIns(OpGobParams &params);
 	void o2_playInfogrames(OpGobParams &params);
-	void o2_gob0x0B(OpGobParams &params);
-	void o2_gob1001(OpGobParams &params);
 	void o2_startInfogrames(OpGobParams &params);
 	void o2_stopInfogrames(OpGobParams &params);
 	void o2_handleGoblins(OpGobParams &params);
@@ -532,6 +530,20 @@ protected:
 	void oLittleRed_playComposition(OpFuncParams &params);
 };
 
+class Inter_Adibou1 : public Inter_v2 {
+public:
+	Inter_Adibou1(GobEngine *vm);
+	~Inter_Adibou1() override {}
+
+protected:
+	void setupOpcodesDraw() override;
+	void setupOpcodesFunc() override;
+	void setupOpcodesGob() override;
+
+	void oAdibou1_getAppliNameFromId(OpGobParams &params);
+	void oAdibou1_listApplications(OpGobParams &params);
+};
+
 class Inter_v3 : public Inter_v2 {
 public:
 	Inter_v3(GobEngine *vm);
diff --git a/engines/gob/inter_adibou1.cpp b/engines/gob/inter_adibou1.cpp
new file mode 100644
index 00000000000..ffe9725803d
--- /dev/null
+++ b/engines/gob/inter_adibou1.cpp
@@ -0,0 +1,123 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/str.h"
+
+#include "gob/inter.h"
+#include "gob/game.h"
+#include "gob/script.h"
+
+
+namespace Gob {
+
+#define OPCODEVER Inter_Adibou1
+#define OPCODEDRAW(i, x)  _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x)
+#define OPCODEFUNC(i, x)  _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x)
+#define OPCODEGOB(i, x)   _opcodesGob[i]._OPCODEGOB(OPCODEVER, x)
+
+Inter_Adibou1::Inter_Adibou1(GobEngine *vm) : Inter_v2(vm) {
+}
+
+void Inter_Adibou1::setupOpcodesDraw() {
+	Inter_v2::setupOpcodesDraw();
+}
+
+void Inter_Adibou1::setupOpcodesFunc() {
+	Inter_v2::setupOpcodesFunc();
+}
+
+void Inter_Adibou1::setupOpcodesGob() {
+	OPCODEGOB(10, oAdibou1_getAppliNameFromId);
+	OPCODEGOB(11, oAdibou1_listApplications);
+}
+
+void Inter_Adibou1::oAdibou1_getAppliNameFromId(OpGobParams &params) {
+	uint16 resultAppliNameVarOffset = 4 * _vm->_game->_script->readUint16();
+	uint16 wantedAppliIdVar = _vm->_game->_script->readUint16();
+	byte wantedAppliId = READ_VAR_UINT8(wantedAppliIdVar);
+
+	WRITE_VARO_STR(resultAppliNameVarOffset, "");
+
+	Common::ArchiveMemberList files;
+	SearchMan.listMatchingMembers(files, "*.BOU");
+	bool firstFile = true;
+	for (Common::ArchiveMemberPtr &file : files) {
+		Common::SeekableReadStream *stream = file->createReadStream();
+		char appliName[4];
+		stream->read(appliName, 3); // Application name, e.g. "C51"
+		appliName[3] = '\0';
+		stream->seek(31);
+		byte appliId = stream->readByte(); // Application numeric ID
+		Common::String appliFilename = Common::String(appliName);
+		appliFilename.toUppercase();
+		appliFilename += ".BOU";
+
+		if (file->getName() == appliFilename) {
+			// First .BOU file is taken as default if the wanted appli is not found
+			if (firstFile || appliId == wantedAppliId)
+				WRITE_VARO_STR(resultAppliNameVarOffset, appliName);
+			if (appliId == wantedAppliId)
+				break;
+		}
+
+		firstFile = false;
+		delete stream;
+	}
+}
+
+void Inter_Adibou1::oAdibou1_listApplications(OpGobParams &params) {
+	uint16 listAppliIdsVarOffset = 4 * _vm->_game->_script->readUint16();
+	uint16 listAppliNamesVarOffset = 4 * _vm->_game->_script->readUint16();
+
+	for (int i = 0; i < 40; i++)
+		WRITE_VARO_UINT8(listAppliNamesVarOffset + i, '\0');
+
+	WRITE_VARO_UINT8(listAppliIdsVarOffset, 0);
+
+	// Look for installed applications .BOU files (C51.BOU, L51.BOU...)
+	Common::ArchiveMemberList files;
+	SearchMan.listMatchingMembers(files, "*.BOU");
+	for (Common::ArchiveMemberPtr &file : files) {
+		Common::SeekableReadStream *stream = file->createReadStream();
+		char appliName[4];
+		stream->read(appliName, 3); // Application name, e.g. "C51"
+		appliName[3] = '\0';
+		stream->seek(31);
+		byte idAppli = stream->readByte(); // Application numeric ID
+
+		Common::String appliFilename = Common::String(appliName);
+		appliFilename.toUppercase();
+		appliFilename += ".BOU";
+
+		WRITE_VARO_UINT8(listAppliIdsVarOffset, idAppli);
+		WRITE_VARO_UINT8(listAppliNamesVarOffset, appliFilename[0]);
+		WRITE_VARO_UINT8(listAppliNamesVarOffset + 1, appliFilename[1]);
+
+		if (file->getName() == appliFilename) {
+			++listAppliIdsVarOffset;
+			listAppliNamesVarOffset += 2;
+		}
+
+		delete stream;
+	}
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 691ca74f2bc..29b51801956 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -140,13 +140,11 @@ void Inter_v2::setupOpcodesGob() {
 	OPCODEGOB(  2, o2_stopInfogrames);
 
 	OPCODEGOB( 10, o2_playInfogrames);
-	OPCODEGOB( 11, o2_gob0x0B);
 
 	OPCODEGOB(100, o2_handleGoblins);
 
 	OPCODEGOB(500, o2_playProtracker);
 	OPCODEGOB(501, o2_stopProtracker);
-	OPCODEGOB(1001, o2_gob1001);
 }
 
 void Inter_v2::checkSwitchTable(uint32 &offset) {
@@ -1592,16 +1590,6 @@ void Inter_v2::o2_playInfogrames(OpGobParams &params) {
 	_vm->_sound->infogramesPlay();
 }
 
-void Inter_v2::o2_gob0x0B(OpGobParams &params) {
-	_vm->_game->_script->skip(4);
-	warning("STUB: Adibou1 o2_gob0x0B");
-}
-
-void Inter_v2::o2_gob1001(OpGobParams &params) {
-	_vm->_game->_script->skip(2);
-	warning("STUB: Adibou1 o2_gob1001");
-}
-
 void Inter_v2::o2_startInfogrames(OpGobParams &params) {
 	_vm->_game->_script->readInt16();
 
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 5d6ee08bc3d..2cef76c3ca9 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -44,6 +44,7 @@ MODULE_OBJS := \
 	inter_v1.o \
 	inter_geisha.o \
 	inter_v2.o \
+	inter_adibou1.o \
 	inter_bargon.o \
 	inter_fascin.o \
 	inter_littlered.o \


Commit: f5f5da58bade6b4ada3137a92862b6215ebb3839
    https://github.com/scummvm/scummvm/commit/f5f5da58bade6b4ada3137a92862b6215ebb3839
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: fix the "fill" tool in Adibou1 paint game

Changed paths:
    engines/gob/inter.h
    engines/gob/inter_adibou1.cpp


diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index c062911aeae..7caf17fc531 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -540,6 +540,7 @@ protected:
 	void setupOpcodesFunc() override;
 	void setupOpcodesGob() override;
 
+	void oAdibou1_fillAreaAtPoint(OpGobParams &params);
 	void oAdibou1_getAppliNameFromId(OpGobParams &params);
 	void oAdibou1_listApplications(OpGobParams &params);
 };
diff --git a/engines/gob/inter_adibou1.cpp b/engines/gob/inter_adibou1.cpp
index ffe9725803d..9f1f38dbf76 100644
--- a/engines/gob/inter_adibou1.cpp
+++ b/engines/gob/inter_adibou1.cpp
@@ -45,10 +45,31 @@ void Inter_Adibou1::setupOpcodesFunc() {
 }
 
 void Inter_Adibou1::setupOpcodesGob() {
+	OPCODEGOB(2, oAdibou1_fillAreaAtPoint);
 	OPCODEGOB(10, oAdibou1_getAppliNameFromId);
 	OPCODEGOB(11, oAdibou1_listApplications);
 }
 
+void Inter_Adibou1::oAdibou1_fillAreaAtPoint(OpGobParams &params) {
+	uint16 varX = _vm->_game->_script->readUint16();
+	uint16 varY = _vm->_game->_script->readUint16();
+	uint16 varSpriteIndex = _vm->_game->_script->readUint16();
+	uint16 varColor = _vm->_game->_script->readUint16();
+
+	int16 x = VAR(varX);
+	int16 y = VAR(varY);
+	int16 spriteIndex = VAR(varSpriteIndex);
+	int16 color = VAR(varColor);
+
+	SurfacePtr destSprite = _vm->_draw->_spritesArray[spriteIndex];
+	if (!destSprite) {
+		warning("oAdibou1_fillAreaAtPoint(): Sprite %d does not exist", spriteIndex);
+		return;
+	}
+
+	destSprite->fillAreaAtPoint(x, y, color);
+}
+
 void Inter_Adibou1::oAdibou1_getAppliNameFromId(OpGobParams &params) {
 	uint16 resultAppliNameVarOffset = 4 * _vm->_game->_script->readUint16();
 	uint16 wantedAppliIdVar = _vm->_game->_script->readUint16();


Commit: 82ed59a1504778ecff7177d0a0cfcebae5b167e7
    https://github.com/scummvm/scummvm/commit/82ed59a1504778ecff7177d0a0cfcebae5b167e7
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: skipping copy protection of Adibou1 applications

Changed paths:
    engines/gob/inter_v1.cpp


diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 63066c67468..c5a11362814 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -848,7 +848,31 @@ void Inter_v1::o1_if(OpFuncParams &params) {
 		WRITE_VAR(285, 0);
 	}
 
+	int pos = _vm->_game->_script->pos();
 	boolRes = _vm->_game->_script->evalBool();
+
+	// Skipping copy protection screen of Adibou 1 applications
+	if (!_vm->_copyProtection &&
+		_vm->getGameType() == kGameTypeAdibou1 &&
+		(pos == 162 ||
+		 pos == 165 ||
+		 pos == 170 ||
+		 pos == 173 ||
+		 pos == 167 ||
+		 pos == 182 ||
+		 pos == 185 ||
+		 pos == 188) &&
+		(_vm->isCurrentTot("C51INTRO.tot") ||
+		 _vm->isCurrentTot("C61INTRO.tot") ||
+		 _vm->isCurrentTot("L51INTRO.tot") ||
+		 _vm->isCurrentTot("L61INTRO.tot"))) {
+		if (pos == 162 || pos == 165 || pos == 170 || pos == 173)
+			boolRes = false; // First, bypass the copy protection screen
+		else
+			boolRes = true; // Then bypass the check of the copy protection test result
+		debugC(2, kDebugGameFlow, "Skipping copy protection screen");
+	}
+
 	if (boolRes) {
 		if ((params.counter == params.cmdCount) && (params.retFlag == 2)) {
 			params.doReturn = true;


Commit: de53ff1caefc5c949b9470bf3ef5277d6348167e
    https://github.com/scummvm/scummvm/commit/de53ff1caefc5c949b9470bf3ef5277d6348167e
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: save application progress in Adibou1

Everything seems to be saved in "bou.inf"

Changed paths:
    engines/gob/save/saveload.h
    engines/gob/save/saveload_adibou1.cpp


diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index 5c960b088c8..0d50f15eba2 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -305,9 +305,32 @@ protected:
 		const char *description;
 	};
 
+	class GameFileHandler : public SaveHandler {
+	public:
+		GameFileHandler(GobEngine *vm, const Common::String &target, const Common::String &ext);
+		~GameFileHandler() override;
+
+		int32 getSize() override;
+		bool load(int16 dataVar, int32 size, int32 offset) override;
+		bool save(int16 dataVar, int32 size, int32 offset) override;
+		bool deleteFile() override;
+
+	private:
+		// Save from raw pointer if ptrRaw != nullptr, else save from game variables
+		bool save(const byte *ptrRaw, int16 dataVar, int32 size, int32 offset);
+
+		class File : public SlotFileStatic {
+		public:
+			File(GobEngine *vm, const Common::String &base, const Common::String &ext);
+			~File() override;
+		};
+
+		File _file;
+	};
+
 	static SaveFile _saveFiles[];
 
-	FakeFileHandler *_bouHandler;
+	GameFileHandler *_bouHandler;
 
 	SaveHandler *getHandler(const char *fileName) const override;
 	const char *getDescription(const char *fileName) const override;
diff --git a/engines/gob/save/saveload_adibou1.cpp b/engines/gob/save/saveload_adibou1.cpp
index a255b89ea6e..fdd3642cc08 100644
--- a/engines/gob/save/saveload_adibou1.cpp
+++ b/engines/gob/save/saveload_adibou1.cpp
@@ -33,13 +33,151 @@ SaveLoad_Adibou1::SaveFile SaveLoad_Adibou1::_saveFiles[] = {
 SaveLoad_Adibou1::SaveLoad_Adibou1(GobEngine *vm, const char *targetName) :
 	SaveLoad(vm) {
 
-	_saveFiles[0].handler = _bouHandler = new FakeFileHandler(vm);
+	_saveFiles[0].handler = _bouHandler = new GameFileHandler(vm, targetName, "bouinf");
 }
 
 SaveLoad_Adibou1::~SaveLoad_Adibou1() {
 	delete _bouHandler;
 }
 
+SaveLoad_Adibou1::GameFileHandler::File::File(GobEngine *vm, const Common::String &base, const Common::String &ext) :
+	SlotFileStatic(vm, base, ext) {
+}
+
+SaveLoad_Adibou1::GameFileHandler::File::~File() {
+}
+
+
+SaveLoad_Adibou1::GameFileHandler::GameFileHandler(GobEngine *vm, const Common::String &target, const Common::String &ext) :
+	SaveHandler(vm), _file(vm, target, ext) {
+}
+
+SaveLoad_Adibou1::GameFileHandler::~GameFileHandler() {
+}
+
+int32 SaveLoad_Adibou1::GameFileHandler::getSize() {
+	Common::String fileName = _file.build();
+	if (fileName.empty())
+		return -1;
+
+	SaveReader reader(1, 0, fileName);
+	SaveHeader header;
+
+	if (!reader.load())
+		return -1;
+
+	if (!reader.readPartHeader(0, &header))
+		return -1;
+
+	// Return the part's size
+	return header.getSize();
+}
+
+bool SaveLoad_Adibou1::GameFileHandler::load(int16 dataVar, int32 size, int32 offset) {
+	Common::String fileName = _file.build();
+	if (fileName.empty())
+		return false;
+
+	if (size == 0) {
+		uint32 varSize = SaveHandler::getVarSize(_vm);
+		// Indicator to load all variables
+		dataVar = 0;
+		size = (int32) varSize;
+	}
+
+	int32 fileSize = getSize();
+	if (fileSize < 0)
+		return false;
+
+	SaveReader reader(1, 0, fileName);
+	SavePartVars vars(_vm, fileSize);
+
+	if (!reader.load()) {
+		return false;
+	}
+
+	if (!reader.readPart(0, &vars)) {
+		return false;
+	}
+
+	if (!vars.writeInto((uint16) dataVar, offset, size)) {
+		return false;
+	}
+
+	return true;
+}
+
+bool SaveLoad_Adibou1::GameFileHandler::save(const byte *ptrRaw, int16 dataVar, int32 size, int32 offset) {
+	Common::String fileName = _file.build();
+	if (fileName.empty())
+		return false;
+
+	if (size == 0) {
+		// Indicator to save all variables
+		dataVar = 0;
+		uint32 varSize = SaveHandler::getVarSize(_vm);
+		size = (int32) varSize;
+	}
+
+	int32 fileSize = getSize();
+	int32 newFileSize = size;
+	if (fileSize > 0) {
+		newFileSize = MAX<int32>(fileSize, size + offset);
+	}
+
+	SavePartVars vars(_vm, newFileSize);
+	if (fileSize > 0
+		&&
+		(offset > 0 || size < fileSize)) {
+		// Load data from file, as some of it will not be overwritten
+		SaveReader reader(1, 0, fileName);
+		if (!reader.load()) {
+			return false;
+		}
+
+		if (fileSize == newFileSize) {
+			// We can use the same SavePartVars object
+			if (!reader.readPart(0, &vars)) {
+				return false;
+			}
+		} else {
+			// We need to use a temporary SavePartVars object to load data
+			SavePartVars vars_from_file(_vm, fileSize);
+			if (!reader.readPart(0, &vars_from_file)) {;
+				return false;
+			}
+
+			// Copy data from temporary SavePartVars object to the real one
+			vars.readFromRaw(vars_from_file.data(), 0, fileSize);
+		}
+	}
+
+	SaveWriter writer(1, 0, fileName);
+	if (ptrRaw) {
+		// Write data from raw pointer
+		vars.readFromRaw(ptrRaw, offset, size);
+	} else {
+		// Write data from variables
+		if (!vars.readFrom((uint16) dataVar, offset, size))
+			return false;
+	}
+
+	return writer.writePart(0, &vars);
+}
+
+bool SaveLoad_Adibou1::GameFileHandler::save(int16 dataVar, int32 size, int32 offset) {
+	return save(nullptr, dataVar, size, offset);
+}
+
+bool SaveLoad_Adibou1::GameFileHandler::deleteFile() {
+	Common::String fileName = _file.build();
+	if (fileName.empty())
+		return false;
+
+	SaveWriter writer(1, 0, fileName);
+	return writer.deleteFile();
+}
+
 const SaveLoad_Adibou1::SaveFile *SaveLoad_Adibou1::getSaveFile(const char *fileName) const {
 	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
 		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))


Commit: bda696d019362c2ae63ca32bb0049501799cfa03
    https://github.com/scummvm/scummvm/commit/bda696d019362c2ae63ca32bb0049501799cfa03
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: workaround for some Adibou1 versions triggering the "quit" action instead of the chosen Read/Count app

Changed paths:
    engines/gob/inter_v2.cpp


diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 29b51801956..4d206597058 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -1462,7 +1462,13 @@ void Inter_v2::o2_checkData(OpFuncParams &params) {
 	debugC(2, kDebugFileIO, "Requested size of file \"%s\": %d", file.c_str(), size);
 
 	WRITE_VAR_OFFSET(varOff, (size == -1) ? -1 : 50);
-	WRITE_VAR(16, (uint32) size);
+	// WORKAROUND: the "current hotspot" variable (also VAR(16)) is sometimes corrupted here before being read.
+	// We skip writing the file size into VAR(16) here as a workaround (the value is not used anyway).
+	// In some versions of Adibou 1, this sometimes triggers the "quit" action instead of starting
+	// a chosen Read/Count application.
+	// Note: a similar issue has been found in Adibou 2, see o7_checkData().
+	if (_vm->getGameType() != kGameTypeAdibou1  || !_vm->isCurrentTot("KID.TOT"))
+		WRITE_VAR(16, (uint32) size);
 }
 
 void Inter_v2::o2_readData(OpFuncParams &params) {


Commit: f57d2b189c3719d3d5fcd345a6298050b2bfa3bb
    https://github.com/scummvm/scummvm/commit/f57d2b189c3719d3d5fcd345a6298050b2bfa3bb
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: save/load drawings for "Paint" game in Adibou1

Changed paths:
    engines/gob/inter.h
    engines/gob/inter_adibou1.cpp
    engines/gob/save/saveload.h
    engines/gob/save/saveload_adibou1.cpp


diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 7caf17fc531..b0933667caa 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -540,6 +540,8 @@ protected:
 	void setupOpcodesFunc() override;
 	void setupOpcodesGob() override;
 
+	void oAdibou1_writeSprite(OpGobParams &params);
+	void oAdibou1_readSprite(OpGobParams &params);
 	void oAdibou1_fillAreaAtPoint(OpGobParams &params);
 	void oAdibou1_getAppliNameFromId(OpGobParams &params);
 	void oAdibou1_listApplications(OpGobParams &params);
diff --git a/engines/gob/inter_adibou1.cpp b/engines/gob/inter_adibou1.cpp
index 9f1f38dbf76..c297592590b 100644
--- a/engines/gob/inter_adibou1.cpp
+++ b/engines/gob/inter_adibou1.cpp
@@ -24,6 +24,7 @@
 #include "gob/inter.h"
 #include "gob/game.h"
 #include "gob/script.h"
+#include "gob/save/saveload.h"
 
 
 namespace Gob {
@@ -45,11 +46,54 @@ void Inter_Adibou1::setupOpcodesFunc() {
 }
 
 void Inter_Adibou1::setupOpcodesGob() {
+	OPCODEGOB(0, oAdibou1_writeSprite);
+	OPCODEGOB(1, oAdibou1_readSprite);
 	OPCODEGOB(2, oAdibou1_fillAreaAtPoint);
 	OPCODEGOB(10, oAdibou1_getAppliNameFromId);
 	OPCODEGOB(11, oAdibou1_listApplications);
 }
 
+void Inter_Adibou1::oAdibou1_writeSprite(OpGobParams &params) {
+	int16 spriteIndex = _vm->_game->_script->readInt16();
+	uint16 varResult = _vm->_game->_script->readUint16();
+	uint16 varFileName = _vm->_game->_script->readUint16();
+
+	WRITE_VAR(varResult, 0);
+
+	const char *filename = GET_VAR_STR(varFileName);
+
+	SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(filename) : SaveLoad::kSaveModeNone;
+	if (mode == SaveLoad::kSaveModeSave) {
+		if (_vm->_saveLoad->save(filename, 0, -spriteIndex - 1, 0)) {
+			WRITE_VAR(varResult, 1);
+		}
+	} else if (mode == SaveLoad::kSaveModeIgnore)
+		return;
+	else if (mode == SaveLoad::kSaveModeNone)
+		warning("Attempted to write to file \"%s\"", filename);
+}
+
+void Inter_Adibou1::oAdibou1_readSprite(OpGobParams &params) {
+	int16 spriteIndex = _vm->_game->_script->readInt16();
+	uint16 varResult = _vm->_game->_script->readUint16();
+	uint16 varFileName = _vm->_game->_script->readUint16();
+
+	WRITE_VAR(varResult, 0);
+
+	const char *filename = GET_VAR_STR(varFileName);
+
+	SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(filename) : SaveLoad::kSaveModeNone;
+	if (mode == SaveLoad::kSaveModeSave) {
+		if (_vm->_saveLoad->load(filename, 0, -spriteIndex - 1, 0)) {
+			WRITE_VAR(varResult, 1);
+		}
+	} else if (mode == SaveLoad::kSaveModeIgnore)
+		return;
+	else if (mode == SaveLoad::kSaveModeNone)
+		warning("Attempted to write to file \"%s\"", filename);
+}
+
+
 void Inter_Adibou1::oAdibou1_fillAreaAtPoint(OpGobParams &params) {
 	uint16 varX = _vm->_game->_script->readUint16();
 	uint16 varY = _vm->_game->_script->readUint16();
diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index 0d50f15eba2..2142f1db477 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -305,6 +305,25 @@ protected:
 		const char *description;
 	};
 
+	class SpriteHandler : public TempSpriteHandler {
+	public:
+		SpriteHandler(GobEngine *vm, const Common::String &target, const Common::String &ext);
+		~SpriteHandler() override;
+
+		int32 getSize() override;
+		bool load(int16 dataVar, int32 size, int32 offset) override;
+		bool save(int16 dataVar, int32 size, int32 offset) override;
+
+	private:
+		class File : public SlotFileStatic {
+		public:
+			File(GobEngine *vm, const Common::String &base, const Common::String &ext);
+			~File() override;
+		};
+
+		File _file;
+	};
+
 	class GameFileHandler : public SaveHandler {
 	public:
 		GameFileHandler(GobEngine *vm, const Common::String &target, const Common::String &ext);
@@ -331,6 +350,7 @@ protected:
 	static SaveFile _saveFiles[];
 
 	GameFileHandler *_bouHandler;
+	SpriteHandler   *_drawingHandler;
 
 	SaveHandler *getHandler(const char *fileName) const override;
 	const char *getDescription(const char *fileName) const override;
diff --git a/engines/gob/save/saveload_adibou1.cpp b/engines/gob/save/saveload_adibou1.cpp
index fdd3642cc08..50a0c323d6e 100644
--- a/engines/gob/save/saveload_adibou1.cpp
+++ b/engines/gob/save/saveload_adibou1.cpp
@@ -28,18 +28,83 @@ namespace Gob {
 
 SaveLoad_Adibou1::SaveFile SaveLoad_Adibou1::_saveFiles[] = {
 	{ "bou.inf", kSaveModeSave, nullptr, "adibou1"},
+	{ "dessin.inf", kSaveModeSave, nullptr, "paint game drawing"},
 };
 
 SaveLoad_Adibou1::SaveLoad_Adibou1(GobEngine *vm, const char *targetName) :
 	SaveLoad(vm) {
 
 	_saveFiles[0].handler = _bouHandler = new GameFileHandler(vm, targetName, "bouinf");
+	_saveFiles[1].handler = _drawingHandler = new SpriteHandler(vm, targetName, "drawing");
 }
 
 SaveLoad_Adibou1::~SaveLoad_Adibou1() {
 	delete _bouHandler;
 }
 
+SaveLoad_Adibou1::SpriteHandler::File::File(GobEngine *vm, const Common::String &base, const Common::String &ext) :
+	SlotFileStatic(vm, base, ext) {
+}
+
+SaveLoad_Adibou1::SpriteHandler::File::~File() {
+}
+
+SaveLoad_Adibou1::SpriteHandler::SpriteHandler(GobEngine *vm, const Common::String &target, const Common::String &ext)
+	: TempSpriteHandler(vm), _file(vm, target, ext) {
+}
+
+SaveLoad_Adibou1::SpriteHandler::~SpriteHandler() {
+}
+
+int32 SaveLoad_Adibou1::SpriteHandler::getSize() {
+	Common::String fileName = _file.build();
+
+	if (fileName.empty())
+		return -1;;
+
+	SaveReader reader(1, 0, fileName);
+	SaveHeader header;
+
+	if (!reader.load())
+		return -1;
+
+	if (!reader.readPartHeader(0, &header))
+		return -1;
+
+	// Return the part's size
+	return header.getSize();
+}
+
+bool SaveLoad_Adibou1::SpriteHandler::load(int16 dataVar, int32 size, int32 offset) {
+	if (!TempSpriteHandler::createFromSprite(dataVar, size, offset))
+		return false;
+
+	Common::String fileName = _file.build();
+	if (fileName.empty())
+		return false;
+
+	SaveReader reader(1, 0, fileName);
+	if (!reader.load())
+		return false;
+
+	if (!reader.readPart(0, _sprite))
+		return false;
+
+	return TempSpriteHandler::load(dataVar, size, offset);
+}
+
+bool SaveLoad_Adibou1::SpriteHandler::save(int16 dataVar, int32 size, int32 offset) {
+	if (!TempSpriteHandler::save(dataVar, size, offset))
+		return false;
+
+	Common::String fileName = _file.build();
+	if (fileName.empty())
+		return false;
+
+	SaveWriter writer(1, 0, fileName);
+	return writer.writePart(0, _sprite);
+}
+
 SaveLoad_Adibou1::GameFileHandler::File::File(GobEngine *vm, const Common::String &base, const Common::String &ext) :
 	SlotFileStatic(vm, base, ext) {
 }


Commit: 9fa5a3061246e84ed67c3f24b3fb4f002e14acc3
    https://github.com/scummvm/scummvm/commit/9fa5a3061246e84ed67c3f24b3fb4f002e14acc3
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: save/load scenes in Adibou1 construction game

Changed paths:
    engines/gob/save/saveload.h
    engines/gob/save/saveload_adibou1.cpp


diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index 2142f1db477..206b54bb50c 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -350,6 +350,7 @@ protected:
 	static SaveFile _saveFiles[];
 
 	GameFileHandler *_bouHandler;
+	GameFileHandler *_constructionHandler;
 	SpriteHandler   *_drawingHandler;
 
 	SaveHandler *getHandler(const char *fileName) const override;
diff --git a/engines/gob/save/saveload_adibou1.cpp b/engines/gob/save/saveload_adibou1.cpp
index 50a0c323d6e..6dec0361676 100644
--- a/engines/gob/save/saveload_adibou1.cpp
+++ b/engines/gob/save/saveload_adibou1.cpp
@@ -29,6 +29,7 @@ namespace Gob {
 SaveLoad_Adibou1::SaveFile SaveLoad_Adibou1::_saveFiles[] = {
 	{ "bou.inf", kSaveModeSave, nullptr, "adibou1"},
 	{ "dessin.inf", kSaveModeSave, nullptr, "paint game drawing"},
+	{ "const.inf", kSaveModeSave, nullptr, "construction game"},
 };
 
 SaveLoad_Adibou1::SaveLoad_Adibou1(GobEngine *vm, const char *targetName) :
@@ -36,6 +37,7 @@ SaveLoad_Adibou1::SaveLoad_Adibou1(GobEngine *vm, const char *targetName) :
 
 	_saveFiles[0].handler = _bouHandler = new GameFileHandler(vm, targetName, "bouinf");
 	_saveFiles[1].handler = _drawingHandler = new SpriteHandler(vm, targetName, "drawing");
+	_saveFiles[2].handler = _constructionHandler = new GameFileHandler(vm, targetName, "construction");
 }
 
 SaveLoad_Adibou1::~SaveLoad_Adibou1() {


Commit: ff60aed2691447f2826a496cda247863f11e11c4
    https://github.com/scummvm/scummvm/commit/ff60aed2691447f2826a496cda247863f11e11c4
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-05T23:29:11+02:00

Commit Message:
GOB: spriteOperation(0) is spriteOperation(DRAW_BLITSURF)

Changed paths:
    engines/gob/game.cpp
    engines/gob/inter_v2.cpp


diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index fe96cb098f4..4c265f04aee 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -688,7 +688,7 @@ void Game::capturePush(int16 left, int16 top, int16 width, int16 height) {
 	_vm->_draw->_destSpriteX = 0;
 	_vm->_draw->_destSpriteY = 0;
 	_vm->_draw->_transparency = 0;
-	_vm->_draw->spriteOperation(0);
+	_vm->_draw->spriteOperation(DRAW_BLITSURF);
 	_captureCount++;
 }
 
@@ -710,7 +710,7 @@ void Game::capturePop(char doDraw) {
 		_vm->_draw->_destSurface = Draw::kBackSurface;
 		_vm->_draw->_spriteLeft = _vm->_draw->_destSpriteX & 0xF;
 		_vm->_draw->_spriteTop = 0;
-		_vm->_draw->spriteOperation(0);
+		_vm->_draw->spriteOperation(DRAW_BLITSURF);
 	}
 	_vm->_draw->freeSprite(Draw::kCaptureSurface + _captureCount);
 }
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 4d206597058..33ef540f361 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -379,7 +379,7 @@ void Inter_v2::o2_initMult() {
 	_vm->_draw->_spriteBottom = _vm->_mult->_animHeight;
 	_vm->_draw->_destSpriteX = 0;
 	_vm->_draw->_destSpriteY = 0;
-	_vm->_draw->spriteOperation(0);
+	_vm->_draw->spriteOperation(DRAW_BLITSURF);
 
 	debugC(4, kDebugGraphics, "o2_initMult: x = %d, y = %d, w = %d, h = %d",
 		  _vm->_mult->_animLeft, _vm->_mult->_animTop,




More information about the Scummvm-git-logs mailing list