[Scummvm-git-logs] scummvm master -> 6f18184f669a42acb90e3770af749291d3501f9c

sdelamarre noreply at scummvm.org
Sat Oct 18 22:20:12 UTC 2025


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

Summary:
37a7d5d38b GOB: Fix a bug when adding Adi4 applications to the search path
b2814d51e3 GOB: Add some Adi4 application progress save files
f2e727339e GOB: Fix in o5_strlen, font index var may not always be uint16
3d4d103e8c GOB: Add Adi4 opcodes related to exercise results and score
0cb12fff71 GOB: Ignore attempts to to blit() from high-color to paletted surfaces
6f18184f66 GOB: Ignore attempts to create surface with a null dimension


Commit: 37a7d5d38b338cc270dc91bf94559e052d4972da
    https://github.com/scummvm/scummvm/commit/37a7d5d38b338cc270dc91bf94559e052d4972da
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-10-19T00:19:58+02:00

Commit Message:
GOB: Fix a bug when adding Adi4 applications to the search path

At mots one application was actually added

Changed paths:
    engines/gob/init_v7.cpp


diff --git a/engines/gob/init_v7.cpp b/engines/gob/init_v7.cpp
index c0a1a8510da..a26b99dfcd4 100644
--- a/engines/gob/init_v7.cpp
+++ b/engines/gob/init_v7.cpp
@@ -63,18 +63,13 @@ void Init_v7::initGame() {
 			// Look for any "DESC*.ADI" file
 			Common::FSList fileNodes;
 			subdirNode.getChildren(fileNodes, Common::FSNode::kListFilesOnly);
-			bool foundDescFile = false;
 			for (const Common::FSNode &fileNode : fileNodes) {
 				if (fileNode.getName().hasPrefixIgnoreCase("DESC") && fileNode.getName().hasSuffixIgnoreCase(".ADI")) {
 					debugC(1, kDebugFileIO, "Found Adi 4 application subdirectory \"%s\", adding it to the search path", subdir.getFSNode().getName().c_str());
 					SearchMan.addSubDirectoryMatching(gameDataDir, subdir.getFSNode().getName(), 0, 4, true);
-					foundDescFile = true;
 					break;
 				}
 			}
-
-			if (foundDescFile)
-				break;
 		}
 	}
 


Commit: b2814d51e35144b33a53a6a0868d6877eac826c5
    https://github.com/scummvm/scummvm/commit/b2814d51e35144b33a53a6a0868d6877eac826c5
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-10-19T00:19:58+02:00

Commit Message:
GOB: Add some Adi4 application progress save files

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


diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index d1c6b836f54..c4e450c8488 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -983,7 +983,10 @@ public:
 	static const uint32 kAdibou2NbrOfConstructionGameFiles = 3;
 
 	static const uint32 kAdi4NbrOfTempFiles = 9;
-	static const uint32 kAdi4NbrOfGameFiles = 36;
+	static const uint32 kAdi4NbrOfApplications = 2; // Only Math/Language for now
+	static const uint32 kAdi4NbrOfSchoolYears = 8;
+	// 4 isolated files, 1 "config" and "statv" file per child, 1 "dip" and "res" file per app x school year x child
+	static const uint32 kAdi4NbrOfGameFiles = 4 + 2 * kChildrenCount + 2 * kAdi4NbrOfApplications * kAdi4NbrOfSchoolYears * kChildrenCount;
 
 	SaveLoad_v7(GobEngine *vm, const char *targetName);
 	~SaveLoad_v7() override;
diff --git a/engines/gob/save/saveload_v7.cpp b/engines/gob/save/saveload_v7.cpp
index fc1d69156a2..dfa11eef9e8 100644
--- a/engines/gob/save/saveload_v7.cpp
+++ b/engines/gob/save/saveload_v7.cpp
@@ -989,6 +989,589 @@ SaveLoad_v7::SaveFile SaveLoad_v7::_saveFiles[] = {
 	{"DATA/statev14.inf", kSaveModeSave, nullptr, nullptr},
 	{"DATA/statev15.inf", kSaveModeSave, nullptr, nullptr},
 
+	// App progress files (one per child per year and per app)
+
+	// Maths
+	// 7-8 years
+	{"DATA/RESM1100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM1115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 8-9 years
+	{"DATA/RESM9100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM9115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 9-10 years
+	{"DATA/RESM8100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM8115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 10-11 years
+	{"DATA/RESM7100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM7115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 11-12 years
+	{"DATA/RESM6100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM6115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 12-13 years
+	{"DATA/RESM5100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM5115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 13-14 years
+	{"DATA/RESM4100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM4115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 14-15 years
+	{"DATA/RESM3100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESM3115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// Language
+	// 7-8 years
+	{"DATA/RESF1100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF1115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 8-9 years
+	{"DATA/RESF9100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF9115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 9-10 years
+	{"DATA/RESF8100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF8115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 10-11 years
+	{"DATA/RESF7100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF7115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 11-12 years
+	{"DATA/RESF6100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF6115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 12-13 years
+	{"DATA/RESF5100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF5115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 13-14 years
+	{"DATA/RESF4100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF4115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 14-15 years
+	{"DATA/RESF3100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/RESF3115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// DIP files (one per child per year and per app)
+
+	// Maths
+	// 7-8 years
+	{"DATA/DIPM1100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM1115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 8-9 years
+	{"DATA/DIPM9100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM9115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 9-10 years
+	{"DATA/DIPM8100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM8115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 10-11 years
+	{"DATA/DIPM7100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM7115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 11-12 years
+	{"DATA/DIPM6100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM6115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 12-13 years
+	{"DATA/DIPM5100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM5115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 13-14 years
+	{"DATA/DIPM4100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM4115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 14-15 years
+	{"DATA/DIPM3100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPM3115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// Language
+	// 7-8 years
+	{"DATA/DIPF1100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF1115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 8-9 years
+	{"DATA/DIPF9100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF9115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 9-10 years
+	{"DATA/DIPF8100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF8115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 10-11 years
+	{"DATA/DIPF7100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF7115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 11-12 years
+	{"DATA/DIPF6100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF6115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 12-13 years
+	{"DATA/DIPF5100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF5115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 13-14 years
+	{"DATA/DIPF4100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF4115.inf", kSaveModeSave, nullptr, nullptr},
+
+	// 14-15 years
+	{"DATA/DIPF3100.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3101.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3102.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3103.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3104.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3105.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3106.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3107.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3108.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3109.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3110.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3111.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3112.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3113.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3114.inf", kSaveModeSave, nullptr, nullptr},
+	{"DATA/DIPF3115.inf", kSaveModeSave, nullptr, nullptr},
 };
 
 SaveLoad_v7::SpriteHandler::File::File(GobEngine *vm, const Common::String &base, const Common::String &ext) :
@@ -1546,6 +2129,18 @@ SaveLoad_v7::SaveLoad_v7(GobEngine *vm, const char *targetName) :
 																								  targetName,
 																								  Common::String::format("statev%02d", i));
 	}
+
+	for (const char* fileType : {"res", "dip"}) {
+		for (uint32 i = 0; i < kAdi4NbrOfApplications; i++) {
+			for (uint32 j = 0; j < kAdi4NbrOfSchoolYears; j++) {
+				for (uint32 k = 0; k < kChildrenCount; k++) {
+					_saveFiles[index++].handler = _adi4GameFileHandler[indexAdi4file++] = new GameFileHandler(_vm,
+																											  targetName,
+																											  Common::String::format("%s_%02d_%02d_%02d", fileType, i, j, k));
+				}
+			}
+		}
+	}
 }
 
 SaveLoad_v7::~SaveLoad_v7() {


Commit: f2e727339e3a58cf7e7f1b44cbb8bdaf29cbe43d
    https://github.com/scummvm/scummvm/commit/f2e727339e3a58cf7e7f1b44cbb8bdaf29cbe43d
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-10-19T00:19:58+02:00

Commit Message:
GOB: Fix in o5_strlen, font index var may not always be uint16

Changed paths:
    engines/gob/inter_v5.cpp


diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp
index 81fccc01fcf..f1b5ae33fa2 100644
--- a/engines/gob/inter_v5.cpp
+++ b/engines/gob/inter_v5.cpp
@@ -230,7 +230,8 @@ void Inter_v5::o5_istrlen(OpFuncParams &params) {
 		strVar1 = _vm->_game->_script->readVarIndex();
 		strVar2 = _vm->_game->_script->readVarIndex(nullptr, &type);
 
-		len = _vm->_draw->stringLength(GET_VARO_STR(strVar1), READ_VARO_UINT16(strVar2));
+		uint32 fontIndex = readValue(strVar2, type);
+		len = _vm->_draw->stringLength(GET_VARO_STR(strVar1), (uint16)fontIndex);
 
 	} else {
 


Commit: 3d4d103e8c74e77ab9fefdcf6a72b1bbabba4695
    https://github.com/scummvm/scummvm/commit/3d4d103e8c74e77ab9fefdcf6a72b1bbabba4695
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-10-19T00:19:58+02:00

Commit Message:
GOB: Add Adi4 opcodes related to exercise results and score

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


diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index d0ec3860759..5bfdd82167c 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -796,9 +796,11 @@ protected:
 									const Common::Array<byte> &appChildData,
 									uint32 childNbr, uint32 appliNbr);
 
+	void o7_saveAdi4ExerciseAttemptsCount(OpGobParams &params);
+	void o7_saveAdi4ExerciseResults(OpGobParams &params);
 	void o7_writeUnknownChildDataToGameVariables(OpGobParams &params);
 	void o7_writeUnknownAppChildDataToGameVariables(OpGobParams &params);
-	void o7_writeUnknownChildUint16ToGameVariables(OpGobParams &params);
+	void o7_writeChildScoreToGameVariables(OpGobParams &params);
 
 	void o7_startAdi4Application(OpGobParams &params);
 
@@ -818,7 +820,8 @@ private:
 
 	uint32 _adi4CurrentAppNbr = 0;
 	uint32 _adi4CurrentChildNbr = 0;
-	uint32 _adi4CurrentSectionInAppChildData = 0; // 0, 1, or 2
+	uint32 _adi4CurrentSectionInGeneralChildData = 0;
+	uint32 _adi4CurrentSectionInAppChildData = 0;
 	Common::Array<byte> _adi4GeneralChildData;
 	Common::Array<byte> _adi4CurrentAppChildData;
 
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp
index 76f8119ffd1..4759ac2ed6c 100644
--- a/engines/gob/inter_v7.cpp
+++ b/engines/gob/inter_v7.cpp
@@ -150,9 +150,12 @@ void Inter_v7::setupOpcodesFunc() {
 }
 
 void Inter_v7::setupOpcodesGob() {
+	OPCODEGOB(0, o7_saveAdi4ExerciseAttemptsCount);
+	OPCODEGOB(1, o7_saveAdi4ExerciseResults);
+
 	OPCODEGOB(55, o7_writeUnknownChildDataToGameVariables);
 	OPCODEGOB(64, o7_writeUnknownAppChildDataToGameVariables);
-	OPCODEGOB(74, o7_writeUnknownChildUint16ToGameVariables);
+	OPCODEGOB(74, o7_writeChildScoreToGameVariables);
 
 	OPCODEGOB(406, o7_startAdi4Application);
 	OPCODEGOB(407, o7_xorDeobfuscate);
@@ -2052,8 +2055,11 @@ bool Inter_v7::writeAdi4InstalledAppsData(const Common::Array<byte> &generalChil
 										 const Common::Array<byte> &appChildData,
 										 uint32 childNbr,
 										 uint32 appliNbr) {
+	if (generalChildData.empty())
+		return false;
+
 	if (!writeAdi4InfDataForChild(generalChildData, childNbr, 0, kAdi4InfGeneralChildDataSize)) {
-		warning("wrAdi4InstalledAppsData: Failed to write general data for child %d in ADI.INF", childNbr);
+		warning("writeAdi4InstalledAppsData: Failed to write general data for child %d in ADI.INF", childNbr);
 		return false;
 	}
 
@@ -2064,17 +2070,94 @@ bool Inter_v7::writeAdi4InstalledAppsData(const Common::Array<byte> &generalChil
 								((appChildData[i + 2 * kAdi4InfAppChildDataSize] & 3) << 4);
 	}
 
-	if (!readAdi4InfDataForChild(appChildDataPacked,
-								 childNbr,
-								 kAdi4InfGeneralChildDataSize + appliNbr * kAdi4InfAppChildDataSize,
-								 kAdi4InfAppChildDataSize)) {
+	if (!writeAdi4InfDataForChild(appChildDataPacked,
+								  childNbr,
+								  kAdi4InfGeneralChildDataSize + appliNbr * kAdi4InfAppChildDataSize,
+								  kAdi4InfAppChildDataSize)) {
 		warning("readAdi4InstalledAppsData: Failed to write app-specific data for child %d in ADI.INF", childNbr);
 		return false;
-								 }
+	}
 
 	return true;
 }
 
+void Inter_v7::o7_saveAdi4ExerciseAttemptsCount(OpGobParams &params) {
+	_vm->_game->_script->skip(2);
+	uint16 sectionNumberVar = _vm->_game->_script->readUint16();
+	_vm->_game->_script->skip(2);
+
+	if (_adi4GeneralChildData.empty())
+		return;
+
+	uint16 sectionNumber = READ_VAR_UINT16(sectionNumberVar);
+	if (sectionNumber & 0x80) {
+		_adi4CurrentSectionInGeneralChildData = 0;
+		_adi4CurrentSectionInAppChildData = sectionNumber;
+		return;
+	}
+
+	if (sectionNumber & 0x100) {
+		_adi4CurrentSectionInGeneralChildData = 0;
+		_adi4CurrentSectionInAppChildData = 0;
+		return;
+	}
+
+	_adi4CurrentSectionInGeneralChildData = sectionNumber - 1;
+	if (_adi4CurrentSectionInAppChildData != 0)
+		_adi4CurrentSectionInGeneralChildData = _adi4CurrentSectionInAppChildData & 3;
+
+	uint16 unknownOffset = READ_LE_UINT16(&_adi4GeneralChildData[3]);
+	byte &totalAttemptsCount = _adi4GeneralChildData[2515 + _adi4CurrentAppNbr * 36 + unknownOffset * 3 + _adi4CurrentSectionInGeneralChildData];
+	if (totalAttemptsCount != 0xFF)
+		++totalAttemptsCount;
+}
+
+void Inter_v7::o7_saveAdi4ExerciseResults(OpGobParams &params) {
+	uint16 varIndexExerciseNumber = _vm->_game->_script->readUint16();
+	uint16 varIndexExerciseOutcome = _vm->_game->_script->readUint16();
+
+	if (_adi4GeneralChildData.empty())
+		return;
+
+	uint32 exerciseOutcome = VAR(varIndexExerciseOutcome);
+	if (exerciseOutcome < 10)
+		return; // Not completed
+
+	uint16 exerciseNumber = READ_VAR_UINT16(varIndexExerciseNumber);
+	byte &exerciseCompletionFlag = _adi4CurrentAppChildData[(_adi4CurrentSectionInAppChildData & 3) * 200 + exerciseNumber];
+	if (exerciseOutcome == 12) {
+		// Failed
+		if (exerciseCompletionFlag == 0)
+			exerciseCompletionFlag = 1; // Mark as attempted but not suceeded
+	} else {
+		// Succeeded
+		uint16 unknownOffset = READ_LE_UINT16(&_adi4GeneralChildData[3]);
+		if (exerciseCompletionFlag < 2) {
+			byte *currentScorePtr = &_adi4GeneralChildData[3241];
+			uint16 currentScore = READ_LE_UINT16(currentScorePtr);
+			if ((_adi4CurrentSectionInAppChildData & 80) == 0) {
+				WRITE_UINT16(currentScorePtr, currentScore + 2);
+			} else {
+				WRITE_UINT16(currentScorePtr, currentScore + 1);
+			}
+			byte &firstTimeSuccessCount = _adi4GeneralChildData[1075 + _adi4CurrentAppNbr * 36 + unknownOffset * 3 + _adi4CurrentSectionInGeneralChildData];
+			if (firstTimeSuccessCount != 0xFF)
+				++firstTimeSuccessCount;
+		} else {
+			byte &repeatSuccessCount = _adi4GeneralChildData[1795 + _adi4CurrentAppNbr * 36 + unknownOffset * 3 + _adi4CurrentSectionInGeneralChildData];
+			if (repeatSuccessCount != 0xFF)
+				++repeatSuccessCount;
+		}
+
+		exerciseCompletionFlag = 2;
+	}
+
+	writeAdi4InstalledAppsData(_adi4GeneralChildData,
+							   _adi4CurrentAppChildData,
+							   _adi4CurrentChildNbr,
+							   _adi4CurrentAppNbr);
+}
+
 void Inter_v7::o7_writeUnknownChildDataToGameVariables(OpGobParams &params) {
 	uint16 destVarIndex = _vm->_game->_script->readUint16();
 	_vm->_game->_script->skip(14);
@@ -2093,11 +2176,11 @@ void Inter_v7::o7_writeUnknownAppChildDataToGameVariables(OpGobParams &params) {
 
 	for (uint32 i = 0; i < kAdi4InfAppChildDataSize; ++i) {
 		WRITE_VARO_UINT8(destVarIndex * 4 + i,
-						_adi4CurrentAppChildData[i + _adi4CurrentSectionInAppChildData * kAdi4InfAppChildDataSize] & 3);
+						_adi4CurrentAppChildData[i + (_adi4CurrentSectionInAppChildData & 3) * kAdi4InfAppChildDataSize] & 3);
 	}
 }
 
-void Inter_v7::o7_writeUnknownChildUint16ToGameVariables(OpGobParams &params) {
+void Inter_v7::o7_writeChildScoreToGameVariables(OpGobParams &params) {
 	uint16 varIndex = _vm->_game->_script->readUint16();
 	if (_adi4GeneralChildData.empty())
 		return;


Commit: 0cb12fff71d24f732b0a54a24a0854e0a9ea12a3
    https://github.com/scummvm/scummvm/commit/0cb12fff71d24f732b0a54a24a0854e0a9ea12a3
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-10-19T00:19:58+02:00

Commit Message:
GOB: Ignore attempts to to blit() from high-color to paletted surfaces

This case happens in a few places because of script bugs, like in Adi4
"Atlas" activity, but should be just ignored.

Changed paths:
    engines/gob/surface.cpp


diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp
index e23a0113eac..53bfaa31bf1 100644
--- a/engines/gob/surface.cpp
+++ b/engines/gob/surface.cpp
@@ -367,6 +367,12 @@ uint32 Surface::getColorFromIndex(uint8 index) const {
 void Surface::blit(const Surface &from, int16 left, int16 top, int16 right, int16 bottom,
 		int16 x, int16 y, int32 transp, bool yAxisReflection) {
 
+	if (_bpp == 1 && from._bpp > 1) {
+		// Sometimes we run into this case because of script bugs. The attempt should be just ignord, no dithering is supposed to happen here.
+		warning("Error in Surface::blit(): trying to blit from a high-color source to a paletted destination");
+		return;
+	}
+
 	// Color depths have to fit
 	assert(_bpp == from._bpp || (from._bpp == 1 && from._highColorMap != nullptr));
 


Commit: 6f18184f669a42acb90e3770af749291d3501f9c
    https://github.com/scummvm/scummvm/commit/6f18184f669a42acb90e3770af749291d3501f9c
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-10-19T00:19:58+02:00

Commit Message:
GOB: Ignore attempts to create surface with a null dimension

This case happens in a few places  because of script bugs, like in Adi4
"Space exploration history" activity, but should be just ignored.

Changed paths:
    engines/gob/inter_v1.cpp


diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 0af78047815..0e6a54e71b7 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1605,6 +1605,11 @@ void Inter_v1::o1_createSprite(OpFuncParams &params) {
 	_vm->_draw->adjustCoords(0, &width, &height);
 	flag = _vm->_game->_script->readInt16();
 	byte bpp = (flag & 0x200) ? 1 : _vm->_pixelFormat.bytesPerPixel;
+	if (width == 0 || height == 0) {
+		warning("Error in o1_createSprite: invalid sprite dimensions (w = %d, h = %d)", width, height);
+		return;
+	}
+
 	_vm->_draw->initSpriteSurf(index, width, height, flag ? 2 : 0, bpp);
 }
 




More information about the Scummvm-git-logs mailing list