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

sev- noreply at scummvm.org
Fri Feb 20 18:09:29 UTC 2026


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

Summary:
2c2d72142b GAMOS: First working movie player
a2cc90780f GAMOS: Load data and process scripts
44c60ebae4 GAMOS: Fix memset() arguments
b1226329b9 GAMOS: Fix warning
578ef8b7ef GAMOS: Remove superfluous semicolon
700cc69a1b JANITORIAL: Remove trailing spaces
7c2ca07b73 GAMOS: Fix includes
944fd8bcb2 GAMOS: Replace array with only grow block-based simple container for draw elements to prevent use after free on resize o
9cecc28f6d GAMOS: VM improve
8b13a14829 GAMOS: Split object field
58754bceaa GAMOS: Small improvements
846c23a879 GAMOS: Fix mouse click handle object priority logic
8bf60ceb6b JANITORIAL: Remove trailing spaces
a9365bab14 GAMOS: printf -> warning
7debb8b363 GAMOS: Fix warnings
3af52c5670 GAMOS: Fix shadowed variable warnings
a778e76b64 GAMOS: Fix warning
6d8fec8520 GAMOS: Add vm call functions
629beeb7b0 GAMOS: Implement missing code
0cfb4ecb20 GAMOS: Fix load of first solgamer game
81bb5acf91 GAMOS: Add additional 4 header bytes for loading compressed images
a29a9f2779 GAMOS: Add play sounds
8773450d27 GAMOS: Various fixes
65ab2c12a2 GAMOS: Functions for debug purpose
b3aa23f580 JANITORIAL: Remove trailing whitespaces and added missing newlines and end-of-files
aed49c2e99 GAMOS: Fix includes
39be5925e2 GAMOS: Added missing game title
ee0db9646c JANITORIAL: Add missing copyright header
4121a3948b GAMOS: Fix bug
0fe94dcee1 GAMOS: Add games entries
bfdcf6a5b1 GAMOS: Make possible run few VM contexts
0affb7084f GAMOS: Disable and modify debug things
6cf5df6de9 GAMOS: Partially implement resources 0x60 and 0x61
51a705480f GAMOS: Change keycodes conversion
c49eda376b GAMOS: Implement loading of missing resource data into VM memory
e11e7cc513 GAMOS: Implement few callbacks and placholders
4a8f382029 GAMOS: Fix skipping
218e0fc5c4 GAMOS: rename thing1 to states and use array2D template
128dd6da37 GAMOS: rename grid size variables
665a53fcdf GAMOS: Path finding functions
779eb34a58 GAMOS: vm callback func 1
86b51afe05 GAMOS: Correctly load samples
e138582fc4 GAMOS: Implement blitter
d138814d47 GAMOS: fix blit
f6219afdaa GAMOS: little refactor
c689017a89 GAMOS: Fixes
6a16720a5f GAMOS: Fix wrong value passed to state array if flags has bit 1
20c8864c01 GAMOS: Add runfile and version fields into detection
d6a6956f91 GAMOS: Replace usage of g_system with _system
06cc8725a4 GAMOS: Set _rawKeyCode with ascii because it's set with WM_CHAR in original game
797ebc7edb GAMOS: Change few indentations in file.cpp
5d403fb3cc GAMOS: Implement usePalette method
54ff252d86 GAMOS: Rename BkgImage structure to GameScreen, improve, update it's functionality for swapping between game screens
6853d0c0da GAMOS: Make internal movie player use new implemented functions for use and restore palette and flush dirty rects
282aeac844 GAMOS: Update screen between frames for smooth mouse draw.
fad23b610e GAMOS: fix wrong detection of compressed images
682c97b313 GAMOS: Fix checkers screen update
a56561e4ed GAMOS: Implement save-load state files used for gameplay progress
3f695b6cd8 GAMOS: Because in of games one of ImageSeq can be referenced multiple times load it into just array of pointers and refe
ff7cee7ed4 GAMOS: Make Images and ImageSeq free on exit and on loading of a new "module"
1e06813100 GAMOS: Simplify logic of dirty region intersections check
c5951670eb GAMOS: Fix wrong usage of high 4 bits which represents ActEntry.t
3b7b264ec9 GAMOS: Fix crash in FUN_0040255c on null object
1bc20af9fe GAMOS: Blit object with 0x40 flag set as it's not apply x/y offsets
2023238aea GAMOS: Disable instruction logging for VM because seems it's stable
5d42472c81 GAMOS: Implement multiple VM callback functions used in games
fcc1ebaefc GAMOS: Fix warning
90755e69c0 GAMOS: printf -> warning
a761316413 GAMOS: Fix warnings
7b1a99f0c0 GAMOS: Replace fprintf() with proper Common::DumpFile usage
faad47a29d GAMOS: Eliminated exit() call useage
83817b935b JANITORIAL: Run astyle
ed9300c387 GAMOS: Removed superfluous semicolons
f1773b8d75 GAMOS: Fix not working skip of Pilots2 intro caused by dealigned read of keycodes
7146e5a7c4 GAMOS: Fix crash on attempt of create actions dump caused by empty path
ac78097f24 GAMOS: Implement update of mouse cursor
b37dc2f059 GAMOS: Rename _d2 fields identified as scroll parameters
ad4a8a7294 GAMOS: Rename _bkgUpdateSizes to _bkgSize
df7cf01c7b GAMOS: Implement screen scroll code
5eb4ad3699 GAMOS: Rework VM registers and address as working throught structure and methods. Store memtype in 2 high bits.
893a66e6d9 GAMOS: Add wildsnakes detection
239f4c1ddf GAMOS: Fix intro in wildsnakes
db182500c7 GAMOS: Smooth mouse in intro player and decrease cpu usage by idle for 1ms
4f0b4148d0 GAMOS: Disable movie player debug warnings
fa16fdc85b GAMOS: Fix mouse cursor palette
ca326dfea2 GAMOS: Implement key sequence check(vm func 13)
6a40704d7f GAMOS: Implement text input used in wildsnakes for score board
b4a6d43280 GAMOS: Update text output function to support score board draw in wildsnake
ec02914c1e GAMOS: Implement volume manipulation
4b41d8b586 GAMOS: Fix no music on replay of music (wildsnakes)
a38406da59 GAMOS: Update and implement missing path-finding code
b6fada6766 GAMOS: Play not only intro movies
52cb4bde5b GAMOS: Style and code improvements
87be9d5208 GAMOS: Implementation or stubs for almost all vm functions
66a24c1831 GAMOS: Add additional scripts into dumpfile
623cad8a53 GAMOS: Add flip-flop demo detection
992948abb5 GAMOS: Fix flip-flop demo crash on negative index
f5f8d0b9bb GAMOS: Implement missing function for flip-flop
2ef840759b GAMOS: Fix for incorrect generation in IT
aec2ef1275 GAMOS: Fix wrong assignment
08239376d9 GAMOS: Allow games to quit
3d0d7f7253 GAMOS: Add detections and set right languages.
40026e73e8 GAMOS: Silence debug warning
8f7876d906 GAMOS: Implement avi file playing
b58a124d3c GAMOS: Update fade in/out code with event update loop
d4d42b1c7d GAMOS: Fix video without bkg image
f32b7f1301 GAMOS: Implement stopSounds method
24cd181d99 GAMOS: Stop sounds on video play and resume midi
5692d57c28 GAMOS: Set video dithering if video not 8bit with palette (pilots 1 final avi)
c096938d66 GAMOS: Do not add empty key into seq
37eed70779 GAMOS: Silence debug message
b0c3d45545 GAMOS: Delete unused stack structure and add comments for undefined pointer
c71f4b8bc8 GAMOS: Fix incorrect blitting functions
2d0f9a19a6 GAMOS: Redo doDraw to original form of game engine
597e2fe214 GAMOS: Fix compilation
e8712f98be GAMOS: Give names for object flags
0ef434666e GAMOS: Move keycodes into engine class to eliminate global object
58d6c92358 GAMOS: Change of VM class for eliminating global objects
b40eb2cfc2 GAMOS: Fix compiler warnings
280bebc77b GAMOS: Disable unused field in file.h
6b366abfc3 GAMOS: Refactor object structure and split fields by their purpose
f49fed5af9 GAMOS: Rename FUN_00402654 to removeObjectAtCoords
bc1a40d693 GAMOS: Replace variables with Common::Point
4cbb3774bf GAMOS: Split field in ObjectAction
56f2a5d8fb GAMOS: Split states uint16 into structure
67b70b62db GAMOS: Implement internal save/load
224ed5b234 GAMOS: Set default scroll parameters on load
7fd6c2d095 GAMOS: Process for save only loaded screens
95d0af9e7b GAMOS: Remove unused commented variables and set missing _midiVolumeTarget in vm funcs
aad5ed6821 GAMOS: Remove unused save files xor key
3ee2c931a0 GAMOS: Inverse arguments in functions with reversed sequences
19063ff663 GAMOS: Give names for part of path finding methods and variables
4100b6ecd9 GAMOS: Rename input handling fields and methods
a5c329b888 GAMOS: Delete unused fields
0a5be01936 GAMOS: Rename many fields
245ae2ffb4 GAMOS: Give names for methods
0c99c33d5b GAMOS: remove unused code created by engine template
a0c3e99c30 GAMOS: give names for fields of Sprite and Unknown1 structures
8837689bd1 GAMOS: give names for resource types
04ecd4bd8c GAMOS: Use exe name as base for save file names
859a0a4858 GAMOS: Add conversion input into win1251 and win1252 codepages
7b32a31b16 GAMOS: Move const methods into header
0fa8028083 GAMOS: Rename GetScummCode->getScummCode and GetWinCode->getWinCode
ce4d262b97 GAMOS: Update detection table
f25233866b GAMOS: Add support loading games with engine version 0x12 and 0x0b
acf0a73511 GAMOS: Update detection table for 1C demo disc
6b9a0d84de GAMOS: Fix loading of engine version 16
ca45b3637d GAMOS: Specify size for size type in array2d template
9b34c8aa80 GAMOS: Delete potfile because it's not needed
82a8c82f78 GAMOS: Replace commented code with tip
bee7e09e8e GAMOS: Replace iteration counter with uint
b9f0f82544 GAMOS: Poll events on scroll routine
0c77ee736e GAMOS: Fix bracket style
686a47927c GAMOS: Sort objects in module.mk
36118e9406 GAMOS: Fill credits.pl
64e9752d9a GAMOS: Add comments with game engine copyright, year and if preserved file date
24b751dbae GAMOS: Set copyright dates
92515190b7 GAMOS: Fix "error C4701: potentially uninitialized local variable"
a10d43885a GAMOS: Fixes for "warning C4018: signed/unsigned mismatch"
4932aef24c GAMOS: Remove unused console for now
51526a2e61 GAMOS: Use first file in detection as run file
027a9df2e6 GAMOS: Rename pilots to pilots1
7700e87131 GAMOS: Rename Archive into GameFile to better convey the meaning and use
6c0a29d10d GAMOS: Rename exit label to loopExit to avoid possible conflicts
a9a9382fb9 GAMOS: Fix style
83c27b9c73 GAMOS: Use scummvm types
2d2a2ecb6e GAMOS: Break event loop on Quit message too
8a94f7cc83 GAMOS: Place action dump into dumps subdir
51db5e1739 GAMOS: Do not include translation.h until keymapper is implemented
1c9da3fa69 GAMOS: Delete unused code for load save from save_slot
3d56e6d864 GAMOS: Implement syncSoundSettings
278fc09bed GAMOS: Use RandomSource for get seed value instead of current time
f90060075a GAMOS: Delete extra spaces
8fd96e993f VIDEO: Fix warning in 4xm decoder
fbf17d6ab9 VIDEO: Comment out unused variable in Paco decoder


Commit: 2c2d72142b685e63dcd78cc75b5b43624e77850a
    https://github.com/scummvm/scummvm/commit/2c2d72142b685e63dcd78cc75b5b43624e77850a
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:13+01:00

Commit Message:
GAMOS: First working movie player

Changed paths:
  A engines/gamos/POTFILES
  A engines/gamos/configure.engine
  A engines/gamos/console.cpp
  A engines/gamos/console.h
  A engines/gamos/credits.pl
  A engines/gamos/detection.cpp
  A engines/gamos/detection.h
  A engines/gamos/detection_tables.h
  A engines/gamos/file.cpp
  A engines/gamos/file.h
  A engines/gamos/gamos.cpp
  A engines/gamos/gamos.h
  A engines/gamos/keycodes.cpp
  A engines/gamos/metaengine.cpp
  A engines/gamos/metaengine.h
  A engines/gamos/module.mk
  A engines/gamos/movie.cpp
  A engines/gamos/movie.h
  A engines/gamos/music.cpp
  A engines/gamos/music.h
  A engines/gamos/proc.cpp
  A engines/gamos/proc.h


diff --git a/engines/gamos/POTFILES b/engines/gamos/POTFILES
new file mode 100644
index 00000000000..1e1c41c86c4
--- /dev/null
+++ b/engines/gamos/POTFILES
@@ -0,0 +1 @@
+engines/gamos/metaengine.cpp
diff --git a/engines/gamos/configure.engine b/engines/gamos/configure.engine
new file mode 100644
index 00000000000..9e1e92694c2
--- /dev/null
+++ b/engines/gamos/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
+add_engine gamos "Gamos" no "" "" "highres" "midi"
diff --git a/engines/gamos/console.cpp b/engines/gamos/console.cpp
new file mode 100644
index 00000000000..0f31c47741e
--- /dev/null
+++ b/engines/gamos/console.cpp
@@ -0,0 +1,38 @@
+/* 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 "gamos/console.h"
+
+namespace Gamos {
+
+Console::Console() : GUI::Debugger() {
+	registerCmd("test",   WRAP_METHOD(Console, Cmd_test));
+}
+
+Console::~Console() {
+}
+
+bool Console::Cmd_test(int argc, const char **argv) {
+	debugPrintf("Test\n");
+	return true;
+}
+
+} // End of namespace Gamos
diff --git a/engines/gamos/console.h b/engines/gamos/console.h
new file mode 100644
index 00000000000..e07209f73e8
--- /dev/null
+++ b/engines/gamos/console.h
@@ -0,0 +1,40 @@
+
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_CONSOLE_H
+#define GAMOS_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Gamos {
+
+class Console : public GUI::Debugger {
+private:
+	bool Cmd_test(int argc, const char **argv);
+public:
+	Console();
+	~Console() override;
+};
+
+} // End of namespace Gamos
+
+#endif // GAMOS_CONSOLE_H
diff --git a/engines/gamos/credits.pl b/engines/gamos/credits.pl
new file mode 100644
index 00000000000..8400341ef9b
--- /dev/null
+++ b/engines/gamos/credits.pl
@@ -0,0 +1,3 @@
+begin_section("Gamos");
+	add_person("Name 1", "Handle 1", "");
+end_section();
diff --git a/engines/gamos/detection.cpp b/engines/gamos/detection.cpp
new file mode 100644
index 00000000000..0d980a7b38a
--- /dev/null
+++ b/engines/gamos/detection.cpp
@@ -0,0 +1,45 @@
+/* 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 "base/plugins.h"
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/md5.h"
+#include "common/str-array.h"
+#include "common/translation.h"
+#include "common/util.h"
+#include "gamos/detection.h"
+#include "gamos/detection_tables.h"
+
+const DebugChannelDef GamosMetaEngineDetection::debugFlagList[] = {
+	{ Gamos::kDebugGraphics, "Graphics", "Graphics debug level" },
+	{ Gamos::kDebugPath, "Path", "Pathfinding debug level" },
+	{ Gamos::kDebugFilePath, "FilePath", "File path debug level" },
+	{ Gamos::kDebugScan, "Scan", "Scan for unrecognised games" },
+	{ Gamos::kDebugScript, "Script", "Enable debug script dump" },
+	DEBUG_CHANNEL_END
+};
+
+GamosMetaEngineDetection::GamosMetaEngineDetection() : AdvancedMetaEngineDetection(
+	Gamos::gameDescriptions, Gamos::gamosGames) {
+}
+
+REGISTER_PLUGIN_STATIC(GAMOS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, GamosMetaEngineDetection);
diff --git a/engines/gamos/detection.h b/engines/gamos/detection.h
new file mode 100644
index 00000000000..a6d47a122ff
--- /dev/null
+++ b/engines/gamos/detection.h
@@ -0,0 +1,69 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_DETECTION_H
+#define GAMOS_DETECTION_H
+
+#include "engines/advancedDetector.h"
+
+namespace Gamos {
+
+enum GamosDebugChannels {
+	kDebugGraphics = 1,
+	kDebugPath,
+	kDebugScan,
+	kDebugFilePath,
+	kDebugScript,
+};
+
+extern const PlainGameDescriptor gamosGames[];
+
+extern const ADGameDescription gameDescriptions[];
+
+#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
+
+} // End of namespace Gamos
+
+class GamosMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
+	static const DebugChannelDef debugFlagList[];
+
+public:
+	GamosMetaEngineDetection();
+	~GamosMetaEngineDetection() override {}
+
+	const char *getName() const override {
+		return "gamos";
+	}
+
+	const char *getEngineName() const override {
+		return "Gamos";
+	}
+
+	const char *getOriginalCopyright() const override {
+		return "Gamos (C)";
+	}
+
+	const DebugChannelDef *getDebugChannels() const override {
+		return debugFlagList;
+	}
+};
+
+#endif // GAMOS_DETECTION_H
diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
new file mode 100644
index 00000000000..bc041c4b9b3
--- /dev/null
+++ b/engines/gamos/detection_tables.h
@@ -0,0 +1,43 @@
+/* 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/>.
+ *
+ */
+
+namespace Gamos {
+
+const PlainGameDescriptor gamosGames[] = {
+	{ "gamos", "Gamos" },
+	{ 0, 0 }
+};
+
+const ADGameDescription gameDescriptions[] = {
+	{
+		"solgamer",
+		0,
+		AD_ENTRY1s("solgamer.exe", "6049dd1645071da1b60cdd395e6999ba", 24658521),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_UNSTABLE,
+		GUIO1(GUIO_NONE)
+	},
+
+	AD_TABLE_END_MARKER
+};
+
+} // End of namespace Gamos
diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
new file mode 100644
index 00000000000..3f08332cb00
--- /dev/null
+++ b/engines/gamos/file.cpp
@@ -0,0 +1,211 @@
+/* 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/>.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+
+#include "gamos/gamos.h"
+
+namespace Gamos {
+
+Archive::Archive() {
+};
+
+Archive::~Archive() {
+};
+
+bool Archive::open(const Common::Path &name) {
+    bool res = File::open(name);
+
+    if (!res)
+        return false;
+
+    seek(-12, SEEK_END);
+
+    _dirOffset = 12 + readUint32LE();
+    skip(4);
+    uint32 magic = readUint32LE();
+
+    if (magic != 0x3d53563d) // =VS=
+        return false;
+    
+    seek(-_dirOffset, SEEK_END);
+
+    _dirCount = readUint32LE();
+    _dataOffset = readUint32LE();
+
+    seek(-(_dirOffset + _dirCount * 5), SEEK_END);
+
+    _directories.resize(_dirCount);
+
+    for(uint i = 0; i < _dirCount; ++i) {
+        ArchiveDir &dir = _directories[i];
+
+        dir.offset = readUint32LE();
+        dir.id = readByte();
+    }
+
+    return true;
+}
+
+bool Archive::seekDir(uint id) {
+    int16 idx = findDirByID(id);
+    if (idx < 0)
+        return false;
+    
+    const ArchiveDir &dir = _directories[idx];
+
+    if ( !seek(_dataOffset + dir.offset, SEEK_SET) )
+        return false;
+    
+    return true;
+}
+
+int32 Archive::readPackedInt() {
+    byte b = readByte();
+    if ( !(b & 0x80) )
+        return b;
+    
+    byte num = 0;
+    byte skipsz = 0;
+    if ( !(b & 0x20) )
+        num = b & 0x1f;
+    else
+        num = 1 + ((b >> 2) & 3);
+    
+    if (num > 4) {
+        skipsz = num - 4;
+        num = 4;
+    }
+    
+    int32 val = 0;
+    for(int i = 0; i < num; ++i)
+        val |= readByte() << (i << 3);
+    
+    if (skipsz) {
+        skip(skipsz);
+        /* warning !!!! */
+        printf("readPackedInt skipped %d\n", skipsz);
+    }
+
+    static int32 negs[4] {0, -1, -1025, -263169};
+    static int32 adds[4] {0, 0x80, 0x480, 0x40480};
+
+    if (b & 0x20) {
+        val += (b & 3) * (1 << ((num << 3) & 0x1f));
+        if (b & 0x10)
+            val = negs[num] - val;
+        else
+            val += adds[num];
+    }
+
+    return val;
+}
+
+RawData *Archive::readCompressedData() {
+    RawData *data = new RawData();
+    if (!readCompressedData(data)) {
+        delete data;
+        data = nullptr;
+    }
+    return data;
+}
+
+bool Archive::readCompressedData(RawData *out) {
+    const byte t = readByte();
+    if ((t & 0x80) == 0)
+        return false;
+    
+    _lastReadDecompressedSize = 0;
+    _lastReadSize = 0;
+
+    if (t & 0x40) {
+        /* small uncompressed data */
+    _lastReadSize = t & 0x1F;
+    } else {
+        /* read size */
+        const byte szsize = (t & 3) + 1;
+
+        /* big data size */
+        for (uint i = 0; i < szsize; ++i)
+            _lastReadSize |= readByte() << (i << 3);
+        
+        /* is compressed */
+        if (t & 0xC) {
+            for (uint i = 0; i < szsize; ++i)
+            _lastReadDecompressedSize |= readByte() << (i << 3);
+        }
+    }
+
+    if (!_lastReadSize)
+        return false;
+    
+    _lastReadDataOffset = pos();
+    out->resize(_lastReadSize);
+    read(out->data(), _lastReadSize);
+
+    if (!_lastReadDecompressedSize)
+        return true;
+
+    /* looks hacky but we just allocate array for decompressed and swap it with compressed */
+    RawData compressed(_lastReadDecompressedSize);
+    out->swap(compressed);
+
+    decompress(&compressed, out);
+    return true;
+}
+
+void Archive::decompress(RawData const *in, RawData *out) {
+    uint pos = 0;
+    uint outPos = 0;
+
+    while (pos < in->size()) {
+        byte ctrlBits = (*in)[pos];
+        pos++;
+
+        for(int bitsLeft = 8; bitsLeft > 0; --bitsLeft) {
+            if (pos >= in->size())
+                return;
+
+            if (ctrlBits & 1) {
+                (*out)[outPos] = (*in)[pos];
+                outPos++;
+                pos++;
+            } else {
+                byte b1 = (*in)[pos];
+                byte b2 = (*in)[pos + 1];
+                pos += 2;
+
+                byte num = (b2 & 0xF) + 3;
+                uint16 distance = b1 | ((b2 & 0xF0) << 4);
+
+                for(int i = 0; i < num; ++i) {
+                    (*out)[outPos] = (*out)[outPos - distance];
+                    outPos++;
+                }
+            }
+
+            ctrlBits >>= 1;
+        }
+    }
+}
+
+
+};
\ No newline at end of file
diff --git a/engines/gamos/file.h b/engines/gamos/file.h
new file mode 100644
index 00000000000..46b527b0c45
--- /dev/null
+++ b/engines/gamos/file.h
@@ -0,0 +1,66 @@
+#ifndef GAMOS_FILE_H
+#define GAMOS_FILE_H
+
+#include "common/file.h"
+
+namespace Gamos {
+
+typedef Common::Array<byte> RawData;
+
+struct ArchiveDir {
+    uint32 offset;
+    byte id;
+};
+
+class Archive : public Common::File {
+public:
+	Archive();
+	~Archive() override;
+	bool open(const Common::Path &name) override;
+
+    uint16 getDirCount() const {
+        return _dirCount;
+    }
+
+    int16 findDirByID(uint id) const {
+        for (uint i = 0; i < _directories.size(); ++i) {
+            if (_directories[i].id == id)
+                return i;
+        }
+
+        return -1;
+    }
+
+    bool seekDir(uint id);
+
+    int32 readPackedInt();
+
+    RawData *readCompressedData();
+    bool readCompressedData(RawData *out);
+    
+    static void decompress(RawData const *in, RawData *out);
+    
+public:
+
+uint32 _lastReadSize = 0;
+uint32 _lastReadDecompressedSize = 0;
+uint32 _lastReadDataOffset = 0;
+
+
+private:
+    int32 _dirOffset;
+
+    byte _dirCount;
+    uint32 _dataOffset;
+
+    Common::Array<ArchiveDir> _directories;
+
+
+    bool _error;
+};
+
+
+
+}; // namespace Gamos
+
+#endif // GAMOS_FILE_H
\ No newline at end of file
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
new file mode 100644
index 00000000000..b0fcbf1482e
--- /dev/null
+++ b/engines/gamos/gamos.cpp
@@ -0,0 +1,660 @@
+/* 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/>.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
+#define FORBIDDEN_SYMBOL_EXCEPTION_exit
+#define FORBIDDEN_SYMBOL_EXCEPTION_rand
+#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+#define FORBIDDEN_SYMBOL_EXCEPTION_fopen
+#define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
+#define FORBIDDEN_SYMBOL_EXCEPTION_fclose
+
+
+#include "gamos/gamos.h" 
+#include "graphics/framelimiter.h"
+#include "gamos/detection.h"
+#include "gamos/console.h"
+#include "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug-channels.h"
+#include "common/events.h"
+#include "common/system.h"
+#include "common/rect.h"
+#include "engines/util.h"
+#include "graphics/paletteman.h"
+#include "common/keyboard.h"
+#include "endian.h"
+#include "audio/mididrv.h"
+#include "audio/midiplayer.h"
+#include <cstdio>
+
+namespace Gamos {
+
+GamosEngine *g_engine;
+
+
+const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c, 
+										 0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47, 
+										 0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c, 
+										 0x32, 0x57, 0xdd, 0xb2, 0x38, 0xa7, 0x95, 0x7a};
+
+GamosEngine::GamosEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
+	_gameDescription(gameDesc), _randomSource("Gamos") {
+	g_engine = this;
+}
+
+GamosEngine::~GamosEngine() {
+	delete _screen;
+}
+
+uint32 GamosEngine::getFeatures() const {
+	return _gameDescription->flags;
+}
+
+Common::String GamosEngine::getGameId() const {
+	return _gameDescription->gameId;
+}
+
+Common::Error GamosEngine::run() {
+	// Set the engine's debugger console
+	setDebugger(new Console());
+
+	// If a savegame was selected from the launcher, load it
+	int saveSlot = ConfMan.getInt("save_slot");
+	if (saveSlot != -1)
+		(void)loadGameState(saveSlot);
+
+	Common::String mname("solgamer.exe");
+	init(mname);
+
+	Common::Event e;
+
+	Graphics::FrameLimiter limiter(g_system, 60);
+	while (!shouldQuit()) {
+		while (g_system->getEventManager()->pollEvent(e)) {
+		}
+		
+		// g_system->getPaletteManager()->setPalette(pal, 0, 256);
+
+		limiter.delayBeforeSwap();
+		_screen->update();
+		limiter.startFrame();
+	}
+
+	return Common::kNoError;
+}
+
+Common::Error GamosEngine::syncGame(Common::Serializer &s) {
+	// The Serializer has methods isLoading() and isSaving()
+	// if you need to specific steps; for example setting
+	// an array size after reading it's length, whereas
+	// for saving it would write the existing array's length
+	int dummy = 0;
+	s.syncAsUint32LE(dummy);
+
+	return Common::kNoError;
+}
+
+bool GamosEngine::loader2() {
+	int32 skipsz = _arch.readSint32LE();
+	_arch.skip(skipsz);
+
+	if (_arch.readByte() != 7)
+		return false;
+	
+	RawData data;
+	if (!_arch.readCompressedData(&data))
+		return false;
+
+	int32 p1 = 0;
+	int32 p2 = 0;
+	int32 pid = 0;
+	byte resType = 0;
+	int32 resSize = 0;
+
+	Common::MemoryReadStream dataStream(data.data(), data.size());
+	while (!dataStream.eos()) {
+		byte curByte = dataStream.readByte();
+		
+		if (curByte == 0) {
+			break;
+		} else if (curByte == 0x80) {
+			p1 = 0;
+			p2 = 0;
+			pid = dataStream.readSint32LE();
+		} else if (curByte == 1) {
+			p1 = dataStream.readSint32LE();
+		} else if (curByte == 2) {
+			p2 = dataStream.readSint32LE();
+		} else if (curByte == 7) {
+			int32 needsz = dataStream.readSint32LE(); // check free mem ?
+			printf("7777 want %d\n", needsz);
+		} else if (curByte == 0x40) {
+			resSize = 4;
+			resType = 0x40;
+			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
+				return false;
+			
+			dataStream.skip(resSize);
+		} else if (curByte == 0x41 || curByte == 0x42) {
+			resSize = dataStream.readSint32LE();
+			resType = curByte;
+			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
+				return false;
+			
+			dataStream.skip(resSize);
+		} else if (curByte == 0x43) {
+			resSize = 0x10;
+			resType = 0x43;
+			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
+				return false;
+			
+			dataStream.skip(resSize);
+		} else if (curByte == 0xff) {
+			printf("0xFF  %d %d %d  ", pid, p1, p2);
+			if (!reuseLastResource(resType, pid, p1, p2, 0))
+				return false;
+		} else {
+			printf("loader2 want %x\n", curByte);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool GamosEngine::loadModule(uint id) {
+	if ( (!_runReadDataMod && !initOrLoadSave(_saveLoadID)) ||
+	     !_arch.seekDir(1) )
+		return false;
+
+	_currentModuleID = id;
+	const byte targetDir = 2 + id;
+
+	bool prefixLoaded = false;
+	byte prevByte = 0;
+	bool doLoad = true;
+
+	int32 p1 = 0;
+	int32 p2 = 0;
+	int32 p3 = 0;
+	int32 pid = 0;
+	
+	while(doLoad) {
+		byte curByte = _arch.readByte();
+
+		switch(curByte) {
+			case 0:
+				if (prefixLoaded) {
+					doLoad = false;
+					break;
+				}
+
+				prefixLoaded = true;
+
+				if (!_arch.seekDir(targetDir))
+					return false;
+
+				break;
+			case CONFTP_P1:
+				p1 = _arch.readPackedInt();
+				break;
+			case CONFTP_P2:
+				p2 = _arch.readPackedInt();
+				break;
+			case CONFTP_P3:
+				p3 = _arch.readPackedInt();
+				break;
+			case 4: {
+				_resReadOffset = _arch.pos();
+				bool isResource = true;
+				if (prevByte == RESTP_F) {
+					RawData data;
+					if (!_arch.readCompressedData(&data))
+						return false;
+					if (_runReadDataMod && BYTE_004177f7 == 0)
+						readData2(data);
+					if (BYTE_004177f7 == 0) {
+						//FUN_00403868();
+					}
+					isResource = false; /* do not loadResHandler */
+				} else if (prevByte == RESTP_10) {
+					if (!initMainDatas())
+						return false;
+					isResource = false; /* do not loadResHandler */
+				} else if (prevByte == RESTP_11) {
+					RawData data;
+					if (!_arch.readCompressedData(&data))
+						return false;
+					if (pid == id)
+						readElementsConfig(data);
+					isResource = false; /* do not loadResHandler */
+				} else if (prevByte == RESTP_18) {
+					/* free elements ? */
+				}
+
+				if (isResource) {
+					RawData data;
+					if (!_arch.readCompressedData(&data))
+						return false;
+
+					if (!loadResHandler(prevByte, pid, p1, p2, p3, data))
+						return false;
+				}
+				
+				
+				/* memory management
+				if (prevByte == RESTP_43) {
+
+				} else if (prevByte != RESTP_11 && prevByte != RESTP_20) {
+					// grow used space
+				}
+				*/
+				
+				break;
+			}
+			case 5: {
+				byte t = _arch.readByte();
+				if (t == 0 || (t & 0xec) != 0xec)
+					return false;
+				
+				byte sz = (t & 3) + 1;
+				int32 movieSize = 0;
+				for(uint i = 0; i < sz; ++i)
+					movieSize |= _arch.readByte() << (i * 8);
+				
+				if (prevByte == 0x14)
+					_movieOffsets[pid] = _arch.pos();
+				
+				_arch.skip(movieSize);
+				break;
+			}
+			case 6:
+				if (!loader2())
+					return false;
+				break;
+			case 0xFF:
+				return false;
+				break;
+			default:
+				p1 = 0;
+				p2 = 0;
+				p3 = 0;
+				pid = 0;
+				prevByte = curByte & CONFTP_RESMASK;
+
+				if ( (curByte & CONFTP_IDFLG) == 0 )
+					pid = _arch.readPackedInt();
+
+				break;
+		}
+	}
+
+	_screen->addDirtyRect(_screen->getBounds());
+	_screen->update();
+
+	return true;
+}
+
+bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize) {
+	if (tp == RESTP_12) {
+		setFPS(_fps);
+	} else if (tp == RESTP_18) {
+		printf("18 size %d\n", dataSize);
+	} else if (tp == RESTP_40) {
+		return loadRes40(pid, data, dataSize);		
+	} else if (tp == RESTP_41) {
+		return loadRes41(pid, data, dataSize);
+	} else if (tp == RESTP_42) {
+		return loadRes42(pid, p1, data, dataSize);
+	} else if (tp == RESTP_43) {
+		return loadRes43(pid, p1, p2, data, dataSize);
+	} else if (tp == RESTP_50) {
+		//printf("data 50 size %d\n", dataSize);
+	} else if (tp == RESTP_51) {
+		//printf("sound  size %d\n", dataSize);
+	} else if (tp == RESTP_52) {
+		return loadRes52(pid, data, dataSize);
+		//printf("midi  size %d\n", dataSize);
+	} else if (tp == RESTP_XORSEQ0) {
+		loadXorSeq(data, dataSize, 0);
+	} else if (tp == RESTP_XORSEQ1) {
+		loadXorSeq(data, dataSize, 1);
+	} else if (tp == RESTP_XORSEQ2) {
+		loadXorSeq(data, dataSize, 2);
+	} else {
+		//printf("Unk Res %x\n", tp);
+	}
+	return true;
+}
+
+bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const RawData &data) {
+	return loadResHandler(tp, pid, p1, p2, p3, data.data(), data.size());
+}
+
+bool GamosEngine::reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3) {
+	if (tp == RESTP_43) {
+		_sprites[pid].sequences[p1][p2].image = _images.back();
+	} else {
+		return false;
+	}
+	return true;
+}
+
+
+bool GamosEngine::initOrLoadSave(int32) {
+	return false;
+}
+
+bool GamosEngine::initMainDatas() {
+	RawData rawdata;
+
+	if (!_arch.readCompressedData(&rawdata))
+		return false;
+	
+	Common::MemoryReadStream dataStream(rawdata.data(), rawdata.size(), DisposeAfterUse::NO);
+	
+	_magic = dataStream.readUint32LE();
+	_pages1kbCount = dataStream.readUint32LE();
+	_readBufSize = dataStream.readUint32LE();
+	_width = dataStream.readUint32LE();
+	_height = dataStream.readUint32LE();
+	_unk2 = dataStream.readUint32LE();
+	_unk3 = dataStream.readUint32LE();
+	_movieCount = dataStream.readUint32LE();
+	_unk5 = dataStream.readByte();
+	_unk6 = dataStream.readByte();
+	_unk7 = dataStream.readByte();
+	_fps = dataStream.readByte();
+	_unk8 = dataStream.readByte();
+	_unk9 = dataStream.readByte();
+	_fadeEffectID = dataStream.readByte();
+	_unk11 = dataStream.readByte();
+
+	/*_winX = dataStream.readUint32LE();
+	_winY = dataStream.readUint32LE();
+	_winW = dataStream.readUint32LE();
+	_winH = dataStream.readUint32LE();*/
+	dataStream.skip(16);
+
+	int64 pos = dataStream.pos();
+	_string1 = dataStream.readString(0, 64);
+	dataStream.seek(pos + 64);
+	_winCaption = dataStream.readString(0, 9);
+
+	if (!_screen) {
+		initGraphics(_width, _height);
+		_screen = new Graphics::Screen();
+	}
+
+	_movieOffsets.clear();
+	_movieOffsets.resize(_movieCount, 0);
+
+	return true;
+}
+
+bool GamosEngine::init(const Common::String &moduleName) {
+	BYTE_004177f7 = 0;
+
+	if (!_arch.open(Common::Path(moduleName)))
+		return false;
+
+	if (!loadInitModule())
+		return false;
+	
+
+	if (!playIntro())
+		return false;
+
+	return true;
+}
+
+bool GamosEngine::loadInitModule() {
+
+	_runReadDataMod = true;
+
+	return loadModule(0);
+}
+
+void GamosEngine::setFPS(uint fps) {
+	_delayTime = 0;
+	if (fps)
+		_delayTime = 1000 / fps;
+}
+
+void GamosEngine::readElementsConfig(const RawData &data) {
+	Common::MemoryReadStream dataStream(data.data(), data.size(), DisposeAfterUse::NO);
+
+	uint32 bkgnum1 = dataStream.readUint32LE(); // 0
+	uint32 bkgnum2 = dataStream.readUint32LE(); // 4
+	dataStream.readUint32LE(); // 8
+	dataStream.readUint32LE(); // c
+	dataStream.readUint32LE(); // 10
+	dataStream.readUint32LE(); // 14
+	dataStream.readUint32LE(); // 18
+	dataStream.readUint32LE(); // 1c
+	dataStream.readUint32LE(); // 20
+	uint32 imageCount = dataStream.readUint32LE(); // 24
+	dataStream.readUint32LE(); // 28
+	uint32 midiCount = dataStream.readUint32LE(); // 2c
+	dataStream.readUint32LE(); // 30
+
+	_bkgImages.clear();
+	_bkgImages.resize(bkgnum1 * bkgnum2);
+	
+	_sprites.clear();
+	_sprites.resize(imageCount);
+
+	_midiTracks.clear();
+	_midiTracks.resize(midiCount);
+}
+
+void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
+	Common::MemoryReadStream dataStream(data, dataSize);
+
+	Common::Array<XorArg> &seq = _xorSeq[id];
+
+	uint32 num = dataStream.readUint32LE();
+	seq.resize(num);
+
+	for(uint i = 0; i < num; ++i) {
+		seq[i].len = dataStream.readUint32LE();
+		seq[i].pos = dataStream.readUint32LE();
+	}
+}
+
+bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
+	if (dataSize < 4)
+		return false;
+	
+	_sprites[id].field_0 = data[0];
+	_sprites[id].field_1 = data[1];
+	_sprites[id].field_2 = data[2];
+	_sprites[id].field_3 = data[3];
+
+	return true;
+}
+
+bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
+	if (*(const uint32 *)data != 0) {
+		printf("41 not null!!!\n");
+		exit(0);
+	}
+	_sprites[id].sequences.resize(dataSize / 4);
+	return true;
+}
+
+bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSize) {
+	//printf("loadRes42 pid %d p %d sz %x\n",id, p1, dataSize);
+
+	if (_sprites[id].sequences.size() == 0)
+		_sprites[id].sequences.resize(1);
+
+	int32 count = dataSize / 8;
+	_sprites[id].sequences[p1].resize(count);
+
+	Common::MemoryReadStream strm(data, dataSize);
+	for(int i = 0; i < count; ++i) {
+		int32 dataz = strm.readSint32LE();
+		if (dataz != 0) {
+			printf("42    nut null \n");
+			exit(0);
+		}
+
+		ImagePos &imgpos = _sprites[id].sequences[p1][i];
+		imgpos.xoffset = strm.readSint16LE();
+		imgpos.yoffset = strm.readSint16LE();
+	}
+	return true;
+}
+
+bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize) {
+	_images.push_back( new Image() );
+	_sprites[id].sequences[p1][p2].image = _images.back();
+
+	Image *img = _sprites[id].sequences[p1][p2].image;
+
+	Common::MemoryReadStream s(data, dataSize);
+	img->surface.pitch = img->surface.w = s.readSint16LE();
+	img->surface.h = s.readSint16LE();
+	img->loaded = false;
+
+	uint32 token = s.readUint32LE();
+
+	/* token 'Disk' */
+	if (token == 0x4469736b) {
+		img->offset = s.readSint32LE();
+		img->cSize = s.readSint32LE();
+	} else {
+		if (_sprites[id].field_1 & 0x80) {
+			img->offset = _arch._lastReadDataOffset;
+			img->cSize = _arch._lastReadSize;
+		} else {
+			img->loaded = true;
+			img->rawData.assign(data + 4, data + dataSize);
+			img->surface.setPixels(img->rawData.data());
+			img->surface.format = Graphics::PixelFormat::createFormatCLUT8();
+		}
+	}
+
+	return true;
+}
+
+bool GamosEngine::loadRes52(int32 id, const byte *data, size_t dataSize) {
+	_midiTracks[id].assign(data, data + dataSize);
+	return true;
+}
+
+
+bool GamosEngine::playIntro() {
+	if (_movieCount != 0 && _unk11 == 1)
+		return scriptFunc18(0);
+	return true;
+}
+
+
+bool GamosEngine::scriptFunc18(int id) {
+	if (true) {
+		_isMoviePlay++;
+		bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
+		_isMoviePlay--;
+		return res;
+	}
+
+	return true;
+}
+
+void GamosEngine::stopMidi() {
+	_musicPlayer.stopMusic();
+	_midiStarted = false;
+}
+
+void GamosEngine::stopMCI() {
+
+}
+
+void GamosEngine::stopSounds() {
+
+}
+
+
+
+void GamosEngine::setErrMessage(const Common::String &msg) {
+	if (_errSet)
+		return;
+	
+	_errMessage = msg;
+	_errSet = true;
+}
+
+void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
+	if (_width == 0 || _height == 0)
+		return;
+
+	if (!checkers) {
+		_screen->addDirtyRect(rect);
+		return;
+	}
+
+	static const Common::Point checkerCoords[16] = {
+		{0, 0}, {16, 32}, {48, 16}, {16, 48}, 
+		{0, 32}, {32, 48}, {16, 16}, {48, 0},
+		{32, 32}, {0, 48}, {32, 16}, {16, 0},
+		{48, 32}, {32, 0}, {0, 16}, {48, 48}};
+	
+	const int16 maxDelay = (500 / 10) - 1;
+	
+	for (int16 p = 0; p < 16; p++) {
+		uint32 val = g_system->getMillis();
+		const Common::Point point = checkerCoords[p];
+		for (uint32 x = point.x; x < _width; x += 64) {
+			for (uint32 y = point.y; y < _height; y += 64) {
+				_screen->addDirtyRect(Common::Rect(x, y, x + 16, y + 16));
+			}
+		}
+		_screen->update();
+		val = g_system->getMillis() - val;
+
+		if (val > maxDelay) 
+			g_system->delayMillis(maxDelay - val);
+	}
+}
+
+
+void GamosEngine::readData2(const RawData &data) {
+	Common::MemoryReadStream dataStream(data.data(), data.size());
+	dataStream.skip(4); // FIX ME
+	_messageProc._gd2flags = dataStream.readByte();
+	dataStream.skip(0x40 - 5); // FIX ME
+	for (int i = 0; i < 12; i++) {
+		_messageProc._keyCodes[i] = _winkeyMap[dataStream.readByte()];
+	}
+}
+
+
+void GamosEngine::playMidi(Common::Array<byte> *buffer) {
+	_musicPlayer.stopMusic();
+	_musicPlayer.playMusic(buffer);
+	_midiStarted = true;
+}
+
+} // End of namespace Gamos
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
new file mode 100644
index 00000000000..76fb8329d8b
--- /dev/null
+++ b/engines/gamos/gamos.h
@@ -0,0 +1,320 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_H
+#define GAMOS_H
+
+#include "common/events.h"
+#include "common/rect.h"
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/error.h"
+#include "common/fs.h"
+#include "common/hash-str.h"
+#include "common/random.h"
+#include "common/serializer.h"
+#include "common/util.h"
+#include "common/array.h"
+#include "common/memstream.h"
+#include "engines/engine.h"
+#include "engines/savestate.h"
+#include "graphics/screen.h"
+
+#include "gamos/proc.h"
+#include "gamos/music.h"
+#include "gamos/movie.h"
+
+
+#include "gamos/detection.h"
+#include "gamos/file.h"
+
+namespace Gamos {
+
+struct GamosGameDescription;
+
+enum CONFTYPE {
+	CONFTP_P1 = 1,
+	CONFTP_P2 = 2,
+	CONFTP_P3 = 3,
+	CONFTP_IDFLG = 0x80,
+	CONFTP_RESMASK = 0x7f,
+
+};
+
+enum ACT2 {
+	ACT_NONE = 0xe,
+	ACT2_81 = 0x81,
+	ACT2_82 = 0x82,
+	ACT2_83 = 0x83,
+	ACT2_84 = 0x84,
+	ACT2_8f = 0x8f,
+};
+
+enum RESTYPE {
+	RESTP_F = 0xf,
+	RESTP_10 = 0x10,
+	RESTP_11 = 0x11,
+	RESTP_12 = 0x12,
+	RESTP_18 = 0x18,
+	RESTP_19 = 0x19,
+	RESTP_20 = 0x20,
+	RESTP_40 = 0x40,
+	RESTP_41 = 0x41,
+	RESTP_42 = 0x42,
+	RESTP_43 = 0x43,
+	RESTP_50 = 0x50,
+	RESTP_51 = 0x51,
+	RESTP_52 = 0x52,
+	RESTP_XORSEQ0 = 0x7c,
+	RESTP_XORSEQ1 = 0x7d,
+	RESTP_XORSEQ2 = 0x7e,
+};
+
+struct BkgImage {
+	bool loaded = false;
+	uint32 offset = 0;
+	Graphics::Surface surface;
+
+	RawData rawData;
+};
+
+struct Image {
+	bool loaded = false;
+	int32 offset = 0;
+	int32 size = 0;
+	int32 cSize = 0;
+
+	Graphics::Surface surface;
+
+	RawData rawData;
+};
+
+struct ImagePos {
+	int16 xoffset = 0;
+	int16 yoffset = 0;
+
+	Image *image = nullptr;
+};
+
+typedef Common::Array<ImagePos> ImageSeq;
+
+struct Sprite {
+	byte field_0;
+	byte field_1;
+	byte field_2;
+	byte field_3;
+
+	Common::Array<ImageSeq> sequences;
+};
+
+/* Used to xor savedata */
+struct XorArg {
+	uint32 pos;
+	uint32 len;
+};
+
+class GamosEngine : public Engine {
+friend class MoviePlayer;
+
+private:
+	const ADGameDescription *_gameDescription;
+	Common::RandomSource _randomSource;
+
+	bool _errSet = false;;
+	Common::String _errMessage;
+
+	Archive _arch;
+	
+	byte _cmdByte;
+
+	bool _runReadDataMod;
+	bool _currentModuleID;
+
+	byte _saveLoadID;
+
+	uint32 _magic;
+	uint32 _pages1kbCount;
+	uint32 _readBufSize;
+	uint32 _width;
+	uint32 _height;
+	uint32 _unk2;
+	uint32 _unk3;
+	uint32 _movieCount;
+	byte _unk5;
+	byte _unk6;
+	byte _unk7;
+	byte _fps;
+	byte _unk8;
+	byte _unk9;
+	byte _fadeEffectID;
+	byte _unk11;
+
+	int _isMoviePlay = 0;
+
+	bool _onlyScanImage = false;
+	int32 _resReadOffset = 0;
+
+	Common::String _string1;
+	Common::String _winCaption;
+
+	Common::Array<uint32> _movieOffsets;
+
+	Common::Array<Image *> _images;
+
+	Common::Array<BkgImage> _bkgImages;
+
+	Common::Array<Sprite> _sprites;
+
+	Common::Array< Common::Array<byte> >  _midiTracks;
+
+	uint32 _delayTime = 0;
+
+	Common::Array<XorArg> _xorSeq[3];
+
+	static const byte _xorKeys[32];
+
+
+
+	uint8 BYTE_004177f7 = 0;
+
+	bool _midiStarted = false;
+
+	/* Data2 */
+
+
+
+	MidiMusic _musicPlayer;
+	SystemProc _messageProc;
+	MoviePlayer _moviePlayer;
+
+private:
+	static const uint16 _winkeyMap[256];
+	
+protected:
+	// Engine APIs
+	Common::Error run() override;
+
+	void readCMDByte() {
+		_cmdByte = _arch.readByte();
+	}
+
+	bool loadModule(uint id);
+	bool loader2();
+
+	bool loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize);
+	bool loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const RawData &data);
+
+	bool reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3);
+
+	bool initOrLoadSave(int32);
+
+	bool initMainDatas();
+
+	bool init(const Common::String &moduleName);
+	bool loadInitModule();
+
+	void readElementsConfig(const RawData &data);
+
+	void setFPS(uint fps);
+
+	void loadXorSeq(const byte *data, size_t dataSize, int id);
+
+	bool loadRes40(int32 id, const byte *data, size_t dataSize);
+	bool loadRes41(int32 id, const byte *data, size_t dataSize);
+	bool loadRes42(int32 id, int32 p1, const byte *data, size_t dataSize);
+	bool loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize);
+
+	bool loadRes52(int32 id, const byte *data, size_t dataSize);
+
+
+	void playMidi(Common::Array<byte> *buffer);
+
+	void stopMidi();
+	void stopMCI();
+	void stopSounds();
+
+	bool playIntro();
+
+	bool scriptFunc18(int id);
+
+	void setErrMessage(const Common::String &msg);
+
+	void updateScreen(bool checkers, Common::Rect rect);
+
+	void readData2(const RawData &data);
+
+
+public:
+	Graphics::Screen *_screen = nullptr;
+public:
+	GamosEngine(OSystem *syst, const ADGameDescription *gameDesc);
+	~GamosEngine() override;
+
+	uint32 getFeatures() const;
+
+	/**
+	 * Returns the game Id
+	 */
+	Common::String getGameId() const;
+
+	/**
+	 * Gets a random number
+	 */
+	uint32 getRandomNumber(uint maxNum) {
+		return _randomSource.getRandomNumber(maxNum);
+	}
+
+	bool hasFeature(EngineFeature f) const override {
+		return
+		    (f == kSupportsLoadingDuringRuntime) ||
+		    (f == kSupportsSavingDuringRuntime) ||
+		    (f == kSupportsReturnToLauncher);
+	};
+
+	bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override {
+		return true;
+	}
+	bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override {
+		return true;
+	}
+
+	/**
+	 * Uses a serializer to allow implementing savegame
+	 * loading and saving using a single method
+	 */
+	Common::Error syncGame(Common::Serializer &s);
+
+	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override {
+		Common::Serializer s(nullptr, stream);
+		return syncGame(s);
+	}
+	Common::Error loadGameStream(Common::SeekableReadStream *stream) override {
+		Common::Serializer s(stream, nullptr);
+		return syncGame(s);
+	}
+};
+
+extern GamosEngine *g_engine;
+#define SHOULD_QUIT ::Gamos::g_engine->shouldQuit()
+
+} // End of namespace Gamos
+
+#endif // GAMOS_H
diff --git a/engines/gamos/keycodes.cpp b/engines/gamos/keycodes.cpp
new file mode 100644
index 00000000000..491b56923d7
--- /dev/null
+++ b/engines/gamos/keycodes.cpp
@@ -0,0 +1,284 @@
+/* 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 "gamos/gamos.h"
+namespace Gamos {
+
+const uint16 GamosEngine::_winkeyMap[256] = {
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_CANCEL,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_BACKSPACE,
+    Common::KEYCODE_TAB,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_RETURN,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_MENU,
+    Common::KEYCODE_PAUSE,
+    Common::KEYCODE_CAPSLOCK,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_ESCAPE,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_SPACE,
+    Common::KEYCODE_PAGEUP,
+    Common::KEYCODE_PAGEDOWN,
+    Common::KEYCODE_END,
+    Common::KEYCODE_HOME,
+    Common::KEYCODE_LEFT,
+    Common::KEYCODE_UP,
+    Common::KEYCODE_RIGHT,
+    Common::KEYCODE_DOWN,
+    Common::KEYCODE_SELECT,
+    Common::KEYCODE_PRINT,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INSERT,
+    Common::KEYCODE_DELETE,
+    Common::KEYCODE_HELP,
+    Common::KEYCODE_0,
+    Common::KEYCODE_1,
+    Common::KEYCODE_2,
+    Common::KEYCODE_3,
+    Common::KEYCODE_4,
+    Common::KEYCODE_5,
+    Common::KEYCODE_6,
+    Common::KEYCODE_7,
+    Common::KEYCODE_8,
+    Common::KEYCODE_9,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_a,
+    Common::KEYCODE_b,
+    Common::KEYCODE_c,
+    Common::KEYCODE_d,
+    Common::KEYCODE_e,
+    Common::KEYCODE_f,
+    Common::KEYCODE_g,
+    Common::KEYCODE_h,
+    Common::KEYCODE_i,
+    Common::KEYCODE_j,
+    Common::KEYCODE_k,
+    Common::KEYCODE_l,
+    Common::KEYCODE_m,
+    Common::KEYCODE_n,
+    Common::KEYCODE_o,
+    Common::KEYCODE_p,
+    Common::KEYCODE_q,
+    Common::KEYCODE_r,
+    Common::KEYCODE_s,
+    Common::KEYCODE_t,
+    Common::KEYCODE_u,
+    Common::KEYCODE_v,
+    Common::KEYCODE_w,
+    Common::KEYCODE_x,
+    Common::KEYCODE_y,
+    Common::KEYCODE_z,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_SLEEP,
+    Common::KEYCODE_KP0,
+    Common::KEYCODE_KP1,
+    Common::KEYCODE_KP2,
+    Common::KEYCODE_KP3,
+    Common::KEYCODE_KP4,
+    Common::KEYCODE_KP5,
+    Common::KEYCODE_KP6,
+    Common::KEYCODE_KP7,
+    Common::KEYCODE_KP8,
+    Common::KEYCODE_KP9,
+    Common::KEYCODE_KP_MULTIPLY,
+    Common::KEYCODE_KP_PLUS,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_KP_MINUS,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_KP_DIVIDE,
+    Common::KEYCODE_F1,
+    Common::KEYCODE_F2,
+    Common::KEYCODE_F3,
+    Common::KEYCODE_F4,
+    Common::KEYCODE_F5,
+    Common::KEYCODE_F6,
+    Common::KEYCODE_F7,
+    Common::KEYCODE_F8,
+    Common::KEYCODE_F9,
+    Common::KEYCODE_F10,
+    Common::KEYCODE_F11,
+    Common::KEYCODE_F12,
+    Common::KEYCODE_F13,
+    Common::KEYCODE_F14,
+    Common::KEYCODE_F15,
+    Common::KEYCODE_F16,
+    Common::KEYCODE_F17,
+    Common::KEYCODE_F18,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_NUMLOCK,
+    Common::KEYCODE_SCROLLOCK,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID,
+    Common::KEYCODE_INVALID
+};
+
+}
diff --git a/engines/gamos/metaengine.cpp b/engines/gamos/metaengine.cpp
new file mode 100644
index 00000000000..8768bc8e274
--- /dev/null
+++ b/engines/gamos/metaengine.cpp
@@ -0,0 +1,69 @@
+/* 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/translation.h"
+
+#include "gamos/metaengine.h"
+#include "gamos/detection.h"
+#include "gamos/gamos.h"
+
+namespace Gamos {
+
+static const ADExtraGuiOptionsMap optionsList[] = {
+	{
+		GAMEOPTION_ORIGINAL_SAVELOAD,
+		{
+			_s("Use original save/load screens"),
+			_s("Use the original save/load screens instead of the ScummVM ones"),
+			"original_menus",
+			false,
+			0,
+			0
+		}
+	},
+	AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
+} // End of namespace Gamos
+
+const char *GamosMetaEngine::getName() const {
+	return "gamos";
+}
+
+const ADExtraGuiOptionsMap *GamosMetaEngine::getAdvancedExtraGuiOptions() const {
+	return Gamos::optionsList;
+}
+
+Common::Error GamosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	*engine = new Gamos::GamosEngine(syst, desc);
+	return Common::kNoError;
+}
+
+bool GamosMetaEngine::hasFeature(MetaEngineFeature f) const {
+	return checkExtendedSaves(f) ||
+		(f == kSupportsLoadingDuringStartup);
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(GAMOS)
+REGISTER_PLUGIN_DYNAMIC(GAMOS, PLUGIN_TYPE_ENGINE, GamosMetaEngine);
+#else
+REGISTER_PLUGIN_STATIC(GAMOS, PLUGIN_TYPE_ENGINE, GamosMetaEngine);
+#endif
diff --git a/engines/gamos/metaengine.h b/engines/gamos/metaengine.h
new file mode 100644
index 00000000000..c0ad7ad17a2
--- /dev/null
+++ b/engines/gamos/metaengine.h
@@ -0,0 +1,43 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_METAENGINE_H
+#define GAMOS_METAENGINE_H
+
+#include "engines/advancedDetector.h"
+
+class GamosMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
+public:
+	const char *getName() const override;
+
+	Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+
+	/**
+	 * Determine whether the engine supports the specified MetaEngine feature.
+	 *
+	 * Used by e.g. the launcher to determine whether to enable the Load button.
+	 */
+	bool hasFeature(MetaEngineFeature f) const override;
+
+	const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override;
+};
+
+#endif // GAMOS_METAENGINE_H
diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
new file mode 100644
index 00000000000..d65d1a944e2
--- /dev/null
+++ b/engines/gamos/module.mk
@@ -0,0 +1,22 @@
+MODULE := engines/gamos
+
+MODULE_OBJS = \
+	gamos.o \
+	file.o \
+	console.o \
+	metaengine.o \
+	keycodes.o \
+	music.o \
+	proc.o \
+	movie.o 
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_GAMOS), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
+
+# Detection objects
+DETECT_OBJS += $(MODULE)/detection.o
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
new file mode 100644
index 00000000000..9c703d729d7
--- /dev/null
+++ b/engines/gamos/movie.cpp
@@ -0,0 +1,621 @@
+/* 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/>.
+ *
+ */
+
+ #define FORBIDDEN_SYMBOL_EXCEPTION_printf
+
+#include "gamos/gamos.h"
+
+namespace Gamos {
+
+bool MoviePlayer::init(Common::File *file, uint32 offset, GamosEngine *gamos) {
+    _gamos = gamos;
+    _screen = _gamos->_screen;
+    _messageProc = &_gamos->_messageProc;
+
+
+    _loopCount = 1;
+    _pos = Common::Point();
+    _midiBufferSize = 0;
+    _soundBufferSize = 0;
+    _paletteBufferSize = 0;
+    _bufferSize = 0;
+    _packedBufferSize = 0;
+    _frameTime = 0;
+    _loopPoint = 0;
+    _midiBuffer.clear();
+    _soundBuffer.clear();
+    _paletteBuffer.clear();
+    _buffer.clear();
+    _packedBuffer.clear();
+    _midiStarted = false;
+    _soundPlaying = false;
+    _frameSize = Common::Point(_screen->w, _screen->h);
+
+    _gamos->stopMidi();
+    _gamos->stopMCI();
+
+    _file = file;
+    return _file->seek(offset, SEEK_SET);
+}
+
+bool MoviePlayer::deinit() {
+    if (_soundPlaying)
+        _gamos->stopSounds();
+
+    _gamos->stopMidi();
+    _gamos->stopMCI();
+
+    _file = nullptr;
+    return true;
+}
+
+bool MoviePlayer::playMovie(Common::File *file, uint32 offset, GamosEngine *gamos) {
+    if (!init(file, offset, gamos))
+        return error();
+    
+    while (true) {
+        int status = 0;
+
+        readHdr();
+
+        switch(_hdrBytes[0]) {
+            case 0:
+            status = processControlChunk();
+            break;
+
+            case 1:
+            status = processImageChunk();
+            break;
+
+            case 2:
+            status = processPaletteChunk();
+            break;
+
+            case 3:
+            status = processSoundChunk();
+            break;
+
+            case 4:
+            status = proccessMidiChunk();
+            break;
+
+            default:
+            break;
+        }
+
+        while(true)
+        {
+            if (status == 2) {
+                while(true) {
+                    if ( !readHdr() )
+                        return error();
+                    if (_hdrBytes[0] == 0) {
+                        if (_hdrBytes[1] == 0 || _hdrBytes[1] == 1)
+                            break;
+                    } else {
+                        if (!_file->seek(_hdrValue1, SEEK_CUR))
+                            return error();
+                    }
+                }
+                status = processControlChunk();
+            } else if (status == 0) {
+                return error();
+            } else if (status == 3) {
+                return deinit();
+            } else {
+                break;
+            }
+        }
+    }
+
+    return deinit();
+}
+
+bool MoviePlayer::error() {
+    deinit();
+    _gamos->setErrMessage("Movie playback error.");
+    return false;
+}
+
+int MoviePlayer::processControlChunk() {
+    printf("%x movieProcessControl %d\n", _file->pos(), _hdrBytes[1]);
+
+    switch(_hdrBytes[1]) {
+    case 0:
+        if ((uint32_t)_hdrValue1 != 0x563d2d5b || (uint32_t)_hdrValue2 != 0x5d2d3d53) {
+            error();
+            return 0;
+        }
+        return 3;
+    
+    case 1:
+        _loopCount = 1;
+        _loopPoint = 0;
+
+        if (_hdrBytes[2] != 0)
+            _loopCount = _hdrValue1;
+        
+        if (_hdrBytes[3] != 0)
+            _frameTime = _hdrValue2;
+        break;
+    
+    case 2:
+        if (_hdrBytes[2] != 0) {
+            _packedBufferSize = _hdrValue1;
+            _packedBuffer.resize(_hdrValue1);
+        }
+        break;
+    
+    case 3:
+        if (_hdrBytes[2] != 0) {
+            _bufferSize = _hdrValue1;
+            _buffer.resize(_hdrValue1);
+        }
+        if (_hdrBytes[3] != 0) {
+            _paletteBufferSize = _hdrValue2;
+            _paletteBuffer.resize(_hdrValue2);
+        }
+        break;
+    
+    case 4:
+        if (_hdrBytes[2] != 0) {
+            _soundBufferSize = _hdrValue1;
+            _soundBuffer.resize(_hdrValue1);
+        }
+        if (_hdrBytes[3] != 0) {
+            _midiBufferSize = _hdrValue2;
+            _midiBuffer.resize(_hdrValue2);
+        }
+        break;
+    
+    case 5:
+        if (_hdrBytes[2] != 0) {
+            _pos.x = _hdrValue1;
+        }
+        if (_hdrBytes[3] != 0) {
+            _pos.y = _hdrValue2; /* BUG? Originally here same _pos.x */
+        }
+        break;
+    
+    case 6:
+        if (_hdrBytes[2] != 0) {
+            _frameSize.x = _hdrValue1;
+        }
+        if (_hdrBytes[3] != 0) {
+            _frameSize.y = _hdrValue2;
+        }
+        break;
+
+    }
+    return 1;
+}
+
+int MoviePlayer::processImageChunk() {
+    printf("%x movieProcessImageChunk %d\n", _file->pos(), _hdrValue1);
+    if (!readCompressed(_bufferSize, &_buffer))
+        return 0;
+
+    bool keepAct = true;
+
+    if (_hdrBytes[1] == 1) {
+        _forceStopMidi = false;
+        //waveoutrestart()
+        _screen->fillRect(_screen->getBounds(), _hdrBytes[3]);
+        if (_loopCount > 1)
+            _loopPoint = _file->pos();
+        keepAct = false;
+        _doUpdateScreen = false;
+    }
+    else if (_hdrBytes[1] == 2) {
+        _forceStopMidi = true;
+        _loopCount--;
+        if (_loopCount != 0)
+            _file->seek(_loopPoint, 0);
+    }
+    
+    if (_hdrValue1 != 0) {
+        byte *pdata = _buffer.data();
+        Common::Point xy;
+        Common::Point wh;
+
+        while (true) {
+            byte val = *pdata;
+            pdata++;
+            if ( (val & 0x40) == 0 ) {
+                xy.x = _pos.x + *pdata;
+                pdata++;
+
+                if ( (val & 4) != 0 ) {
+                    xy.x += *pdata * 256;
+                    pdata++;
+                }
+
+                xy.y = _pos.y + *pdata;
+                pdata++;
+
+                if ( (val & 8) != 0 ) {
+                    xy.y += *pdata * 256;
+                    pdata++;
+                }
+
+                wh.x = *pdata;
+                pdata++;
+
+                if ( (val & 0x10) != 0 ) {
+                    wh.x += *pdata * 256;
+                    pdata++;
+                }
+
+                wh.y = *pdata;
+                pdata++;
+
+                if ( (val & 0x20) != 0 ) {
+                    wh.y += *pdata * 256;
+                    pdata++;
+                }
+            } else {
+                xy = _pos;
+                wh = _frameSize;
+            }
+
+            printf("movie blit%d %d %d %d %d\n", val & 3, xy.x, xy.y, wh.x, wh.y);
+            static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) = 
+               {&blit0, 
+                &blit1, 
+                &blit2, 
+                &blit3};
+            
+            pdata = blitters[val & 3](Common::Rect(xy, xy + wh), pdata, _screen->surfacePtr());
+
+            if (_doUpdateScreen) {
+                _gamos->updateScreen(false, Common::Rect(xy, xy + wh));
+            }
+
+            if (val & 0x80)
+                break;
+        }
+        
+    }
+
+    if (_doUpdateScreen) {
+        //FUN_00403c70(true);
+    }
+
+    uint32 tstamp = 0;
+    uint8 act = processMessages(keepAct, &tstamp);
+
+    if (act == ACT2_82)
+        return 2;
+
+    if (act == ACT2_83)
+        return 3;
+
+    if (_hdrBytes[1] == 1) {
+        _gamos->updateScreen(_gamos->_fadeEffectID != 0, Common::Rect(_pos, _pos + _frameSize));
+
+        _firstFrameTime = g_system->getMillis();
+        _currentFrame = 0;
+        _skippedFrames = 0;
+        _doUpdateScreen = true;
+    } else if (_frameTime == 0) {
+        _doUpdateScreen = true;
+    } else {
+        int32 dtime = (tstamp - _firstFrameTime) / _currentFrame;
+        if (dtime > _frameTime) {
+            if (_soundBufferSize) {
+                _skippedFrames++;
+                if (_skippedFrames != 8)
+                    _doUpdateScreen = false;
+            }
+        }
+        else if (dtime < _frameTime) {
+            while (true) {
+                act = processMessages(false, &tstamp);
+                if (act == ACT2_82)
+                    return 2;
+                
+                if (act == ACT2_83)
+                    return 3;
+                
+                if ((tstamp - _firstFrameTime) / _currentFrame >= _frameTime)
+                    break;
+
+                g_system->delayMillis(1);
+            }
+        }
+
+        _skippedFrames = 0;
+        _doUpdateScreen = true;
+    }
+
+    _screen->update();
+    _currentFrame++;
+    
+    return 1;
+}
+
+int MoviePlayer::processPaletteChunk() {
+    printf("%x movieProcessPaletteChunk\n", _file->pos());
+    if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
+        return 0;
+    
+    _screen->setPalette(_paletteBuffer.data());
+    //g_system->getPaletteManager()->setPalette(PalColors.data(), 0, 256);
+    
+    return 1;
+}
+
+int MoviePlayer::processSoundChunk() {
+    printf("%x movieProcessSoundChunk\n", _file->pos());
+    if (!readCompressed(_soundBufferSize, &_soundBuffer))
+        return 0;
+    return 1;
+}
+
+int MoviePlayer::proccessMidiChunk() {
+    printf("%x movieProccessMidiChunk\n", _file->pos());
+
+    if (_midiStarted && (_forceStopMidi == false || _hdrBytes[1] != 0)) {
+        _gamos->stopMidi();
+        _midiStarted = false;
+    }
+
+    if (_hdrValue1 == 0)
+        return 1;
+
+    if (_midiStarted) {
+        if ( !_file->seek(_hdrValue1, SEEK_CUR) )
+            return 0;
+        return 1;
+    }
+
+    if (!readCompressed(_midiBufferSize, &_midiBuffer)) {
+        _midiStarted = false;
+        return 0;
+    }
+
+    _gamos->playMidi(&_midiBuffer);
+    _midiStarted = true;
+
+    return 1;
+}
+
+bool MoviePlayer::readHdr() {
+    _file->read(_hdrBytes, 4);
+    _hdrValue1 = _file->readSint32LE();
+    _hdrValue2 = _file->readSint32LE();
+    return true;
+}
+
+bool MoviePlayer::readCompressed(int32_t count, Common::Array<byte> *buf) {
+    if (_hdrValue1 == 0)
+        return true;
+
+    if (_hdrValue1 != _hdrValue2) {
+        _packedBuffer.resize(_hdrValue1);
+        _file->read(_packedBuffer.data(), _hdrValue1);
+        buf->resize(_hdrValue2);
+        Archive::decompress(&_packedBuffer, buf);
+    }
+    else {
+        buf->resize(_hdrValue1);
+        _file->read(buf->data(), _hdrValue1);
+    }
+    return true;
+}
+
+byte* MoviePlayer::blit0(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+    int16 y = rect.top;
+    while (y < rect.bottom) {
+        const int count = rect.width();
+        byte *out = (byte *)surface->getBasePtr(rect.left, y);
+        for (int i = 0; i < count; i++) {
+            *out += *in;
+            in++;
+            out++;
+        }
+        y++;
+    }
+    return in;
+}
+
+byte* MoviePlayer::blit1(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+    int16 y = rect.top;
+    int16 x = rect.left;
+    while (y < rect.bottom) {
+        
+        byte b = *in;
+        in++;
+        if (b & 0x80) {
+            if ((b & 0x40) == 0) {
+                int count = (b & 0x3f) + 1;
+                byte *out = (byte *)surface->getBasePtr(x, y);
+                for (int i = 0; i < count; i++) {
+                    *out += *in;
+                    in++;
+                    out++;
+                }
+                x += count;
+            } else {
+                if ((b & 0x3f) == 0)
+                    x = rect.right;
+                else {
+                    if ((b & 0x3f) != 1) {
+                        int count = (b & 0x3f) + 1;
+                        byte val = *in;
+                        in++;
+                        byte *out = (byte *)surface->getBasePtr(x, y);
+                        for (int i = 0; i < count; i++) {
+                            *out += val;
+                            out++;
+                        }
+                        x += count;
+                    } else {
+                        int count = rect.right - x;
+                        byte *out = (byte *)surface->getBasePtr(x, y);
+                        for (int i = 0; i < count; i++) {
+                            *out += *in;
+                            in++;
+                            out++;
+                        }
+                        x = rect.right;
+                    }
+                }
+            }
+        } else {
+            x += b + 1;
+        }
+
+        if (x >= rect.right) {
+            y++;
+            x = rect.left;
+        }
+    }
+    return in;
+}
+
+byte* MoviePlayer::blit2(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+    int16 y = rect.top;
+    int16 x = rect.left;
+    while (y < rect.bottom) {
+        
+        byte b = *in;
+        in++;
+        if (b & 0x80) {
+            if ((b & 0x40) == 0) {
+                x += (b & 0x3f) + 1;
+            } else {
+                int count = (b & 0x3f) + 1;
+                byte *out = (byte *)surface->getBasePtr(x, y);
+                for (int i = 0; i < count; i++) {
+                    *out += *in;
+                    in++;
+                    out++;
+                }
+                x += count;
+            }
+        } else if (b == 0) {
+            x += b + 1;
+        } else if (b != 1) {
+            int count = b + 1;
+            byte val = *in;
+            in++;
+            byte *out = (byte *)surface->getBasePtr(x, y);
+            for (int i = 0; i < count; i++) {
+                *out += val;
+                out++;
+            }
+            x += count;
+        } else {
+            int count = rect.right - x;
+            byte *out = (byte *)surface->getBasePtr(x, y);
+            for (int i = 0; i < count; i++) {
+                *out += *in;
+                in++;
+                out++;
+            }
+            x = rect.right;
+        }
+
+        if (x >= rect.right) {
+            y++;
+            x = rect.left;
+        }
+    }
+    return in;
+}
+
+byte* MoviePlayer::blit3(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+    int16 y = rect.top;
+    int16 x = rect.left;
+    while (y < rect.bottom) {
+        
+        byte b = *in;
+        in++;
+        if (b & 0x80) {
+            if ((b & 0x40) == 0) {
+                x += (b & 0x3f) + 1;
+            } else {
+                if ((b & 0x3f) == 0)
+                    x = rect.right;
+                else {
+                    if ((b & 0x3f) != 1) {
+                        int count = (b & 0x3f) + 1;
+                        byte val = *in;
+                        in++;
+                        byte *out = (byte *)surface->getBasePtr(x, y);
+                        for (int i = 0; i < count; i++) {
+                            *out += val;
+                            out++;
+                        }
+                        x += count;
+                    } else {
+                        int count = rect.right - x;
+                        byte *out = (byte *)surface->getBasePtr(x, y);
+                        for (int i = 0; i < count; i++) {
+                            *out += *in;
+                            in++;
+                            out++;
+                        }
+                        x = rect.right;
+                    }
+                }
+            }
+        } else {
+            int count = b + 1;
+            byte *out = (byte *)surface->getBasePtr(x, y);
+            for (int i = 0; i < count; i++) {
+                *out += *in;
+                in++;
+                out++;
+            }
+            x += count;
+        }
+
+        if (x >= rect.right) {
+            y++;
+            x = rect.left;
+        }
+    }
+    return in;
+}
+
+
+uint8 MoviePlayer::processMessages(bool keepAct, uint32 *msecs) {
+	if (!keepAct)
+		_messageProc->_act2 = ACT_NONE;
+
+	Common::Event e;
+	while (g_system->getEventManager()->pollEvent(e)) {
+		if (e.type == Common::EVENT_QUIT) {
+			//_errMessage = 1;
+			return ACT2_83;
+		}
+		_messageProc->processMessage(e);
+	}
+
+	uint8 act = _messageProc->_act2;
+	_messageProc->_act2 = ACT_NONE;
+	*msecs = g_system->getMillis();
+	return act;
+}
+
+}
\ No newline at end of file
diff --git a/engines/gamos/movie.h b/engines/gamos/movie.h
new file mode 100644
index 00000000000..9e70e6862b7
--- /dev/null
+++ b/engines/gamos/movie.h
@@ -0,0 +1,108 @@
+/* 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/>.
+ *
+ */
+
+
+#ifndef GAMOS_MOVIE_H
+#define GAMOS_MOVIE_H
+
+#include "common/file.h"
+
+namespace Gamos
+{
+
+class GamosEngine;
+
+class MoviePlayer {
+    public:
+
+    bool playMovie(Common::File *file, uint32 offset, GamosEngine *gamos);
+
+
+    private:
+    
+    bool init(Common::File *file, uint32 offset, GamosEngine *gamos);
+	bool deinit();
+	bool error();
+
+	int processControlChunk();	
+	int processImageChunk();
+	int processPaletteChunk();
+	int processSoundChunk();
+	int proccessMidiChunk();
+
+	bool readHdr();
+	bool readCompressed(int32_t count, Common::Array<byte> *buf);
+
+	uint8 processMessages(bool keepAct, uint32 *msecs);
+
+	static byte* blit0(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte* blit1(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte* blit2(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte* blit3(Common::Rect rect, byte *in, Graphics::Surface *surface);
+        
+
+
+    private:
+
+    GamosEngine *_gamos = nullptr;
+    Graphics::Screen *_screen = nullptr;
+    SystemProc *_messageProc = nullptr;
+
+
+    bool _doUpdateScreen = false;
+	uint32 _skippedFrames = 0;
+	uint32 _currentFrame = 0;
+	uint32 _firstFrameTime = 0;
+
+	bool _forceStopMidi = false;
+
+	int _loopCount = 1;
+    int _loopPoint = 0;
+
+	Common::Point _pos; /* Movie frame leftup corner */
+	Common::Point _frameSize; /* Sizes of movie frame */
+
+    int _midiBufferSize = 0;
+    int _soundBufferSize = 0;
+    int _paletteBufferSize = 0;
+    int _bufferSize = 0;
+    int _packedBufferSize = 0;
+    int _frameTime = 0;
+
+    Common::Array<byte> _midiBuffer;
+    Common::Array<byte> _soundBuffer;
+    Common::Array<byte> _paletteBuffer;
+    Common::Array<byte> _buffer;
+    Common::Array<byte> _packedBuffer;
+
+    bool _midiStarted = false;
+    bool _soundPlaying = false;
+
+	Common::File *_file = nullptr;
+
+	byte _hdrBytes[4];
+	int32_t _hdrValue1 = 0;
+	int32_t _hdrValue2 = 0;
+};
+
+} 
+
+#endif //GAMOS_MOVIE_H
\ No newline at end of file
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
new file mode 100644
index 00000000000..373250ed675
--- /dev/null
+++ b/engines/gamos/music.cpp
@@ -0,0 +1,185 @@
+/* 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/system.h"
+#include "gamos/gamos.h"
+
+namespace Gamos {
+
+MidiMusic::MidiMusic() {
+    MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_GM);
+
+    _driver = MidiDriver::createMidi(dev);
+    _driver->open();
+    _driver->sendGMReset();
+}
+
+MidiMusic::~MidiMusic() {
+    if (_driver) {
+        _driver->stopAllNotes(true);
+        _driver->close();
+        delete _driver;
+    }
+}
+
+void MidiMusic::stopMusic() {
+    g_system->getTimerManager()->removeTimerProc(_timerProc);
+
+    if (_mutex.lock()) {
+        _driver->stopAllNotes(true);
+
+        _mutex.unlock();
+    }
+}
+
+void MidiMusic::playMusic(Common::Array<byte> *midiData) {
+    stopMusic();
+
+    if (!midiData || midiData->size() <= 4)
+        return;
+
+    if (_mutex.lock()) {
+        _pMidiData.clear();
+        _pMidiData.swap(*midiData);
+
+        _dataPos = 4;
+        _midiDelayTicks = 1;
+        _midiDelayCount = 1;
+
+        if (_pMidiData[_dataPos] == 0xf8) {
+            _dataPos++;
+            midi2low();
+            _dataPos++;
+        }
+
+        g_system->getTimerManager()->installTimerProc(_timerProc, 10 * 1000, this, "Gamos::Music");
+
+        _mutex.unlock();
+    }
+}
+
+void MidiMusic::update() {
+    while (true) {
+        if (_dataPos >= _pMidiData.size())
+            return;
+
+        uint8 b = _pMidiData[_dataPos];
+
+        if (b > 0x7f) {
+            /* only if new event type then update _midiOp */
+            _midiOp = b;
+            _dataPos++;
+        }
+
+        bool doDelay = true;
+
+        if (_midiOp == 0xf0 || _midiOp == 0xf7) {
+            int16 skipLen = midi2low();
+            if (skipLen >= 0)
+                _dataPos += skipLen;
+        } else if (_midiOp == 0xff) {
+            if (_midiDelayTicks != -1) {
+                _midiDelayCount = _midiDelayTicks;
+                _dataPos = _dataStart;
+            } else {
+                g_system->getTimerManager()->removeTimerProc(_timerProc);
+                _driver->stopAllNotes(true);
+            }
+            break;
+        } else {
+            uint8 param1 = _pMidiData[_dataPos];
+            uint8 param2 = 0;
+            _dataPos++;
+
+            bool doSend = true;
+
+            uint8 cmd = _midiOp & 0xf0;
+            if (cmd != MidiDriver_BASE::MIDI_COMMAND_PROGRAM_CHANGE && 
+                cmd != MidiDriver_BASE::MIDI_COMMAND_CHANNEL_AFTERTOUCH) {
+                if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_OFF || 
+                    cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_ON) {
+                    if (_midiMute)
+                        doSend = false;
+                }
+
+                b = _pMidiData[_dataPos];
+                _dataPos++;
+
+                doDelay = (b & 0x80) == 0;
+                param2 = b & 0x7f;
+            }
+
+            if (doSend)
+                _driver->send(_midiOp, param1, param2);
+        }
+
+        if (doDelay) {
+            int16 ln = midi2low();
+            if (ln > 0) {
+                _midiTimeStamp += ln * 10;
+                if (g_system->getMillis() < _midiTimeStamp)
+                    break;
+            }
+        }
+    }
+}
+
+int16 MidiMusic::midi2low() {
+    if (_dataPos >= _pMidiData.size())
+        return -1;
+    
+    int16 dat = _pMidiData[_dataPos];
+    _dataPos++;
+
+    if (dat & 0x80) {
+        if (_dataPos >= _pMidiData.size())
+            return -1;
+
+        dat &= 0x7f;
+        dat |= _pMidiData[_dataPos] << 7;
+
+        _dataPos++;
+    }
+    return dat;
+}
+
+
+void MidiMusic::_timerProc(void *data) {
+    if (!data)
+        return;
+
+    MidiMusic *_this = (MidiMusic *)data;
+
+    if (_this->_midiDelayCount != 0) {
+        _this->_midiDelayCount--;
+        if (_this->_midiDelayCount != 0)
+            return;
+        
+        _this->_midiTimeStamp = g_system->getMillis();
+    }
+
+    if (_this->_midiTimeStamp <= g_system->getMillis() && _this->_mutex.lock()) {
+        _this->update();
+        _this->_mutex.unlock();
+    }
+}
+
+};
\ No newline at end of file
diff --git a/engines/gamos/music.h b/engines/gamos/music.h
new file mode 100644
index 00000000000..68be61815bd
--- /dev/null
+++ b/engines/gamos/music.h
@@ -0,0 +1,67 @@
+/* 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/>.
+ *
+ */
+
+
+#ifndef GAMOS_MUSIC_H
+#define GAMOS_MUSIC_H
+
+
+
+#include "audio/mididrv.h"
+#include "common/memstream.h"
+#include "common/mutex.h"
+#include "common/scummsys.h"
+#include "common/timer.h"
+#include "common/system.h"
+
+namespace Gamos {
+
+class MidiMusic {
+private:
+	MidiDriver *_driver = nullptr;
+    Common::Array<byte> _pMidiData;
+
+    Common::Mutex _mutex;
+    
+    uint32 _dataPos = 0;
+    uint32 _dataStart = 0;
+    int32 _midiDelayTicks = 0;
+    int32 _midiDelayCount = 0;
+    uint32 _midiTimeStamp = 0;
+    uint32 _midiOp = 0; /* save midi event type between update cycles */
+    bool _midiMute = false;
+	
+public:
+
+	MidiMusic();
+  ~MidiMusic();
+
+  void stopMusic();
+  void playMusic(Common::Array<byte> *midiData);
+  void update();
+  int16 midi2low();
+
+  static void _timerProc(void *data);
+};
+
+};
+
+#endif //GAMOS_MUSIC_H
\ No newline at end of file
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
new file mode 100644
index 00000000000..c095bc93eda
--- /dev/null
+++ b/engines/gamos/proc.cpp
@@ -0,0 +1,80 @@
+/* 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 "gamos/gamos.h"
+
+namespace Gamos {
+	
+void SystemProc::processMessage(const Common::Event &ev) {
+	switch(ev.type) {
+	case Common::EVENT_KEYDOWN:
+		if ((_gd2flags & 1) == 0)
+			return;
+
+		if (ev.kbd.keycode == _keyCodes[0])
+			_act1 = 0;
+		else if (ev.kbd.keycode == _keyCodes[1])
+			_act1 = 1;
+		else if (ev.kbd.keycode == _keyCodes[2])
+			_act1 = 2;
+		else if (ev.kbd.keycode == _keyCodes[3])
+			_act1 = 3;
+		else if (ev.kbd.keycode == _keyCodes[4])
+			_act1 = 4;
+		else if (ev.kbd.keycode == _keyCodes[5])
+			_act1 = 5;
+		else if (ev.kbd.keycode == _keyCodes[6])
+			_act1 = 6;
+		else if (ev.kbd.keycode == _keyCodes[7])
+			_act1 = 7;
+		else {
+			if (ev.kbd.keycode == _keyCodes[8])
+				_act2 = ACT2_82;
+			else if (ev.kbd.keycode == _keyCodes[9])
+				_act2 = ACT2_83;
+			else if (ev.kbd.keycode == _keyCodes[10])
+				_act2 = ACT2_8f;
+			else if (ev.kbd.keycode == _keyCodes[11])
+				_act2 = ACT2_84;
+
+			return;
+		}
+
+		if ((_act1 < 8) && (ev.kbd.flags & Common::KBD_SHIFT))
+			_act1 |= 8;
+
+		_mouseAct = _mouseReported;
+		break;
+	
+	case Common::EVENT_MOUSEMOVE:
+		if ((_gd2flags & 1) == 0)
+			return;
+
+		_mouseReported = ev.mouse;
+		
+		break;
+	
+	default:
+		break;
+	}
+}
+
+}
\ No newline at end of file
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
new file mode 100644
index 00000000000..a691b3e36aa
--- /dev/null
+++ b/engines/gamos/proc.h
@@ -0,0 +1,50 @@
+/* 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/>.
+ *
+ */
+
+
+#ifndef GAMOS_PROC_H
+#define GAMOS_PROC_H
+
+#include <common/events.h>
+
+namespace Gamos {
+
+class SystemProc {
+public:
+
+    void processMessage(const Common::Event &ev);
+
+public:
+    uint8 _act1 = 0;
+    uint8 _act2 = 0;
+
+    Common::Point _mouseReported;
+    Common::Point _mouseAct;
+
+    uint8 _gd2flags = 0; /* 0x4 */
+    uint16 _keyCodes[12]; /* 0x40 */
+    
+};
+
+
+}
+
+#endif //GAMOS_PROC_H
\ No newline at end of file


Commit: a2cc90780f125c7ad1617ec2e165f5c36926f4c9
    https://github.com/scummvm/scummvm/commit/a2cc90780f125c7ad1617ec2e165f5c36926f4c9
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:14+01:00

Commit Message:
GAMOS: Load data and process scripts

Changed paths:
  A engines/gamos/vm.cpp
  A engines/gamos/vm.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/module.mk
    engines/gamos/movie.cpp
    engines/gamos/music.cpp
    engines/gamos/music.h
    engines/gamos/proc.cpp
    engines/gamos/proc.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index b0fcbf1482e..187b293d315 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -27,6 +27,8 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_fopen
 #define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
 #define FORBIDDEN_SYMBOL_EXCEPTION_fclose
+#define FORBIDDEN_SYMBOL_EXCEPTION_setbuf
+#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
 
 
 #include "gamos/gamos.h" 
@@ -39,6 +41,7 @@
 #include "common/events.h"
 #include "common/system.h"
 #include "common/rect.h"
+#include "common/util.h"
 #include "engines/util.h"
 #include "graphics/paletteman.h"
 #include "common/keyboard.h"
@@ -78,26 +81,50 @@ Common::Error GamosEngine::run() {
 	// Set the engine's debugger console
 	setDebugger(new Console());
 
+	_vm._callFuncs = vmCallDispatcher;
+	_vm._callingObject = this;
+
 	// If a savegame was selected from the launcher, load it
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot != -1)
 		(void)loadGameState(saveSlot);
+	
+	g_system->showMouse(true);
 
 	Common::String mname("solgamer.exe");
 	init(mname);
 
 	Common::Event e;
 
-	Graphics::FrameLimiter limiter(g_system, 60);
 	while (!shouldQuit()) {
 		while (g_system->getEventManager()->pollEvent(e)) {
+			_messageProc.processMessage(e);
 		}
-		
-		// g_system->getPaletteManager()->setPalette(pal, 0, 256);
 
-		limiter.delayBeforeSwap();
-		_screen->update();
-		limiter.startFrame();
+		uint32 curTime = g_system->getMillis();
+		if (curTime > _lastTimeStamp + _delayTime) {
+			_lastTimeStamp = curTime;
+
+			if (_messageProc._gd2flags & 2) {
+
+			}
+
+			uint8 result = 2;
+			while (result == 2) {
+				result = update({}, _messageProc._mouseReportedPos, _messageProc._mouseActPos, _messageProc._act2, _messageProc._act1, _messageProc._rawKeyCode, true);
+			}
+
+			if (!result)
+				break;
+			
+			_messageProc._act2 = ACT_NONE;
+			_messageProc._act1 = ACT_NONE;
+			_messageProc._rawKeyCode = ACT_NONE;
+			
+			doDraw();
+		}
+
+		//if (_delayTime)
 	}
 
 	return Common::kNoError;
@@ -147,7 +174,7 @@ bool GamosEngine::loader2() {
 			p2 = dataStream.readSint32LE();
 		} else if (curByte == 7) {
 			int32 needsz = dataStream.readSint32LE(); // check free mem ?
-			printf("7777 want %d\n", needsz);
+			//printf("7777 want %d\n", needsz);
 		} else if (curByte == 0x40) {
 			resSize = 4;
 			resType = 0x40;
@@ -161,6 +188,8 @@ bool GamosEngine::loader2() {
 			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
 				return false;
 			
+			_loadedDataSize += (resSize + 3) & (~3);
+			
 			dataStream.skip(resSize);
 		} else if (curByte == 0x43) {
 			resSize = 0x10;
@@ -168,9 +197,11 @@ bool GamosEngine::loader2() {
 			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
 				return false;
 			
+			_loadedDataSize += (resSize + 3) & (~3);
+			
 			dataStream.skip(resSize);
 		} else if (curByte == 0xff) {
-			printf("0xFF  %d %d %d  ", pid, p1, p2);
+			//printf("0xFF  %d %d %d \n", pid, p1, p2);
 			if (!reuseLastResource(resType, pid, p1, p2, 0))
 				return false;
 		} else {
@@ -190,6 +221,12 @@ bool GamosEngine::loadModule(uint id) {
 	_currentModuleID = id;
 	const byte targetDir = 2 + id;
 
+	_readingBkgMainId = -1;
+
+	/* Complete me */
+
+	setbuf(stdout, 0);
+
 	bool prefixLoaded = false;
 	byte prevByte = 0;
 	bool doLoad = true;
@@ -250,25 +287,43 @@ bool GamosEngine::loadModule(uint id) {
 					isResource = false; /* do not loadResHandler */
 				} else if (prevByte == RESTP_18) {
 					/* free elements ? */
+					_readingBkgOffset = _arch.pos();
 				}
 
+				RawData data;
 				if (isResource) {
-					RawData data;
 					if (!_arch.readCompressedData(&data))
 						return false;
 
 					if (!loadResHandler(prevByte, pid, p1, p2, p3, data))
 						return false;
+					
 				}
-				
-				
-				/* memory management
-				if (prevByte == RESTP_43) {
 
-				} else if (prevByte != RESTP_11 && prevByte != RESTP_20) {
-					// grow used space
+				uint32 datasz = (data.size() + 3) & (~3);
+				
+				switch (prevByte) {
+					case RESTP_11:
+					case RESTP_18:
+					case RESTP_19:
+					case RESTP_20:
+					case RESTP_40:
+					case RESTP_50:
+						break;
+					
+					case RESTP_43:
+						//printf("t %x sz %x sum %x\n", prevByte, data.size(), _loadedDataSize);
+						if (_onlyScanImage)
+							_loadedDataSize += 0x10;
+						else
+							_loadedDataSize += datasz;
+						break;
+					
+					default:
+						//printf("t %x sz %x sum %x\n", prevByte, data.size(), _loadedDataSize);
+						_loadedDataSize += datasz;
+						break;
 				}
-				*/
 				
 				break;
 			}
@@ -309,7 +364,23 @@ bool GamosEngine::loadModule(uint id) {
 		}
 	}
 
-	_screen->addDirtyRect(_screen->getBounds());
+	//FUN_00404a28();
+	if (BYTE_004177f7 == 0) {
+		// Reverse Here
+
+		setCursor(0, false);
+
+		if (_readingBkgMainId == -1)
+			_screen->setPalette(_bkgImages[0].palette);
+			//FUN_00405ebc(0, false);
+		else 
+			_screen->setPalette(_bkgImages[_readingBkgMainId].palette);
+			//FUN_00405ebc(0, false);
+		
+		addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes ));
+	} else {
+		
+	}
 	_screen->update();
 
 	return true;
@@ -318,8 +389,56 @@ bool GamosEngine::loadModule(uint id) {
 bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize) {
 	if (tp == RESTP_12) {
 		setFPS(_fps);
+	} else if (tp == RESTP_13) {
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
 	} else if (tp == RESTP_18) {
-		printf("18 size %d\n", dataSize);
+		loadRes18(pid, data, dataSize);
+	} else if (tp == RESTP_19) {
+		if (BYTE_004177f7 == 0) {
+			for (int i = 0; i < _thing1.size(); i++)
+				_thing1[i] = 0xf0fe;
+			
+			DAT_004177f8 = 1;
+			ProcessScript(true, data, dataSize);
+			if (_needReload)
+				printf(" need reload from loadResHandler, CANT HAPPEN! \n ");
+			DAT_004177f8 = 0;
+			FUN_00404fcc(pid);
+		}
+	} else if (tp == RESTP_20) {
+		if (dataSize != 4) 
+			return false;
+		_someActsArr[pid].unk1 = getU32(data);
+	} else if (tp == RESTP_21) {
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		_someActsArr[pid].script1 = _loadedDataSize + p3;
+		//printf("RESTP_21 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
+	} else if (tp == RESTP_22) {
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		_someActsArr[pid].script2 = _loadedDataSize + p3;
+		//printf("RESTP_22 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
+	} else if (tp == RESTP_23) {
+		if (dataSize % 4 != 0 || dataSize < 4)
+			return false;
+		_someActsArr[pid].scriptS.resize(dataSize / 4);
+	} else if (tp == RESTP_2A) {
+		ScriptS &scr = _someActsArr[pid].scriptS[p1];
+		scr.data.assign(data, data + dataSize);
+	} else if (tp == RESTP_2B) {
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		_someActsArr[pid].scriptS[p1].codes1 = _loadedDataSize + p3;
+		//printf("RESTP_2B %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
+	} else if (tp == RESTP_2C) {
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		_someActsArr[pid].scriptS[p1].codes2 = _loadedDataSize + p3;
+		//printf("RESTP_2C %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
+	} else if (tp == RESTP_38) {
+		printf("Data 38 size %d\n", dataSize);
+		_thing2[pid].field_0.assign(data, data + dataSize);
+	} else if (tp == RESTP_39) {
+		_thing2[pid].field_1.assign(data, data + dataSize);
+	} else if (tp == RESTP_3A) {
+		_thing2[pid].field_2.assign(data, data + dataSize);
 	} else if (tp == RESTP_40) {
 		return loadRes40(pid, data, dataSize);		
 	} else if (tp == RESTP_41) {
@@ -342,7 +461,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_XORSEQ2) {
 		loadXorSeq(data, dataSize, 2);
 	} else {
-		//printf("Unk Res %x\n", tp);
+		printf("Unk Res %x at %x sz %x\n", tp, _loadedDataSize, dataSize);
 	}
 	return true;
 }
@@ -409,6 +528,8 @@ bool GamosEngine::initMainDatas() {
 	_movieOffsets.clear();
 	_movieOffsets.resize(_movieCount, 0);
 
+	_drawElements.clear();
+
 	return true;
 }
 
@@ -429,8 +550,24 @@ bool GamosEngine::init(const Common::String &moduleName) {
 }
 
 bool GamosEngine::loadInitModule() {
-
+	rndSeed(g_system->getMillis());
+	//DAT_0041723c = -1;
+	_curObjIndex = -1;
+	PTR_00417218 = nullptr;
+    PTR_00417214 = nullptr;
+	//DAT_00417238 = 0;
+	_xorSeq[2].clear();
+	_xorSeq[1].clear();
+	_xorSeq[0].clear();
+	_isMoviePlay = 0;
+	DAT_00417802 = false;
+	//DAT_00417808 = 0;
 	_runReadDataMod = true;
+	//DAT_00417807 = 0;
+	//DAT_00417806 = 0;
+	//DAT_004177fa = 0;
+	//DAT_004177fb = 0;
+	//_mouseInWindow = false;
 
 	return loadModule(0);
 }
@@ -446,18 +583,29 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 
 	uint32 bkgnum1 = dataStream.readUint32LE(); // 0
 	uint32 bkgnum2 = dataStream.readUint32LE(); // 4
-	dataStream.readUint32LE(); // 8
-	dataStream.readUint32LE(); // c
-	dataStream.readUint32LE(); // 10
-	dataStream.readUint32LE(); // 14
+	_thing1Size = dataStream.readUint32LE(); // 8
+	_thing1Count = dataStream.readUint32LE(); // c
+	_bkgUpdateSizes.x = dataStream.readUint32LE(); // 10
+	_bkgUpdateSizes.y = dataStream.readUint32LE(); // 14
 	dataStream.readUint32LE(); // 18
-	dataStream.readUint32LE(); // 1c
-	dataStream.readUint32LE(); // 20
+	uint32 actsCount = dataStream.readUint32LE(); // 1c
+	uint32 unk1Count = dataStream.readUint32LE(); // 20
 	uint32 imageCount = dataStream.readUint32LE(); // 24
 	dataStream.readUint32LE(); // 28
 	uint32 midiCount = dataStream.readUint32LE(); // 2c
 	dataStream.readUint32LE(); // 30
 
+	_thing1Shift = 2;
+	for(int i = 2; i < 9; i++) {
+		if (_thing1Size <= (1 << i)) {
+			_thing1Shift = i;
+			break;
+		}
+	}
+
+	_thing1.clear();
+	_thing1.resize(_thing1Count << _thing1Shift);
+
 	_bkgImages.clear();
 	_bkgImages.resize(bkgnum1 * bkgnum2);
 	
@@ -466,6 +614,15 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 
 	_midiTracks.clear();
 	_midiTracks.resize(midiCount);
+
+	_thing2.clear();
+	_thing2.resize(unk1Count);
+
+	_someActsArr.clear();
+	_someActsArr.resize(actsCount);
+	
+	_loadedDataSize = 0;
+	_vm.clearMemory();
 }
 
 void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
@@ -485,12 +642,17 @@ void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
 bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
 	if (dataSize < 4)
 		return false;
+
+	if (dataSize % 4)
+		printf("dataSize > 4\n");
 	
 	_sprites[id].field_0 = data[0];
 	_sprites[id].field_1 = data[1];
 	_sprites[id].field_2 = data[2];
 	_sprites[id].field_3 = data[3];
 
+	_onlyScanImage = data[1] & 0x80;
+
 	return true;
 }
 
@@ -499,6 +661,8 @@ bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
 		printf("41 not null!!!\n");
 		exit(0);
 	}
+	if (dataSize % 4)
+		printf("loadRes41 datasize > 4 \n");
 	_sprites[id].sequences.resize(dataSize / 4);
 	return true;
 }
@@ -537,6 +701,7 @@ bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size
 	img->surface.pitch = img->surface.w = s.readSint16LE();
 	img->surface.h = s.readSint16LE();
 	img->loaded = false;
+	img->offset = -1;
 
 	uint32 token = s.readUint32LE();
 
@@ -564,6 +729,40 @@ bool GamosEngine::loadRes52(int32 id, const byte *data, size_t dataSize) {
 	return true;
 }
 
+bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
+	BkgImage &bimg = _bkgImages[id];
+	bimg.loaded = true;
+	bimg.offset = _readingBkgOffset;
+	bimg.field2_0x8 = 0;
+	bimg.field3_0xc = 0;
+	bimg.palette = nullptr;
+
+	bimg.rawData.assign(data, data + dataSize);
+	
+	Common::MemoryReadStream strm(data, dataSize);
+	
+	if (_readingBkgMainId == -1 && (strm.readUint32LE() & 0x80000000) )
+		_readingBkgMainId = id;
+	
+	//printf("res 18 id %d 4: %x\n", id, strm.readUint32LE());
+
+	strm.seek(8);
+
+	bimg.surface.pitch = bimg.surface.w = strm.readUint32LE();
+	bimg.surface.h = strm.readUint32LE();
+
+	uint32 imgsize = strm.readUint32LE();
+
+	//printf("res 18 id %d 14: %x\n", id, strm.readUint32LE());
+
+	bimg.surface.setPixels(bimg.rawData.data() + 0x18);
+	bimg.surface.format = Graphics::PixelFormat::createFormatCLUT8();
+
+	bimg.palette = bimg.rawData.data() + 0x18 + imgsize;
+
+	return true;
+}
+
 
 bool GamosEngine::playIntro() {
 	if (_movieCount != 0 && _unk11 == 1)
@@ -571,11 +770,20 @@ bool GamosEngine::playIntro() {
 	return true;
 }
 
+bool GamosEngine::playMovie(int id) {
+	bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
+	if (_readingBkgMainId == -1)
+		_screen->setPalette(_bkgImages[0].palette);
+	else 
+		_screen->setPalette(_bkgImages[_readingBkgMainId].palette);
+	return res;
+}
+
 
-bool GamosEngine::scriptFunc18(int id) {
+bool GamosEngine::scriptFunc18(uint32 id) {
 	if (true) {
 		_isMoviePlay++;
-		bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
+		bool res = playMovie(id);
 		_isMoviePlay--;
 		return res;
 	}
@@ -589,11 +797,11 @@ void GamosEngine::stopMidi() {
 }
 
 void GamosEngine::stopMCI() {
-
+	printf("Not implemented stopMCI\n");
 }
 
 void GamosEngine::stopSounds() {
-
+	printf("Not implemented stopSounds\n");
 }
 
 
@@ -642,19 +850,1474 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 
 void GamosEngine::readData2(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
-	dataStream.skip(4); // FIX ME
-	_messageProc._gd2flags = dataStream.readByte();
-	dataStream.skip(0x40 - 5); // FIX ME
+	dataStream.seek(4); // FIX ME
+	_messageProc._gd2flags = dataStream.readByte(); //4
+	//5
+	//x15
+	dataStream.seek(0x15);
+	_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
+	//x16
+	dataStream.seek(0x38);
+	_midiTrack = dataStream.readUint32LE(); //0x38
+	_mouseCursorImgId = dataStream.readUint32LE(); //0x3c
+	//0x40
 	for (int i = 0; i < 12; i++) {
 		_messageProc._keyCodes[i] = _winkeyMap[dataStream.readByte()];
 	}
 }
 
 
-void GamosEngine::playMidi(Common::Array<byte> *buffer) {
+bool GamosEngine::playMidi(Common::Array<byte> *buffer) {
 	_musicPlayer.stopMusic();
-	_musicPlayer.playMusic(buffer);
-	_midiStarted = true;
+	_midiStarted = _musicPlayer.playMusic(buffer);
+	return _midiStarted;
+}
+
+uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
+	_needReload = false;
+
+	FUN_00402c2c(mouseMove, actPos, act2, act1);
+
+	/*if ()*/{
+		bool loop = false;
+		if (!DAT_00417802)
+			loop = FUN_00402fb4();
+		/*else
+			loop = FUN_00403314(_messageProc._act2);*/
+		
+		if (_needReload)
+			return 2;  // rerun update after loadModule
+		
+		while (loop) {
+			if (!PTR_00417388) {
+				if (FUN_004033a8(mouseMove) && FUN_004038b8())
+					return 1;
+				else
+					return 0;
+			}
+
+			RawKeyCode = ACT_NONE;
+
+			if (!FUN_00402bc4())
+				return 0;
+			
+			if (!DAT_00417802)
+				loop = FUN_00402fb4();
+			/*else
+				loop = FUN_00403314(_messageProc._act2);*/
+
+			if (_needReload)
+				return 2; // rerun update after loadModule
+		}
+	}
+	return 1;
+}
+
+
+int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int32 code1, int32 code2) {
+
+	Common::Array<uint16> ARR_00412208(512);
+
+	Common::MemoryReadStream rstream(data, dataSize);
+
+	if (!p1) {
+		DAT_00417228 = PTR_00417218->pos;
+		DAT_0041722c = PTR_00417218->blk;
+	} else {
+		PTR_00417218 = nullptr;
+		_curObjIndex = -1;
+		PTR_00417214 = nullptr;
+		//DAT_00417238 = 0;
+		//DAT_0041723c = -1;
+		DAT_0041722c = 0;
+		DAT_00417228 = 0;
+		BYTE_004177f6 = 0x10;
+		_preprocDataId = 0;
+		PTR_004173e8 = nullptr;
+	}
+
+	DAT_00417220 = DAT_00417228;
+	DAT_00417224 = DAT_0041722c;
+
+	int32 spos = -1;
+	int32 sbuf[6];
+
+	uint8 b[4];
+	rstream.read(b, 4);
+
+	//printf("FLAGS %x\n", b[0]);
+
+	if (b[0] & 1) {
+		if (code1 != -1) {
+			if (!doScript(code1))
+				return 0;
+			if (_needReload)
+				return 0;
+		}
+		rstream.skip(4);
+	}
+
+	if (b[0] & 2) {
+		bool fastSkipAll = false;
+		while (true) {
+			uint16 sz = rstream.readUint16LE();
+			uint8 f = rstream.readByte();
+			uint8 t = rstream.readByte();
+
+			if (fastSkipAll) {
+				rstream.skip(sz * 4);
+				if (f & 1)
+					break;
+				continue;
+			}
+			
+			if (t == 4) {
+				spos++;
+				if (spos == 0) {
+					sbuf[0] = 0;
+					sbuf[1] = 0;
+				} else {
+					int32 p = sbuf[spos * 2 - 1];
+					sbuf[spos * 2 + 1] = p;
+					sbuf[spos * 2] = p;
+				}
+			} else {
+				spos = -1;
+			}
+			int32 ps = spos * 2 + 1;
+			for (int read = 0; read < sz; read++) {
+				byte c[4];
+				rstream.read(c, 4);
+				preprocessData(_preprocDataId, c);
+
+				uint16 fb = 0;
+				if (!p1) {
+					fb = _thing1[ ((int8)c[2] + DAT_00417220 + _thing1Size) % _thing1Size  +  
+				                  ((((int8)c[3] + DAT_00417224 + _thing1Count) % _thing1Count) << _thing1Shift) ];
+				} else {
+					fb = _thing1[(c[3] << _thing1Shift) + c[2]];
+				}
+
+				uint8 lb = fb & 0xff;
+				uint8 hb = (fb >> 8) & 0xff;
+
+				int cval = 0;
+				int fnc = c[1] >> 4;
+				if ((c[1] & 1) == 0) {
+					if (c[0] == lb && (c[1] & hb & 0xf0)) {
+						cval = 2;
+					}
+				} else if (lb != 0xfe && 
+					       (_thing2[c[0]].field_0[(fb >> 3) & 0xff] & (1 << fb & 7)) != 0) {
+					
+					if (!_thing2[c[0]].field_2.empty()) {
+						c[1] = c[1] & 0xf | _thing2[c[0]].field_2[lb];
+						preprocessData(fnc + 8, c);
+					}
+
+					if (hb & c[1] & 0xf0) {
+						cval = 2;
+					}
+				}
+
+				if (c[1] & 2 == cval) {
+					if ((c[1] & 0xc) == 0) {
+						rstream.skip((sz - read) * 4);
+						break;
+					}
+					if ((c[1] & 0xc) == 4)
+						return 0;
+					if ((c[1] & 0xc) == 8) {
+						fastSkipAll = true;
+						rstream.skip((sz - read) * 4);
+						break;
+					}
+					ARR_00412208[ sbuf[ps] ] = (c[3] << 8) | c[2];
+					sbuf[ps]++;
+				} else if ((sz - read) == 1 && spos > -1 && sbuf[spos * 2] == sbuf[ps]) {
+					return 0;
+				}
+			}
+
+			if (f & 1)
+				break;
+		}
+	}
+
+	BYTE_00412200 = 0;
+
+	if (b[0] & 4) {
+		byte s = b[1];
+		preprocessData(_preprocDataId, b);
+		preprocessDataB1(b[1] >> 4, b);
+		rnd();
+		b[1] = (b[1] & 0xf0) | (s & 0xf);
+		//FUN_00402a68(b);
+		if (_needReload)
+			return 0;
+	}
+
+	BYTE_004177fc = 0;
+	if (b[0] & 8) {
+		uint32 fldsv;
+		if (PTR_00417218)
+			fldsv = PTR_00417218->fld_5;
+		if (code2 != -1)
+			doScript(code2);
+		if (_needReload)
+			return 0;
+		rstream.skip(4);
+		if (BYTE_004177fc == 0 && BYTE_00412200 == 0 && PTR_00417218 && PTR_00417218->fld_5 != fldsv && PTR_00417218->y != -1)
+			addDirtRectOnObject( &_drawElements[PTR_00417218->y] );
+	}
+
+	if (BYTE_004177fc == 0 && BYTE_00412200 != 0)
+		FUN_004095a0(PTR_00417218);
+
+	int32 retval = 0;
+
+	if (b[0] & 0x10) {
+		int ivar5 = -1;
+		while (true) {
+			uint16 dcount = rstream.readUint16LE();
+			uint8 dbits = rstream.readByte();
+			uint8 dtype = rstream.readByte();
+
+			/* set next pos before next iteration */
+			uint32 nextpos = rstream.pos() + (dcount * 4);
+
+			switch (dtype) {
+			case 0: {
+				uint16 rndval = rndRange16(b[1] & 3);
+
+				if (rndval == 2) {
+					rstream.skip(dcount * 4);
+					dcount = rstream.readUint16LE();
+					rstream.skip(2 + dcount * 4);
+					dcount = rstream.readUint16LE();
+					rstream.skip(2);
+				} else if (rndval == 1) {
+					rstream.skip(dcount * 4);
+					dcount = rstream.readUint16LE();
+					rstream.skip(2);
+				}
+
+				rnd();
+
+				for (int i = 0; i < dcount; i++) {
+					byte d[4];
+					rstream.read(d, 4);
+					retval += processData(p1, d);
+
+					if (_needReload)
+						return 0;
+				}
+				
+				return retval + 1;
+			} break;
+
+			case 1: {
+				int32 num = rndRange16(dcount);
+
+				for (int i = 0; i < dcount; i++) {
+					byte d[4];
+					rstream.read(d, 4);
+
+					if (num != 0) {
+						retval += processData(p1, d);
+						if (_needReload)
+							return 0;
+					}
+
+					num--;
+				}
+
+			} break;
+
+			case 2: {
+				rstream.skip(4 * rndRange16(dcount));
+
+				byte d[4];
+				rstream.read(d, 4);
+
+				retval += processData(p1, d);
+				if (_needReload)
+						return 0;
+			} break;
+
+			case 3: {
+				for (int i = 0; i < dcount; i++) {
+					uint16 doproc = rndRange16(2);
+
+					byte d[4];
+					rstream.read(d, 4);
+
+					if (doproc != 0) {
+						retval += processData(p1, d);
+
+						if (_needReload)
+							return 0;
+					}
+				}
+			} break;
+
+			default: {
+				ivar5++;
+				/* Seems it's has a error in original
+				   think it's must be:
+				   min + rnd(max-min) */
+				
+				uint32 lb = rnd() >> 0x10;
+				uint32 idx = ((sbuf[ivar5 * 2 + 1] - sbuf[ivar5 * 2]) * lb + sbuf[ivar5 * 2]) >> 0x10;
+				uint16 tval = ARR_00412208[ idx ];
+
+				for (int i = 0; i < dcount; i++) {
+					byte d[4];
+					rstream.read(d, 4);
+
+					if ( ((d[3] << 8) | d[2]) == tval ) {
+						retval += processData(p1, d);
+						if (_needReload)
+							return 0;
+						break;
+					}
+				}
+			} break;
+
+			}
+
+			rstream.seek(nextpos);
+
+			if (dbits & 1) 
+				break;
+		}
+		
+	}
+	return retval + 1;
+}
+
+uint32 GamosEngine::getU32(const void *ptr) {
+	const uint8 *p = (const uint8 *)ptr;
+	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+
+void GamosEngine::preprocessData(int id, byte *data) {
+	switch (id) {
+
+	default:
+	case 0:
+		break;
+
+	case 1:
+	case 10: {
+		static const uint8 lookup[16] = {0, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0x10, 0x30, 0x50, 0x70, 0x90, 0xB0, 0xD0, 0xF0};
+		int8 tmp = (int8)data[3];
+		data[3] = data[2];
+		data[2] = -tmp;
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+
+	case 2:
+	case 12: {
+		static const uint8 lookup[16] = {0, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0};
+		data[3] = -((int8)data[3]);
+		data[2] = -((int8)data[2]);
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+
+	case 3:
+	case 16: {
+		static const uint8 lookup[16] = {0, 0x80, 0x10, 0x90, 0x20, 0xA0, 0x30, 0xB0, 0x40, 0xC0, 0x50, 0xD0, 0x60, 0xE0, 0x70, 0xF0};
+		int8 tmp = (int8)data[2];
+		data[2] = data[3];
+		data[3] = -tmp;
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+
+	case 4: {
+		static const uint8 lookup[16] = {0, 0x10, 0x80, 0x90, 0x40, 0x50, 0xC0, 0xD0, 0x20, 0x30, 0xA0, 0xB0, 0x60, 0x70, 0xE0, 0xF0};
+		data[2] = -((int8)data[2]);
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+
+	case 5: {
+		static const uint8 lookup[16] = {0, 0x20, 0x10, 0x30, 0x80, 0xA0, 0x90, 0xB0, 0x40, 0x60, 0x50, 0x70, 0xC0, 0xE0, 0xD0, 0xF0};
+		int8 tmp = (int8)data[2];
+		data[2] = -((int8)data[3]);
+		data[3] = -tmp;
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+
+	case 6: {
+		static const uint8 lookup[16] = {0, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, 0x80, 0xC0, 0xA0, 0xE0, 0x90, 0xD0, 0xB0, 0xF0};
+		data[3] = -((int8)data[3]);
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+
+	case 7: {
+		static const uint8 lookup[16] = {0, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0};
+		uint8 tmp = data[2];
+		data[2] = data[3];
+		data[3] = tmp;
+		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+	} break;
+	}
+}
+
+void GamosEngine::preprocessDataB1(int id, byte *data) {
+	switch (id) {
+
+		default:
+		case 0:
+			break;
+	
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			data[1] &= 0xf0;
+			break;
+	
+		case 3: {
+			static const uint8 lookup[2] = {0x10, 0x20};
+			data[1] = lookup[rndRange16(2)];
+		} break;
+
+		case 5: {
+			static const uint8 lookup[2] = {0x10, 0x40};
+			data[1] = lookup[rndRange16(2)];
+		} break;
+
+		case 6: {
+			static const uint8 lookup[2] = {0x20, 0x40};
+			data[1] = lookup[rndRange16(2)];
+		} break;
+
+		case 7: {
+			static const uint8 lookup[3] = {0x10, 0x20, 0x40};
+			data[1] = lookup[rndRange16(3)];
+		} break;
+
+		case 9: {
+			static const uint8 lookup[2] = {0x10, 0x80};
+			data[1] = lookup[rndRange16(2)];
+		} break;
+
+		case 0xa: {
+			static const uint8 lookup[2] = {0x20, 0x80};
+			data[1] = lookup[rndRange16(2)];
+		} break;
+
+		case 0xb: {
+			static const uint8 lookup[3] = {0x10, 0x20, 0x80};
+			data[1] = lookup[rndRange16(3)];
+		} break;
+
+		case 0xc: {
+			static const uint8 lookup[2] = {0x40, 0x80};
+			data[1] = lookup[rndRange16(2)];
+		} break;
+
+		case 0xd: {
+			static const uint8 lookup[3] = {0x10, 0x40, 0x80};
+			data[1] = lookup[rndRange16(3)];
+		} break;
+
+		case 0xe: {
+			static const uint8 lookup[3] = {0x20, 0x40, 0x80};
+			data[1] = lookup[rndRange16(3)];
+		} break;
+
+		case 0xf: {
+			static const uint8 lookup[4] = {0x10, 0x20, 0x40, 0x80};
+			data[1] = lookup[rndRange16(4)];
+		} break;
+	}
+}
+
+int GamosEngine::processData(int id, byte *data) {
+	preprocessData(_preprocDataId, data);
+	if (id == 0) {
+		FUN_0040283c( ((int8)data[3] + DAT_00417224 + _thing1Count) % _thing1Count,
+		              ((int8)data[2] + DAT_00417220 + _thing1Size) % _thing1Size,
+					  data );
+		if (_needReload)
+			return 0;
+		return data[2] == 0 && data[3] == 0;
+	} else {
+		FUN_0040283c( (int8)data[3], (int8)data[2],	data);
+		return 0;
+	}
+}
+
+void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
+	byte td[4];
+	memcpy(td, data, 4);
+
+	uint16 *pv1 = _thing1.data() + (id << _thing1Shift) + pos;
+
+	uint8 oid = td[0];
+
+	if ((td[1] & 1) == 0) {
+		if (oid == 0xfe) {
+			FUN_00402654(1, id, pos);
+			if (_needReload)
+				return;
+
+			*pv1 = (td[1] << 8) | td[0];
+			return;
+		}
+	} else {
+		Unknown1 &unk1 = _thing2[ oid ];
+		uint8 index = rndRange16( unk1.field_1[0] );
+		if (!unk1.field_2.empty()) {
+			byte id = td[1];
+			td[1] = unk1.field_2[ unk1.field_1[ index + 1 ] ];
+			preprocessData(8 + (id >> 4), td);
+		}
+	}
+
+	preprocessDataB1(td[1] >> 4, td);
+	rnd(); // needed?
+
+	td[0] = oid;
+
+	Object *obj = nullptr;
+	int index = 0;
+	byte *odat = nullptr;
+		
+	SomeAction &act = _someActsArr[oid];
+	if ((act.unk1 & 0xff) == 0) {
+		FUN_00402654(1, id, pos);
+		if (_needReload)
+			return;
+		obj = nullptr;
+		index = -1;
+		odat = nullptr;
+	} else {
+		FUN_00402654(0, id, pos);
+		if (_needReload)
+			return;
+		obj = getFreeObject();
+		obj->flags = (td[1] & 0xf0) | 3;
+		obj->actID = oid;
+		obj->fld_4 = 0;
+		obj->fld_5 = (act.unk1 >> 16) & 0xff;
+		obj->pos = pos;
+		obj->blk = id;
+		obj->x = -1;
+		obj->y = -1;
+		obj->fld_2 = *pv1;
+		if (PTR_00417218 && obj->index > PTR_00417218->index)
+			obj->fld_2 |= 0x100;
+		
+		int storageSize = ((act.unk1 >> 24) & 0xff) + 1;
+		// if (storageSize < 5) {
+		// 	obj->pImg = nullptr;
+		// 	odat = &obj->pImg;
+		// } else {
+		// 	odat = malloc(storageSize);
+		// 	obj->pImg = (Sprite *)odat;
+		// 	obj->flags |= 8;
+		// }
+		obj->storage.clear();
+		obj->storage.resize(storageSize, 0);
+		odat = obj->storage.data();
+		index = obj->index;
+		if ((act.unk1 & 0xff) == 3 && PTR_004121b4 == nullptr)
+			PTR_004121b4 = obj;
+	}
+
+	*pv1 = (td[1] << 8) | td[0];
+	executeScript(td[1], id, pos, odat, index, obj, &act, act.script1);
+}
+
+void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
+	if (id != -1)
+		removeObjectMarkDirty(&_drawElements[id]);
+}
+
+
+void GamosEngine::FUN_00402654(int mode, int id, int pos) {
+	uint16 *pth1 = &_thing1[pos + (id << _thing1Shift)];
+
+	uint8 actid = (*pth1 & 0xff);
+
+	if (actid == 0xfe)
+		return;
+	
+	SomeAction &act = _someActsArr[actid];
+	Object *povar4 = nullptr;
+	bool multidel = false;
+
+	for(Object &obj : _drawElements) {
+		if (obj.flags & 1) {
+			if (obj.flags & 2) {
+				if (obj.pos == pos && obj.blk == id) {
+					removeObjectByIDMarkDirty(obj.y);
+					if (obj.y != obj.x)
+						removeObjectByIDMarkDirty(obj.x);
+					/* if (obj.flags & 8)
+						obj.storage.clear(); */
+					FUN_004023d8(&obj);
+					removeObject(&obj);
+					FUN_0040255c(&obj);
+					povar4 = &obj;
+					if (!mode || multidel)
+						break;
+					
+					multidel = true;
+				}
+			} else {
+				if (mode && obj.fld_4 == pos && obj.fld_5 == id && 
+					obj.pos == 0xff && obj.blk == 0xff && (obj.flags & 0x40) == 0) {
+					
+					removeObjectMarkDirty(&obj);
+					if (multidel)
+						break;
+
+					multidel = true;
+				}
+			}
+		}
+	}
+
+	if (povar4)
+		*pth1 = povar4->fld_2 & 0xf0ff;
+	
+	executeScript((*pth1) >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
+}
+
+Object *GamosEngine::getFreeObject() {
+	for (Object &rObj : _drawElements) {
+		if ( (rObj.flags & 1) == 0 ) {
+			rObj.flags = 1;
+			return &rObj;
+		}
+	}
+
+	_drawElements.emplace_back();
+	Object &rObj = _drawElements.back();
+	rObj.flags = 1;
+	rObj.index = _drawElements.size() - 1;
+	return &rObj;
+}
+
+void GamosEngine::removeObject(Object *obj) {
+	obj->flags = 0;
+	/*if (&(_drawElements.back()) == obj) {
+		int32 lastindex = _drawElements.size() - 1;
+		for (int32 i = lastindex - 1; i >= 0; i--) {
+			if ( _drawElements[i].flags & 1 ) {
+				lastindex = i;
+				break;
+			}
+		}
+		_drawElements.resize(lastindex);
+	}*/
+}
+
+void GamosEngine::removeObjectMarkDirty(Object *obj) {
+	if (obj->flags & 0x80)
+		addDirtRectOnObject(obj);
+	removeObject(obj);
+}
+
+
+void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, SomeAction *act, int32 scriptAddr) {
+	if (scriptAddr == -1)
+		return;
+	
+	uint8 sv1 = BYTE_004177f6;
+	byte *sv2 = PTR_004173e8;
+	int32 sv3 = DAT_0041722c;
+	int32 sv4 = DAT_00417228;
+	int32 sv5 = DAT_00417224;
+	int32 sv6 = DAT_00417220;
+	int32 sv7 = _curObjIndex;
+	Object *sv8 = PTR_00417218;
+	SomeAction *sv9 = PTR_00417214;
+
+	BYTE_004177f6 = p1;
+	PTR_004173e8 = storage;
+	DAT_0041722c = id;
+	DAT_00417228 = pos;
+	DAT_00417224 = id;
+	DAT_00417220 = pos;
+	_curObjIndex = index;
+	PTR_00417218 = pobj;
+	PTR_00417214 = act;
+
+	doScript(scriptAddr);
+
+	BYTE_004177f6 = sv1;
+	PTR_004173e8 = sv2;
+	DAT_0041722c = sv3;
+	DAT_00417228 = sv4 ;
+	DAT_00417224 = sv5;
+	DAT_00417220 = sv6;
+	_curObjIndex = sv7;
+	PTR_00417218 = sv8;
+	PTR_00417214 = sv9;
+}
+
+bool GamosEngine::FUN_00402fb4()
+{
+	if (_drawElements.empty())
+		return true;
+
+	Object *pobj = DAT_00412204;
+	if (!pobj)
+		pobj = &(_drawElements.front());
+
+	for (int32 objIdx = pobj->index; objIdx < _drawElements.size(); objIdx++) {
+		pobj = &_drawElements[objIdx];
+	
+		if ((pobj->flags & 3) == 3) {
+			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7))) ) {
+				if (pobj->fld_2 & 0x100) {
+					pobj->fld_2 &= ~0x100;
+				} else {
+					if ((pobj->flags & 4) == 0) {
+						if (pobj->y != -1 && FUN_00402f34(true, false, &_drawElements[pobj->y])) {
+							pobj->y = pobj->x;
+							if (pobj->x != -1) {
+								Object &o = _drawElements[pobj->x];
+								o.flags |= 0x80;
+								o.fld_4 = pobj->pos;
+								o.fld_5 = pobj->blk;
+								FUN_0040921c(&o);
+								addDirtRectOnObject(&o);
+							}
+						}
+					} else {
+						if (FUN_00402f34(pobj->y != pobj->x, true, &_drawElements[pobj->y])) {
+							pobj->y = pobj->x;
+							if (pobj->x != -1) {
+								Object &o = _drawElements[pobj->x];
+								o.flags |= 0x80;
+								o.fld_4 = pobj->pos;
+								o.fld_5 = pobj->blk;
+								FUN_0040921c(&o);
+								addDirtRectOnObject(&o);
+							}
+							pobj->flags &= ~4;
+						} else {
+							if (pobj == DAT_00412204) {
+								goto exit;
+							}
+							goto continue_to_next_object;
+						}
+					}
+
+					PTR_00417218 = pobj;
+					_curObjIndex = pobj->index;
+					PTR_00417214 = &_someActsArr[pobj->actID];
+					PTR_004173e8 = pobj->storage.data();
+
+					//DAT_00417804 = 0;
+					for ( ScriptS &scr: PTR_00417214->scriptS ) {
+						BYTE_004177f6 = PTR_00417218->flags & 0xf0;
+						
+						int ivr8 = 0;
+						if (BYTE_004177f6 == 0x20)
+							ivr8 = 1;
+						else if (BYTE_004177f6 == 0x40)
+							ivr8 = 2;
+						else if (BYTE_004177f6 == 0x80)
+							ivr8 = 3;
+						
+						bool tmp = false;
+						for (int i = 0; i < 8; i++) {
+							if ((PTR_00417214->unk1 >> 8) & (1 << i)) {
+								//DAT_004173ec = (i & 3) + ivr8;
+								int fncid = ((i & 3) + ivr8) & 3;
+								if (i > 3)
+									fncid += 4;
+								
+								DAT_004177ff = false;
+								_preprocDataId = fncid;
+								int32 res = ProcessScript(false, scr.data.data(), scr.data.size(), scr.codes1, scr.codes2);
+
+								if (_needReload)
+									return false;
+
+								if (res != 0) {
+									if (res != 1) {
+										if (DAT_00412204) {
+											DAT_00412204 = nullptr;
+											goto exit;
+										}
+										FUN_0040255c(pobj);
+										goto continue_to_next_object;
+									}
+									if (!DAT_004177ff) {
+										if (DAT_00412204) {
+											DAT_00412204 = nullptr;
+											goto exit;
+										}
+										goto continue_to_next_object;
+									}
+									tmp = true;
+									break;
+								}
+							}
+						}
+
+						if (scr.data[0] & 0x80) {
+							if (tmp) {
+								DAT_00412204 = pobj;
+								goto exit;
+							}
+
+							if (DAT_00412204) {
+								DAT_00412204 = nullptr;
+								goto exit;
+							}
+
+							break;
+						}
+					}
+				}
+			}
+		} else {
+			if (!PTR_00417388 && (pobj->flags & 0x83) == 0x81 && pobj->pos == -1 && pobj->blk == -1)
+				FUN_00402f34(true, false, pobj);
+		}
+continue_to_next_object:
+	}
+
+exit:
+	PTR_00417218 = nullptr;
+	_curObjIndex = -1;
+	return true;
+}
+
+bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
+	uint8 v = obj->fld_2 & 0xff;
+	if (v < 2) {
+		if (p2 || (obj->flags & 4)) {
+			addDirtRectOnObject(obj);
+			if (p1)
+				removeObject(obj);
+			return true;
+		}
+	} else {
+		addDirtRectOnObject(obj);
+		obj->actID++;
+		if (obj->actID == v) {
+			obj->actID = 0;
+			obj->pImg = obj->pImg - (v - 1);
+			if (p2 || (obj->flags & 4)) {
+				addDirtRectOnObject(obj);
+				if (p1)
+					removeObject(obj);
+				return true;
+			}
+		} else {
+			obj->pImg++;
+		}
+
+		if ((obj->flags & 0x40) == 0)
+			FUN_0040921c(obj);
+		
+		addDirtRectOnObject(obj);
+	}
+	return 0;
+}
+
+void GamosEngine::FUN_0040921c(Object *obj) {
+	ImagePos *imgPos = obj->pImg;
+	Image *img = imgPos->image;
+
+	int32 x = obj->fld_4 * _unk2; 
+	int32 y = obj->fld_5 * _unk3; 
+
+	if (obj->pos != 255 && obj->blk != 255) {
+		Object *o = &_drawElements[(obj->blk * 0x100) + obj->pos];
+		if (o->flags & 4) {
+			int t = obj->actID + 1;
+			x += (o->pos - obj->fld_4) * _unk2 * t / (obj->fld_2 & 0xFF);
+			y += (o->blk - obj->fld_5) * _unk3 * t / (obj->fld_2 & 0xFF);
+		}
+	}
+
+	if (obj->flags & 8) 
+		obj->x = x - (img->surface.w - _unk2 - imgPos->xoffset);
+	else
+		obj->x = x - imgPos->xoffset;
+	
+	if (obj->flags & 0x10) 
+		obj->y = y - (img->surface.h - _unk3 - imgPos->yoffset);
+	else
+		obj->y = y - imgPos->yoffset;
+}
+
+void GamosEngine::addDirtRectOnObject(Object *obj) {
+	ImagePos *imgPos = obj->pImg;
+	Common::Rect rect;
+	rect.left = obj->x;
+	rect.top = obj->y;
+	if (obj->flags & 0x40) {
+		rect.left -= imgPos->xoffset;
+		rect.top -= imgPos->yoffset;
+	}
+	rect.right = rect.left + imgPos->image->surface.w;
+	rect.bottom = rect.top + imgPos->image->surface.h;
+
+	addDirtyRect(rect);
+}
+
+void GamosEngine::addDirtyRect(const Common::Rect &rect) {
+	if (_dirtyRects.empty()) {
+		_dirtyRects.push_back(rect);
+		return;
+	}
+
+	int flags = 0;
+
+	for(int i = 0; i < _dirtyRects.size(); i++) {
+		Common::Rect &r = _dirtyRects[i];
+		if (!rect.intersects(r))
+			continue;
+		
+		flags |= 1;
+		
+		if (rect.left < r.left) {
+			r.left = rect.left;
+			flags |= 2;
+		}
+		if (rect.right > r.right) {
+			r.right = rect.right;
+			flags |= 2;
+		}
+		if (rect.top < r.top) {
+			r.top = rect.top;
+			flags |= 2;
+		}
+		if (rect.bottom > r.bottom) {
+			r.bottom = rect.bottom;
+			flags |= 2;
+		}
+		break;
+	}
+
+	if (flags == 0) {
+		_dirtyRects.push_back(rect);
+		return;
+	}
+	
+	if ( !(flags & 2) )
+		return;
+	
+	rerunCheck:
+	for(int i = _dirtyRects.size() - 2; i > 0; i--) {
+		for (int j = _dirtyRects.size() - 1; j > i; j--) {
+			Common::Rect &r1 = _dirtyRects[i];
+			Common::Rect &r2 = _dirtyRects[j];
+			if (!r1.intersects(r2))
+				continue;
+			
+			r1.extend(r2);
+			_dirtyRects.remove_at(j);
+			goto rerunCheck;
+		}
+	}
+}
+
+void GamosEngine::doDraw() {
+	if (_dirtyRects.empty())
+		return;
+
+	int32 bkg = _readingBkgMainId;
+	if (bkg == -1)
+		bkg = 0;
+	
+	Common::Array<Object *> drawList( 1024 );//_drawElements.size(), 1024) );
+	
+	int cnt = 0;
+	for (int i = 0; i < _drawElements.size(); i++) {
+		Object &obj = _drawElements[i];
+		if ((obj.flags & 0x83) == 0x81) {
+			drawList[cnt] = &obj;
+			cnt++;
+		}
+	}
+
+	if (_unk9 == 0 /*&& */) {
+		/*drawList[cnt] = &_cursorObject;
+		cnt++;*/
+	}
+	
+	drawList.resize(cnt);
+
+	if (cnt) {
+		for (int i = 0; i < drawList.size() - 1; i++) {
+			for (int j = i + 1; j < drawList.size(); j++) {
+				Object *o1 = drawList[i];
+				Object *o2 = drawList[j];
+				if ((o1->fld_2 & 0xff00) < (o2->fld_2 & 0xff00)) {
+					drawList[i] = o2;
+					drawList[j] = o1;
+				}
+			}
+		}
+	}
+
+	/* add mouse cursor here*/
+
+	for (int i = 0; i < _dirtyRects.size(); i++) {
+		Common::Rect &r = _dirtyRects[i];
+
+		if (_bkgImages[bkg].loaded) {
+			_screen->blitFrom(_bkgImages[bkg].surface, r, r);
+		}
+		_screen->addDirtyRect(r);
+	}
+
+	for(Object *o: drawList) {
+		if (o->pImg && loadImage(o->pImg->image))
+			_screen->blitFrom(o->pImg->image->surface, Common::Point(o->x, o->y));
+	}
+
+	_screen->update();
+}
+
+bool GamosEngine::loadImage(Image *img) {
+	if (img->loaded)
+		return true;
+	
+	if (img->offset < 0)
+		return false;
+	
+	_arch.seek(img->offset, 0);
+	
+	img->rawData.resize((img->surface.w * img->surface.h + 16) & ~0xf);
+
+	if (img->cSize == 0) {
+		_arch.read(img->rawData.data(), img->surface.w * img->surface.h);
+		img->surface.setPixels(img->rawData.data());
+	} else {
+		RawData tmp(img->cSize);
+		_arch.read(tmp.data(), tmp.size());
+		_arch.decompress(&tmp, &img->rawData);
+		img->surface.setPixels(img->rawData.data() + 4);
+	}
+
+	img->surface.format = Graphics::PixelFormat::createFormatCLUT8();
+	img->loaded = true;
+	return true;
+}
+
+uint32 GamosEngine::doScript(uint32 scriptAddress) {
+	_vm.EBX = PTR_004173e8;
+	return _vm.doScript(scriptAddress);
 }
 
+
+uint32 GamosEngine::vmCallDispatcher(void *engine, VM *vm, uint32 funcID) {
+	GamosEngine *gamos = (GamosEngine *)engine;
+
+	uint32 arg1 = 0, arg2 = 0, arg3 = 0;
+	
+	switch (funcID)
+	{
+	case 0:
+		gamos->DAT_004177ff = true;
+		return 1;
+	case 3:
+		printf("func 3 %x check 0x10 \n", gamos->PTR_00417218->fld_4 & 0x90);
+		return (gamos->PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
+	case 4:
+		printf("func 4 %x check 0x20 \n", gamos->PTR_00417218->fld_4 & 0xa0);
+		return (gamos->PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0;
+	case 5:
+		arg1 = vm->pop32();
+		//printf("func 5 %x check %x \n", gamos->PTR_00417218->fld_4 & 0xb0, arg1);
+		return (gamos->PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0;
+	case 6:
+		arg1 = vm->pop32();
+		printf("func 6 %x check %x \n", gamos->PTR_00417218->fld_4 & 0x4f, arg1);
+		return (gamos->PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
+	case 13: {
+		VM::Reg regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef.ref, regRef.val);
+		printf("CallDispatcher 13 keycode %s\n", str.c_str());
+		return 0;
+	}
+	
+	case 14:
+		arg1 = vm->pop32();
+		gamos->loadModule(arg1);
+		gamos->setNeedReload();
+		return 1;
+
+	case 15:
+		arg1 = vm->pop32(); //implement
+		break;
+
+	case 16:
+		arg1 = vm->pop32();
+		return gamos->scriptFunc16(arg1);
+
+	case 19:
+		arg1 = vm->pop32();
+		return gamos->scriptFunc19(arg1);
+
+	case 31:
+		arg1 = vm->pop32();
+		gamos->setCursor(arg1, true);
+		return 1;
+	
+	default:
+		break;
+	}
+	printf("Call Dispatcher %d\n", funcID);
+	return 0;
+}
+
+uint32 GamosEngine::scriptFunc19(uint32 id) {
+	BYTE_004177fc = 1;
+	FUN_0040738c(id, DAT_00417220 * _unk2, DAT_00417224 * _unk3, false);
+
+	return 1;
+}
+
+uint32 GamosEngine::scriptFunc16(uint32 id) {
+	if (DAT_004177f8 == 0) {
+		stopMidi();
+		if (_enableMidi) {
+			_midiTrack = id;
+			if (id >= _midiTracks.size())
+				return 0;
+
+			return playMidi(&_midiTracks[id]) ? 1 : 0;
+		}
+	}
+	return 1;
+}
+
+
+bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
+	Sprite &spr = _sprites[id];
+	Object *pobj = getFreeObject();
+
+	pobj->flags |= 0x80;
+
+	if (spr.field_1 & 1)
+		pobj->flags |= 4;
+	
+	pobj->fld_2 = (pobj->fld_2 & 0xFF00) | spr.field_3;
+	int32 idx = 0xffff;
+	if (!p)
+		idx = _curObjIndex;
+	
+	pobj->pos = idx & 0xff;
+	pobj->blk = (idx >> 8) & 0xff;
+	pobj->x = x;
+	pobj->y = y;
+
+	if (!p) {
+		if (!PTR_00417218) {
+			pobj->fld_2 = (pobj->fld_2 & 0xff) | (((PTR_00417214->unk1 >> 2) & 0xFF) << 8);
+		} else {
+			int32 index = pobj->index;
+			if (PTR_00417218->y != -1) {
+				Object *oobj = &_drawElements[PTR_00417218->y];
+				addDirtRectOnObject(oobj);
+				oobj->flags &= 0x7f;
+				if (PTR_00417218->x != PTR_00417218->y)
+					removeObject(oobj);
+			}
+
+			PTR_00417218->y = index;
+			if (!(pobj->flags & 4)) {
+				if (PTR_00417218->x != -1)
+					removeObject(&_drawElements[PTR_00417218->x]);
+				PTR_00417218->x = index;
+			}
+
+			pobj->fld_2 = (pobj->fld_2 & 0xff) | ((PTR_00417218->fld_5) << 8);
+			if (DAT_00417220 != DAT_00417228 || DAT_00417224 != DAT_0041722c) {
+				PTR_00417218->flags |= 4;
+			}
+		}
+	} else {
+		pobj->fld_4 = 0xff;
+		pobj->fld_5 = 0xff;
+		pobj->fld_2 = (pobj->fld_2 & 0xff) | ((PTR_00417218->fld_5) << 8);
+	}
+
+	FUN_00409378(&spr, pobj, p);
+	return true;
+}
+
+void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
+	obj->flags &= ~0x18;
+	obj->actID = 0;
+	obj->spr = spr;
+
+	if (spr->field_2 == 1) {
+		obj->pImg = &spr->sequences[0][0];
+		if (BYTE_004177f6 == 0x80) {
+			if (spr->field_1 & 2) 
+				obj->flags |= 8;
+		} else if (BYTE_004177f6 == 0x40 && (spr->field_1 & 4)) {
+			obj->flags |= 0x10;
+		}
+	} else {
+		int frm = 0;
+		if (BYTE_004177f6 == 0x10) {
+			frm = 1;
+			if (DAT_00417224 == DAT_0041722c && (spr->field_1 & 8))
+				frm = 0;
+		} else if (BYTE_004177f6 == 0x20) {
+			frm = 3;
+			if (DAT_0041722c < DAT_00417224)
+				frm = 2;
+			else if (DAT_0041722c > DAT_00417224) {
+				frm = 4;
+				if (spr->field_1 & 4) {
+					frm = 2;
+					obj->flags |= 0x10;
+				}
+			} else if (DAT_00417220 == DAT_00417228 && (spr->field_1 & 8))
+				frm = 0;
+		} else if (BYTE_004177f6 == 0x40) {
+			frm = 5;
+			if (DAT_00417224 == DAT_0041722c && (spr->field_1 & 8))
+				frm = 0;
+			else if (spr->field_1 & 4) {
+				frm = 1;
+				obj->flags |= 0x10;
+			}
+		} else {
+			frm = 7;
+			if (DAT_00417224 == DAT_0041722c) {
+				if ((spr->field_1 & 8) && DAT_00417220 == DAT_00417228)
+					frm = 0;
+				else if (spr->field_1 & 2) {
+					frm = 3;
+					obj->flags |= 8;
+				}
+			} else {
+				if (DAT_0041722c < DAT_00417224) {
+					frm = 8;
+					if (spr->field_1 & 2) {
+						frm = 2;
+						obj->flags |= 8;
+					} 
+				} else {
+					frm = 6;
+					if (spr->field_1 & 4) {
+						frm = 8;
+						obj->flags |= 0x10;
+
+						if (spr->field_1 & 2) {
+							frm = 2;
+							obj->flags |= 8;
+						} 
+					} else if (spr->field_1 & 2) {
+						frm = 4;
+						obj->flags |= 8;
+					}
+				}
+			}
+		}
+
+		obj->pImg = &spr->sequences[frm][0];
+	}
+	if (!p) {
+		obj->fld_4 = DAT_00417228;
+		obj->fld_5 = DAT_0041722c;
+		FUN_0040921c(obj);
+	} else {
+		obj->flags |= 0x40;
+	}
+
+	addDirtRectOnObject(obj);
+}
+
+void GamosEngine::FUN_004095a0(Object *obj) {
+	if (obj->y != -1) {
+		Object &yobj = _drawElements[obj->y];
+		Sprite *spr = yobj.spr; //FUN_00409568
+		addDirtRectOnObject(&yobj);
+		if (DAT_00417228 != DAT_00417220 || DAT_0041722c != DAT_00417224)
+			obj->flags |= 4;
+		FUN_00409378(spr, &yobj, false);
+	}
+}
+
+void GamosEngine::FUN_004023d8(Object *obj) {
+	if (obj->fld_2 & 0x200) {
+		obj->fld_2 &= ~0x200;
+		int32 index = obj->index;
+		for (int index = obj->index; index < _drawElements.size(); index++) {
+			Object *pobj = &_drawElements[index];
+			if ((pobj->flags & 0xe3) == 0xe1 && ((pobj->blk << 8) | pobj->pos) == obj->index)
+				removeObjectMarkDirty(pobj);
+		}
+	}
+}
+
+void GamosEngine::FUN_0040255c(Object *obj) {
+	if (obj == PTR_004121b4) {
+		PTR_004121b4 = nullptr;
+		int32 n = 0;
+		for (int32 i = 0; i < _drawElements.size(); i++) {
+			Object &robj = _drawElements[i];
+			
+			if (robj.index > obj->index)
+				n++;
+			
+			if ( (robj.flags & 3) == 3 && (_someActsArr[robj.actID].unk1 & 0xff) == 3 ) {
+				if (n) {
+					PTR_004121b4 = &robj;
+					break;
+				}
+				if (!PTR_004121b4)
+					PTR_004121b4 = &robj;
+			}
+		}
+	}
+}
+
+void GamosEngine::setCursor(int id, bool dirtRect) {
+	if (_unk9 == 0) {
+		if (dirtRect && _cursorObject.spr)
+			addDirtRectOnObject(&_cursorObject);
+		
+		_mouseCursorImgId = id;
+
+		_cursorObject.spr = &_sprites[id];
+		_cursorObject.flags = 0xc1;
+		_cursorObject.fld_2 = _sprites[id].field_3; // max frames
+		_cursorObject.actID = 0; //frame
+		_cursorObject.x = 0;
+		_cursorObject.y = 0;
+		_cursorObject.pImg = &_sprites[id].sequences[0][0];
+
+		g_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(), 
+								 _cursorObject.pImg->image->surface.w,
+								 _cursorObject.pImg->image->surface.h,
+								 _cursorObject.pImg->xoffset,
+								 _cursorObject.pImg->yoffset, 0);
+	}
+}
+
+void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1) {
+	uint8 tmpb = 0;
+	if (act2 == ACT2_8f)
+		FUN_0040255c(PTR_004121b4);
+	else if (act2 == ACT2_82)
+		tmpb = 0x90;
+	else if (act2 == ACT2_83)
+		tmpb = 0xa0;
+	else if (act2 == ACT_NONE)
+		actPos = move;
+	
+	if (act1 != 0xe)
+		tmpb |= act1 | 0x40;
+	
+	//actPos +=
+	printf("Not full FUN_00402c2c\n");
+
+	Object *pobj = nullptr;
+	uint8 actT = 0;
+	uint8 pobjF5 = 0xff;
+
+	for(int i = 0; i < _drawElements.size(); i++) {
+		Object &obj = _drawElements[i];
+		if ((obj.flags & 3) == 3) {
+			SomeAction &action = _someActsArr[obj.actID];
+			uint8 tp = action.unk1 & 0xff;
+			if (tp == 1)
+				obj.fld_4 = tmpb;
+			else if (tp == 2)
+				obj.fld_4 = tmpb & 0x4f;
+			else if (tp == 3) {
+				if (&obj == PTR_004121b4)
+					obj.fld_4 = tmpb & 0x4f;
+				else
+					obj.fld_4 = 0;
+			}
+
+			if (!pobj || ((obj.fld_5 <= pobjF5) && FUN_00409600(&obj, actPos))) {
+				actT = tp;
+				pobjF5 = obj.fld_5;
+				pobj = &obj;
+			}
+		}
+	}
+
+	if (!pobj) {
+		DAT_004173f4 = actPos.x / _unk2;
+		DAT_004173f0 = actPos.y / _unk3;
+		DAT_00417803 = _thing1[DAT_004173f4 + (DAT_004173f0 << _thing1Shift)] & 0xff;
+	} else {
+		DAT_00417803 = actT;
+		if (actT == 2) {
+			if (act2 == ACT_NONE)
+				tmpb |= 0x10;
+			else if (act2 == ACT2_81)
+				tmpb |= 0x20;
+
+			pobj->fld_4 = tmpb;
+		} else if (actT == 3 && (tmpb == 0x90 || tmpb == 0xa0)) {
+			PTR_004121b4 = pobj;
+			pobj->fld_4 = tmpb;
+		}
+
+		DAT_004173f4 = pobj->pos;
+		DAT_004173f0 = pobj->blk;
+	}
+
+	DAT_00417805 = act2;
+	if (act2 == ACT2_82 || act2 == ACT2_83) {
+		DAT_004177fe = act2;
+		DAT_004177fd = DAT_00417803;
+		DAT_004173fc = DAT_004173f4;
+		DAT_004173f8 = DAT_004173f0;
+	} else {
+		if (act2 == ACT2_81)
+			DAT_004177fe = 14;
+		DAT_00417805 = 14;
+	}
+
+}
+
+void GamosEngine::FUN_00404fcc(int32 id) {
+	printf("Not implemented FUN_00404fcc\n");
+}
+
+bool GamosEngine::FUN_004033a8(Common::Point mouseMove) {
+	_cursorObject.x = mouseMove.x;
+	_cursorObject.y = mouseMove.y;
+	printf("Not implemented FUN_004033a8\n");
+	return true;
+}
+
+bool GamosEngine::FUN_004038b8() {
+	printf("Not implemented FUN_004038b8\n");
+	return true;
+}
+
+bool GamosEngine::FUN_00402bc4() {
+	printf("Not implemented FUN_00402bc4\n");
+	return true;
+}
+
+bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
+	if (obj->y == -1)
+		return false;
+	
+	Object &robj = _drawElements[obj->y];
+	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
+		return true;
+	return false;
+}
+
+
 } // End of namespace Gamos
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 76fb8329d8b..4cb6dc94a0f 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -41,7 +41,7 @@
 #include "gamos/proc.h"
 #include "gamos/music.h"
 #include "gamos/movie.h"
-
+#include "gamos/vm.h"
 
 #include "gamos/detection.h"
 #include "gamos/file.h"
@@ -59,23 +59,25 @@ enum CONFTYPE {
 
 };
 
-enum ACT2 {
-	ACT_NONE = 0xe,
-	ACT2_81 = 0x81,
-	ACT2_82 = 0x82,
-	ACT2_83 = 0x83,
-	ACT2_84 = 0x84,
-	ACT2_8f = 0x8f,
-};
 
 enum RESTYPE {
 	RESTP_F = 0xf,
 	RESTP_10 = 0x10,
 	RESTP_11 = 0x11,
 	RESTP_12 = 0x12,
+	RESTP_13 = 0x13,
 	RESTP_18 = 0x18,
 	RESTP_19 = 0x19,
 	RESTP_20 = 0x20,
+	RESTP_21 = 0x21,
+	RESTP_22 = 0x22,
+	RESTP_23 = 0x23,
+	RESTP_2A = 0x2a,
+	RESTP_2B = 0x2b,
+	RESTP_2C = 0x2c,
+	RESTP_38 = 0x38,
+	RESTP_39 = 0x39,
+	RESTP_3A = 0x3a,
 	RESTP_40 = 0x40,
 	RESTP_41 = 0x41,
 	RESTP_42 = 0x42,
@@ -92,13 +94,17 @@ struct BkgImage {
 	bool loaded = false;
 	uint32 offset = 0;
 	Graphics::Surface surface;
+	byte *palette = nullptr;
+
+	uint32 field2_0x8 = 0;
+	uint32 field3_0xc = 0;
 
 	RawData rawData;
 };
 
 struct Image {
 	bool loaded = false;
-	int32 offset = 0;
+	int32 offset = -1;
 	int32 size = 0;
 	int32 cSize = 0;
 
@@ -131,6 +137,53 @@ struct XorArg {
 	uint32 len;
 };
 
+struct Unknown1 {
+	Common::Array<byte> field_0;
+	Common::Array<byte> field_1;
+	Common::Array<byte> field_2;
+	uint32 field_3;
+};
+
+struct ScriptS {
+	Common::Array<byte> data;
+	int32 codes1 = -1;
+	int32 codes2 = -1;
+};
+
+struct SomeAction {
+	uint32 unk1;
+	int32 script1 = -1;
+	Common::Array< ScriptS > scriptS;
+	int32 script2 = -1;
+};
+
+struct Object {
+	/* additional data */
+	int16 index;
+	Sprite *spr = nullptr;
+
+	/* 80 - drawable
+	   40 -
+	   20 - 
+	   10 -
+	   8 - has storage
+	   4 - 
+	   2 - 
+	   1 - used */
+	uint8 flags = 0;
+	uint8 actID = 0;
+	uint16 fld_2 = 0;
+	uint8 fld_4 = 0;
+	uint8 fld_5 = 0;
+	uint8 pos = 0xff;
+	uint8 blk = 0xff;
+	int16 x = 0;
+	int16 y = 0;
+	ImagePos *pImg = nullptr;
+	Common::Array<byte> storage;
+};
+
+
 class GamosEngine : public Engine {
 friend class MoviePlayer;
 
@@ -179,6 +232,8 @@ private:
 
 	Common::Array<Image *> _images;
 
+	Common::Point _bkgUpdateSizes;
+
 	Common::Array<BkgImage> _bkgImages;
 
 	Common::Array<Sprite> _sprites;
@@ -186,25 +241,99 @@ private:
 	Common::Array< Common::Array<byte> >  _midiTracks;
 
 	uint32 _delayTime = 0;
+	uint32 _lastTimeStamp = 0;
 
 	Common::Array<XorArg> _xorSeq[3];
 
 	static const byte _xorKeys[32];
 
+	uint32 _seed = 1;
+
+	Object _cursorObject;
+	uint32 _mouseCursorImgId = 0;
+
 
 
 	uint8 BYTE_004177f7 = 0;
+	uint8 DAT_004177f8 = 0;
+
+
+	uint8 DAT_004177fd = 0;
+	uint8 DAT_004177fe = 0;
 
 	bool _midiStarted = false;
 
 	/* Data2 */
 
+	bool _enableMidi = false;
+	int32 _midiTrack = 0;
+
+	uint32 _readingBkgOffset = 0;
+	int32 _readingBkgMainId = -1;
+	int32 _loadedDataSize = -1;
+
 
 
 	MidiMusic _musicPlayer;
 	SystemProc _messageProc;
 	MoviePlayer _moviePlayer;
 
+	VM _vm;
+
+	uint32 _thing1Size = 0;
+	uint32 _thing1Count = 0;
+	uint32 _thing1Shift = 0;
+	Common::Array<uint16> _thing1;
+
+
+	uint8 _preprocDataId = 0;
+
+	Common::Array<Unknown1> _thing2;
+	Common::Array<SomeAction> _someActsArr;
+
+	Common::Array<Object> _drawElements;
+
+	uint8 BYTE_00412200 = 0;
+
+	Object *DAT_00412204 = nullptr;
+
+	SomeAction *PTR_00417214 = nullptr;
+	Object *PTR_00417218 = nullptr;
+	Object *PTR_004121b4 = nullptr;
+
+	uint8 BYTE_004177f6 = 0;
+	uint8 BYTE_004177fc = 0;
+	bool DAT_004177ff = false;
+	
+
+	byte *PTR_004173e8 = nullptr;	
+
+	int32 DAT_00417220 = 0;
+	int32 DAT_00417224 = 0;
+	int32 DAT_00417228 = 0;
+	int32 DAT_0041722c = 0;
+
+	byte *PTR_00417388 = nullptr;
+
+	int32 _curObjIndex = 0;
+
+	bool DAT_00417802 = false;
+
+
+	int32 DAT_004173f0 = 0;
+	int32 DAT_004173f4 = 0;
+	int32 DAT_004173f8 = 0;
+	int32 DAT_004173fc = 0;
+	uint8 DAT_00417803 = 0;
+
+	uint8 DAT_00417805 = 0;
+
+	uint16 RawKeyCode = 0;
+
+	Common::Array<Common::Rect> _dirtyRects;
+
+	bool _needReload = false;
+
 private:
 	static const uint16 _winkeyMap[256];
 	
@@ -244,8 +373,10 @@ protected:
 
 	bool loadRes52(int32 id, const byte *data, size_t dataSize);
 
+	bool loadRes18(int32 id, const byte *data, size_t dataSize);
+
 
-	void playMidi(Common::Array<byte> *buffer);
+	bool playMidi(Common::Array<byte> *buffer);
 
 	void stopMidi();
 	void stopMCI();
@@ -253,7 +384,9 @@ protected:
 
 	bool playIntro();
 
-	bool scriptFunc18(int id);
+	bool scriptFunc18(uint32 id);
+	uint32 scriptFunc19(uint32 id);
+	uint32 scriptFunc16(uint32 id);
 
 	void setErrMessage(const Common::String &msg);
 
@@ -261,6 +394,86 @@ protected:
 
 	void readData2(const RawData &data);
 
+	uint8 update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow);
+
+	int32 ProcessScript(bool p1, const byte *data, size_t dataSize, int32 code1 = -1, int32 code2 = -1);
+
+	void FUN_00404fcc(int32 id);
+
+	uint32 getU32(const void *ptr);
+
+	void preprocessData(int id, byte *data);
+	void preprocessDataB1(int id, byte *data);
+	int processData(int id, byte *data);
+
+	void executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, SomeAction *act, int32 scriptAddr);
+
+	void FUN_0040283c(int id, int pos, const byte *data);
+
+	void FUN_00402654(int mode, int id, int pos);
+
+	Object *getFreeObject();
+	void removeObject(Object *obj);
+	void removeObjectMarkDirty(Object *obj);
+	void removeObjectByIDMarkDirty(int32 id);
+
+	void FUN_004023d8(Object *obj);
+	void FUN_0040255c(Object *obj);
+
+	bool FUN_00402fb4();
+
+	bool FUN_004033a8(Common::Point mouseMove);
+	bool FUN_004038b8();
+	bool FUN_00402bc4();
+	bool FUN_00402f34(bool p1, bool p2, Object *obj);
+
+	void FUN_0040921c(Object *obj);
+	void addDirtRectOnObject(Object *obj);
+	void addDirtyRect(const Common::Rect &rect);
+
+	void doDraw();
+
+	bool loadImage(Image *img);
+
+	uint32 doScript(uint32 scriptAddress);
+
+	bool FUN_0040738c(uint32 id, int32 x, int32 y, bool p);
+
+	void FUN_00409378(Sprite *spr, Object *obj, bool p);
+
+	void FUN_004095a0(Object *obj);
+
+	bool playMovie(int id);
+
+	void setCursor(int id, bool dirtRect);
+
+	void FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1);
+	bool FUN_00409600(Object *obj, Common::Point pos);
+
+	void setNeedReload() {
+		_needReload = true;
+		_vm._interrupt = true;
+	};
+
+	static uint32 vmCallDispatcher(void *engine, VM *vm, uint32 funcID);
+	
+public:
+
+	inline void rndSeed(uint32 seed) {
+		_seed = seed * 0x41c64e6d + 0x3039;
+	}
+
+	inline uint32 rnd() {
+		uint32 val = _seed;
+		_seed = _seed * 0x41c64e6d + 0x3039;
+		return val;
+	}
+
+	inline uint16 rndRange16(uint32 range) {
+		uint16 percent = _seed >> 16;
+		_seed = _seed * 0x41c64e6d + 0x3039;
+		return (percent * range) >> 16;
+	}
 
 public:
 	Graphics::Screen *_screen = nullptr;
diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
index d65d1a944e2..66c4a6919e9 100644
--- a/engines/gamos/module.mk
+++ b/engines/gamos/module.mk
@@ -8,7 +8,8 @@ MODULE_OBJS = \
 	keycodes.o \
 	music.o \
 	proc.o \
-	movie.o 
+	movie.o \
+	vm.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_GAMOS), DYNAMIC_PLUGIN)
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 9c703d729d7..08d6f82e80c 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -392,8 +392,7 @@ int MoviePlayer::proccessMidiChunk() {
         return 0;
     }
 
-    _gamos->playMidi(&_midiBuffer);
-    _midiStarted = true;
+    _midiStarted = _gamos->playMidi(&_midiBuffer);
 
     return 1;
 }
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index 373250ed675..809b297b7e9 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -33,6 +33,8 @@ MidiMusic::MidiMusic() {
 }
 
 MidiMusic::~MidiMusic() {
+    g_system->getTimerManager()->removeTimerProc(_timerProc);
+
     if (_driver) {
         _driver->stopAllNotes(true);
         _driver->close();
@@ -50,30 +52,33 @@ void MidiMusic::stopMusic() {
     }
 }
 
-void MidiMusic::playMusic(Common::Array<byte> *midiData) {
+bool MidiMusic::playMusic(Common::Array<byte> *midiData) {
     stopMusic();
 
     if (!midiData || midiData->size() <= 4)
-        return;
+        return false;
 
-    if (_mutex.lock()) {
-        _pMidiData.clear();
-        _pMidiData.swap(*midiData);
+    if (!_mutex.lock())
+        return false;
 
-        _dataPos = 4;
-        _midiDelayTicks = 1;
-        _midiDelayCount = 1;
+    _pMidiData.clear();
+    _pMidiData.swap(*midiData);
 
-        if (_pMidiData[_dataPos] == 0xf8) {
-            _dataPos++;
-            midi2low();
-            _dataPos++;
-        }
+    _dataStart = 4;
+    _dataPos = _dataStart;
+    _midiDelayTicks = 1;
+    _midiDelayCount = 1;
 
-        g_system->getTimerManager()->installTimerProc(_timerProc, 10 * 1000, this, "Gamos::Music");
-
-        _mutex.unlock();
+    if (_pMidiData[_dataPos] == 0xf8) {
+        _dataPos++;
+        midi2low();
+        _dataPos++;
     }
+
+    g_system->getTimerManager()->installTimerProc(_timerProc, 10 * 1000, this, "Gamos::Music");
+
+    _mutex.unlock();
+    return true;
 }
 
 void MidiMusic::update() {
diff --git a/engines/gamos/music.h b/engines/gamos/music.h
index 68be61815bd..186b7931484 100644
--- a/engines/gamos/music.h
+++ b/engines/gamos/music.h
@@ -55,7 +55,7 @@ public:
   ~MidiMusic();
 
   void stopMusic();
-  void playMusic(Common::Array<byte> *midiData);
+  bool playMusic(Common::Array<byte> *midiData);
   void update();
   int16 midi2low();
 
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index c095bc93eda..17d2d884c79 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -28,6 +28,8 @@ void SystemProc::processMessage(const Common::Event &ev) {
 	case Common::EVENT_KEYDOWN:
 		if ((_gd2flags & 1) == 0)
 			return;
+		
+		_ascii = ev.kbd.ascii;
 
 		if (ev.kbd.keycode == _keyCodes[0])
 			_act1 = 0;
@@ -54,22 +56,52 @@ void SystemProc::processMessage(const Common::Event &ev) {
 				_act2 = ACT2_8f;
 			else if (ev.kbd.keycode == _keyCodes[11])
 				_act2 = ACT2_84;
+			else 
+				return;
 
+			_rawKeyCode = ev.kbd.keycode;
 			return;
 		}
 
 		if ((_act1 < 8) && (ev.kbd.flags & Common::KBD_SHIFT))
 			_act1 |= 8;
 
-		_mouseAct = _mouseReported;
+		_mouseActPos = _mouseReportedPos;
 		break;
 	
 	case Common::EVENT_MOUSEMOVE:
-		if ((_gd2flags & 1) == 0)
+		if ((_gd2flags & 2) == 0)
 			return;
 
-		_mouseReported = ev.mouse;
+		_mouseReportedPos = ev.mouse;
+		
+		break;
+	
+	case Common::EVENT_LBUTTONDOWN:
+	case Common::EVENT_RBUTTONDOWN:
+		if ((_gd2flags & 2) == 0)
+			return;
+		
+		_mouseActPos = ev.mouse;
+		_act2 = ACT2_81;		
+		break;
+	
+	case Common::EVENT_LBUTTONUP:
+		if ((_gd2flags & 2) == 0)
+			return;
+		
+		_mouseActPos = ev.mouse;
+		_act2 = ACT2_82;
+		_rawKeyCode = _keyCodes[8];
+		break;
+	
+	case Common::EVENT_RBUTTONUP:
+		if ((_gd2flags & 2) == 0)
+			return;
 		
+		_mouseActPos = ev.mouse;
+		_act2 = ACT2_83;
+		_rawKeyCode = _keyCodes[9];
 		break;
 	
 	default:
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index a691b3e36aa..5488c4cc03a 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -27,6 +27,15 @@
 
 namespace Gamos {
 
+enum ACT2 {
+    ACT_NONE = 0xe,
+    ACT2_81 = 0x81,
+    ACT2_82 = 0x82,
+    ACT2_83 = 0x83,
+    ACT2_84 = 0x84,
+    ACT2_8f = 0x8f,
+};
+
 class SystemProc {
 public:
 
@@ -36,8 +45,12 @@ public:
     uint8 _act1 = 0;
     uint8 _act2 = 0;
 
-    Common::Point _mouseReported;
-    Common::Point _mouseAct;
+    uint16 _rawKeyCode = 0;
+    uint16 _ascii = 0;
+    
+
+    Common::Point _mouseReportedPos;
+    Common::Point _mouseActPos;
 
     uint8 _gd2flags = 0; /* 0x4 */
     uint16 _keyCodes[12]; /* 0x40 */
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
new file mode 100644
index 00000000000..4e5e2fdd064
--- /dev/null
+++ b/engines/gamos/vm.cpp
@@ -0,0 +1,941 @@
+/* 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/>.
+ *
+ */
+#define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#include <gamos/gamos.h>
+
+namespace Gamos {
+
+uint32 VM::doScript(uint32 scriptAddress) {
+    //Common::String disasm = disassembly(scriptAddress);
+
+    _interrupt = false;
+    ESI = scriptAddress;
+
+    _currentReadMemBlock = findMemoryBlock(ESI);
+    _currentWriteMemBlock = _currentReadMemBlock;
+
+    SP = 0x400;
+    _stack.resize(0x480);
+    _stackT.resize(0x480);
+
+    struct vmcmd {
+        uint32 addr;
+        OP op;
+        uint32 sp;
+    };
+
+    Common::Array<vmcmd> cmdlog;
+    
+    bool loop = true;
+    while (loop) {
+        if (_interrupt)
+            return 0;
+            
+        byte op = getMemBlockU8(ESI);
+        cmdlog.push_back({ESI, (OP)op, SP});
+        ESI++;
+
+        switch (op) {
+        default:
+        case OP_EXIT:
+            loop = false;
+            break;
+        
+        case OP_CMP_EQ:
+            if (EDX.val == EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_CMP_NE:
+            if (EDX.val != EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_CMP_LE:
+            if ((int32)EDX.val < (int32)EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_CMP_LEQ:
+            if ((int32)EDX.val <= (int32)EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+
+        case OP_CMP_GR:
+            if ((int32)EDX.val > (int32)EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_CMP_GREQ:
+            if ((int32)EDX.val >= (int32)EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_CMP_NAE:
+            if (EDX.val < EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+
+        case OP_CMP_NA:
+            if (EDX.val <= EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_CMP_A:
+            if (EDX.val > EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+
+        case OP_CMP_AE:
+            if (EDX.val >= EAX.val)
+                EAX.val = 1;
+            else
+                EAX.val = 0;
+            break;
+        
+        case OP_BRANCH:
+            if (EAX.val != 0) 
+                ESI += 4;
+            else
+                ESI += (int32)getMemBlockU32(ESI);
+            break;
+        
+        case OP_JMP:
+            ESI += (int32)getMemBlockU32(ESI);
+            break;
+        
+        case OP_SP_ADD:
+            SP += (int32)getMemBlockU32(ESI);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EDI_ECX_AL:
+            ECX.val = getMemBlockU32(ESI);
+            setMem8(REF_EDI, ECX.val, EAX.val & 0xff);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EBX_ECX_AL:
+            ECX.val = getMemBlockU32(ESI);
+            setMem8(REF_EBX, ECX.val, EAX.val & 0xff);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EDI_ECX_EAX:
+            ECX.val = getMemBlockU32(ESI);
+            setMem32(REF_EDI, ECX.val, EAX.val);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EBX_ECX_EAX:
+            ECX.val = getMemBlockU32(ESI);
+            setMem32(REF_EBX, ECX.val, EAX.val);
+            ESI += 4;
+            break;
+        
+        case OP_POP_ESI:
+            ESI = pop32();
+            ESI += 4; /* ? */
+            break;
+        
+        case OP_POP_ESI_ADD_ESP:
+            ECX = popReg();
+            SP += getMemBlockU32(ESI);
+            ESI = ECX.val;
+            break;
+        
+        case OP_MOV_EDX_EAX:
+            EDX = EAX;
+            break;
+        
+        case OP_ADD_EAX_EDX:
+            EAX.val += EDX.val;
+            if (EAX.ref == REF_UNK && EDX.ref != REF_UNK)
+                EAX.ref = EDX.ref;
+            break;
+
+        case OP_MUL:
+            EAX.val *= EDX.val;
+            break;
+        
+        case OP_OR:
+            EAX.val |= EDX.val;
+            break;
+        
+        case OP_XOR:
+            EAX.val ^= EDX.val;
+            break;
+        
+        case OP_AND:
+            EAX.val &= EDX.val;
+            break;
+        
+        case OP_NEG:
+            EAX.val = (uint32)(-((int32)EAX.val));
+            break;
+        
+        case OP_SAR:
+            EAX.val = (uint32)(((int32)EDX.val) >> (EAX.val & 0xff)); /* must be arythmetic shift! */
+            break;
+        
+        case OP_SHL:
+            EAX.val = EDX.val << (EAX.val & 0xff);
+            break;
+        
+        case OP_LOAD:
+            EAX.val = getMemBlockU32(ESI);
+            EAX.ref = REF_UNK;
+            ESI += 4;
+            break;
+        
+        case OP_INC:
+            EAX.val += 1;
+            break;
+
+        case OP_DEC:
+            EAX.val -= 1;
+            break;
+        
+        case OP_XCHG:
+            ECX = EAX;
+            EAX = EDX;
+            EDX = ECX;
+            break;
+
+        case OP_PUSH_EAX:
+            pushReg(EAX);
+            break;
+        
+        case OP_POP_EDX:
+            EDX = popReg();
+            break;
+
+        case OP_LOAD_OFFSET_EDI:
+        case OP_LOAD_OFFSET_EDI2:
+            EAX.val = getMemBlockU32(ESI);
+            EAX.ref = REF_EDI;
+            ESI += 4;
+            break;
+        
+        case OP_LOAD_OFFSET_EBX:
+            EAX.val = getMemBlockU32(ESI);
+            EAX.ref = REF_EBX;
+            ESI += 4;
+            break;
+        
+        case OP_LOAD_OFFSET_ESP:
+            EAX.val = getMemBlockU32(ESI) + SP;
+            EAX.ref = REF_STACK;
+            ESI += 4;
+            break;
+        
+        case OP_MOV_PTR_EDX_AL:
+            setMem8(EDX.ref, EDX.val, EAX.val & 0xff);
+            break;
+
+        case OP_MOV_PTR_EDX_EAX:
+            setMem32(EDX.ref, EDX.val, EAX.val);
+            break;
+
+        case OP_SHL_2:
+            EAX.val <<= 2;
+            break;
+        
+        case OP_ADD_4:
+            EAX.val += 4;
+            break;
+        
+        case OP_SUB_4:
+            EAX.val -= 4;
+            break;
+
+        case OP_XCHG_ESP:
+            ECX = popReg();
+            pushReg(EAX);
+            EAX = ECX;
+            break;
+
+        case OP_NEG_ADD:
+            EAX.val = (uint32)(-((int32)EAX.val)) + EDX.val;
+            break;
+        
+        case OP_DIV:
+            ECX = EAX;
+            EAX.val = EDX.val / ECX.val;
+            EDX.val = EDX.val % ECX.val;
+            break;
+        
+        case OP_MOV_EAX_BPTR_EDI:
+            ECX.val = getMemBlockU32(ESI);
+            EAX.val = (int8)getMem8(REF_EDI, ECX.val);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EAX_BPTR_EBX:
+            ECX.val = getMemBlockU32(ESI);
+            EAX.val = (int8)getMem8(REF_EBX, ECX.val);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EAX_DPTR_EDI:
+            ECX.val = getMemBlockU32(ESI);
+            EAX.val = getMem32(REF_EDI, ECX.val);
+            ESI += 4;
+            break;
+        
+        case OP_MOV_EAX_DPTR_EBX:
+            ECX.val = getMemBlockU32(ESI);
+            EAX.val = getMem32(REF_EBX, ECX.val);
+            ESI += 4;
+            break;
+
+        case OP_MOV_EAX_BPTR_EAX:
+            EAX.val = (int8)getMem8(EAX.ref, EAX.val);
+            EAX.ref = REF_UNK;
+            break;
+        
+        case OP_MOV_EAX_DPTR_EAX:
+            EAX.val = getMem32(EAX.ref, EAX.val);
+            EAX.ref = REF_UNK;
+            break;
+        
+        case OP_PUSH_ESI_ADD_EDI:
+            push32(ESI);
+            ESI = getMemBlockU32(ESI);
+            break;
+
+        case OP_CALL_FUNC:
+            EAX.val = getMemBlockU32(ESI);
+            ESI += 4;
+            if (_callFuncs)
+                EAX.val = _callFuncs(_callingObject, this, EAX.val);
+            // call funcs[ EAX ]
+            break;
+        
+        case OP_PUSH_ESI_SET_EDX_EDI:
+            push32(ESI);
+            ESI = EDX.val; // + EDI ?
+            break;
+        }
+    }
+
+    return EAX.val;
+}
+
+int32 VM::getS32(const void *mem) {
+    const uint8 *mem8 = (const uint8 *)mem;
+    return (int32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
+}
+
+uint32 VM::getU32(const void *mem) {
+    const uint8 *mem8 = (const uint8 *)mem;
+    return (uint32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
+}
+
+void VM::setU32(void *mem, uint32 val) {
+    uint8 *mem8 = (uint8 *)mem;
+    mem8[0] = val & 0xff;
+    mem8[1] = (val >> 8) & 0xff;
+    mem8[2] = (val >> 16) & 0xff;
+    mem8[3] = (val >> 24) & 0xff;
+}
+
+void VM::push32(uint32 val) {
+    SP -= 4;
+    setU32(_stack.data() + SP, val);
+}
+
+uint32 VM::pop32() {
+    uint32 val = getU32(_stack.data() + SP);
+    SP += 4;
+    return val;
+}
+
+void VM::pushReg(Reg reg) {
+    SP -= 4;
+    setU32(_stack.data() + SP, reg.val);
+    _stackT[SP] = reg.ref;
+}
+
+VM::Reg VM::popReg() {
+    Reg tmp;
+    tmp.val = getU32(_stack.data() + SP);
+    tmp.ref = _stackT[SP];
+    SP += 4;
+    return tmp;
+}
+
+uint32 VM::getMem32(int memtype, uint32 offset) {
+    switch (memtype) {
+    default:
+    case REF_UNK:
+        return 0;
+    
+    case REF_STACK:
+        return getU32(_stack.data() + offset);
+    
+    case REF_EBX:
+        return getU32(EBX + offset);
+    
+    case REF_EDI:
+        return getMemBlockU32(offset);
+    }
+}
+
+uint8 VM::getMem8(int memtype, uint32 offset) {
+    switch (memtype) {
+    default:
+    case REF_UNK:
+        return 0;
+    
+    case REF_STACK:
+        return _stack[offset];
+    
+    case REF_EBX:
+        return EBX[offset];
+    
+    case REF_EDI:
+        return getMemBlockU8(offset);
+    }
+}
+
+void VM::setMem32(int memtype, uint32 offset, uint32 val) {
+    switch (memtype) {
+    default:
+    case REF_UNK:
+        break;
+    case REF_STACK:
+        setU32(_stack.data() + offset, val);
+        break;
+    case REF_EBX:
+        setU32(EBX + offset, val);
+        break;
+    
+    case REF_EDI:
+        setMemBlockU32(offset, val);
+        break;
+    }
+}
+
+void VM::setMem8(int memtype, uint32 offset, uint8 val) {
+    switch (memtype) {
+    default:
+    case REF_UNK:
+        break;
+    case REF_STACK:
+        _stack[offset] = val;
+        break;
+    case REF_EBX:
+        EBX[offset] = val;
+        break;
+    
+    case REF_EDI:
+        setMemBlockU8(offset, val);
+        break;
+    }
+}
+
+void VM::clearMemory() {
+    _memMap.clear();
+    _currentReadMemBlock = nullptr;
+    _currentWriteMemBlock = nullptr;
+}
+
+void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
+
+    uint32 blockAddr = address & (~0xff);
+    uint32 pos = 0;
+    uint32 remain = dataSize;
+
+    printf("Write memory at %x sz %x\n", address, dataSize);
+    
+    for (uint32 addr = blockAddr; addr < address + dataSize; addr += 0x100) {
+        MemoryBlock &block = _memMap.getOrCreateVal(addr);
+
+        block.address = addr; // update it 
+
+        uint32 copyCnt = (addr + 0x100) - (address + pos); 
+        if (copyCnt > remain)
+            copyCnt = remain;
+
+        uint32 blockPos = (address + pos) - addr;
+        memcpy(block.data + blockPos, data + pos, copyCnt);
+
+        pos += copyCnt;
+        remain -= copyCnt;
+    }
+}
+
+VM::MemoryBlock *VM::findMemoryBlock(uint32 address) {
+    Common::HashMap<uint32, MemoryBlock>::iterator it = _memMap.find(address & (~0xff));
+    if (it == _memMap.end())
+        return nullptr;
+    
+    return &it->_value;
+}
+
+uint8 VM::getMemBlockU8(uint32 address) {
+    if (!_currentReadMemBlock || address < _currentReadMemBlock->address || address >= (_currentReadMemBlock->address + 0x100))
+        _currentReadMemBlock = findMemoryBlock(address);
+    
+    if (!_currentReadMemBlock)
+        return 0; // ERROR!
+    
+    return _currentReadMemBlock->data[ address - _currentReadMemBlock->address ];
+}
+
+uint32 VM::getMemBlockU32(uint32 address) {
+    if (!_currentReadMemBlock || address < _currentReadMemBlock->address || address >= (_currentReadMemBlock->address + 0x100))
+        _currentReadMemBlock = findMemoryBlock(address);
+    
+    if (!_currentReadMemBlock)
+        return 0; // ERROR!
+    
+    uint32 pos = address - _currentReadMemBlock->address;
+    if (0x100 - pos >= 4)
+        return getU32(_currentReadMemBlock->data + pos); //easy
+
+    MemoryBlock *block = _currentReadMemBlock;
+    uint32 val = block->data[ pos ];
+    pos++;
+    for (int i = 1; i < 4; i++) {
+        if (pos > 0x100) {
+            block = findMemoryBlock(address + i);
+            if (!block)
+                break;
+            pos = (address + i) - block->address;
+        }
+        val |= block->data[ pos ] << (i * 8);
+    }
+
+    return val;
+}
+
+VM::MemoryBlock *VM::createBlock(uint32 address) {
+    MemoryBlock &blk = _memMap.getOrCreateVal(address & (~0xff));
+    blk.address = address & (~0xff);
+    return &blk;
+}
+
+void VM::setMemBlockU8(uint32 address, uint8 val) {
+    if (!_currentWriteMemBlock || address < _currentWriteMemBlock->address || address >= (_currentWriteMemBlock->address + 0x100))
+        _currentWriteMemBlock = findMemoryBlock(address);
+
+    if (!_currentWriteMemBlock)
+        _currentWriteMemBlock = createBlock(address);
+
+    _currentWriteMemBlock->data[ address - _currentWriteMemBlock->address ] = val;
+}
+
+void VM::setMemBlockU32(uint32 address, uint32 val) {
+    if (!_currentWriteMemBlock || address < _currentWriteMemBlock->address || address >= (_currentWriteMemBlock->address + 0x100))
+        _currentWriteMemBlock = findMemoryBlock(address);
+
+    if (!_currentWriteMemBlock)
+        _currentWriteMemBlock = createBlock(address);
+
+    uint32 pos = address - _currentWriteMemBlock->address;
+
+    if (address + 4 <= _currentWriteMemBlock->address + 0x100) {
+        setU32(_currentWriteMemBlock->data + pos, val);
+        return;
+    }
+    
+    _currentWriteMemBlock->data[ pos ] = val & 0xff;
+    pos++;
+
+    MemoryBlock *block = _currentWriteMemBlock;
+
+    for (int i = 1; i < 4; i++) {
+        if (pos > 0x100) {
+            block = createBlock(address + i);
+            if (!block)
+                break;
+            pos = 0;
+        }
+        block->data[ pos ] = (val >> (i * 8)) & 0xff;
+    }
+}
+
+Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
+    Common::Array<byte> data;
+    data.resize(count);
+
+    MemoryBlock *blk = _currentReadMemBlock;
+    if (!blk || address < blk->address || address >= (blk->address + 0x100))
+        blk = findMemoryBlock(address);
+    
+    uint32 pos = 0;
+    uint32 blockAddr = address & (~0xff);
+    uint32 remain = count;
+    while(remain > 0) {
+        uint32 dataCpyCount = (blockAddr + 0x100) - (address + pos);
+        if (dataCpyCount < remain)
+            dataCpyCount = remain;
+
+        if (!blk) {
+            memset(data.data() + pos, 0, dataCpyCount);
+        } else {
+            memcpy(data.data() + pos, blk->data + (address + pos - blk->address), dataCpyCount);
+        }
+        
+        pos += dataCpyCount;
+        remain -= dataCpyCount;
+        blockAddr += 0x100;
+        blk = findMemoryBlock(blockAddr);
+    }
+    return data;
+}
+
+Common::String VM::readMemString(uint32 address, uint32 maxLen) {
+    Common::String s;
+
+    MemoryBlock *blk = _currentReadMemBlock;
+    if (!blk || address < blk->address || address >= (blk->address + 0x100))
+        blk = findMemoryBlock(address);
+    
+    if (!blk)
+        return s;
+    
+    uint32 pos = address - blk->address;
+    char c = blk->data[pos];
+
+    while(c != 0) {
+        s += c;
+
+        pos++;
+        if (pos > 0x100) {
+            blk = findMemoryBlock(blk->address + 0x100);
+            pos = 0;
+        }
+
+        if (!blk)
+            break;
+        
+        c = blk->data[pos];
+    }
+    return s;
+}
+
+Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
+    switch (memtype) {
+        default:
+        case REF_UNK:
+            return Common::String();
+
+        case REF_STACK: {
+            Common::String s = Common::String((const char *)_stack.data() + offset);
+            if (s.size() > maxLen)
+                s.erase(maxLen);
+            return s;
+        }
+        case REF_EBX: {
+            Common::String s = Common::String((const char *)EBX + offset);
+            if (s.size() > maxLen)
+                s.erase(maxLen);
+            return s;
+        }
+        
+        case REF_EDI:
+            return readMemString(offset, maxLen);
+    }
+}
+
+
+Common::String VM::disassembly(uint32 address) {
+    Common::String tmp;
+
+    uint32 addr = address;
+    
+    bool loop = true;
+    while (loop) {
+        tmp += Common::String::format("%0.8x: ", addr);
+
+        byte op = getMemBlockU8(addr);
+        addr++;
+
+        switch (op) {
+        default:
+        case OP_EXIT:
+            loop = false;
+            tmp += Common::String("EXIT\n");
+            break;
+        
+        case OP_CMP_EQ:
+            tmp += Common::String("EAX =  EDX == EAX (CMP_EQ)\n");
+            break;
+        
+        case OP_CMP_NE:
+            tmp += Common::String("EAX =  EDX != EAX (CMP_NE)\n");
+            break;
+        
+        case OP_CMP_LE:
+            tmp += Common::String("EAX =  EDX < EAX (CMP_LE) //signed\n");
+            break;
+        
+        case OP_CMP_LEQ:
+            tmp += Common::String("EAX =  EDX <= EAX (CMP_LEQ) //signed\n");
+            break;
+
+        case OP_CMP_GR:
+            tmp += Common::String("EAX =  EDX > EAX (CMP_GR) //signed\n");
+            break;
+        
+        case OP_CMP_GREQ:
+            tmp += Common::String("EAX =  EDX >= EAX (CMP_GREQ) //signed\n");
+            break;
+        
+        case OP_CMP_NAE:
+            tmp += Common::String("EAX =  EDX < EAX (CMP_NAE) //unsigned\n");
+            break;
+
+        case OP_CMP_NA:
+            tmp += Common::String("EAX =  EDX <= EAX (CMP_NA) //unsigned\n");
+            break;
+        
+        case OP_CMP_A:
+            tmp += Common::String("EAX =  EDX > EAX (CMP_A) //unsigned\n");
+            break;
+
+        case OP_CMP_AE:
+            tmp += Common::String("EAX =  EDX >= EAX (CMP_AE) //unsigned\n");
+            break;
+        
+        case OP_BRANCH:
+            tmp += Common::String::format("BR %x\n", addr + (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_JMP:
+            tmp += Common::String::format("JMP %x\n", (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_SP_ADD:
+            tmp += Common::String::format("ADD SP, %x\n", (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EDI_ECX_AL:
+            tmp += Common::String::format("MOV byte ptr[EDI + %x], AL\n", (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EBX_ECX_AL:
+            tmp += Common::String::format("MOV byte ptr[EBX + %x], AL\n", (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EDI_ECX_EAX:
+            tmp += Common::String::format("MOV dword ptr[EDI + %x], EAX\n", (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EBX_ECX_EAX:
+            tmp += Common::String::format("MOV dword ptr[EBX + %x], EAX\n", (int32)getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_POP_ESI:
+            tmp += Common::String("POP ESI + 4 //RET?\n");
+            break;
+        
+        case OP_POP_ESI_ADD_ESP:
+            tmp += Common::String::format("ADD SP, %x | POP ESI\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EDX_EAX:
+            tmp += Common::String("MOV EDX, EAX\n");
+            break;
+        
+        case OP_ADD_EAX_EDX:
+            tmp += Common::String("ADD EAX, EDX\n");
+            break;
+
+        case OP_MUL:
+            tmp += Common::String("MUL EDX\n");
+            break;
+        
+        case OP_OR:
+            tmp += Common::String("OR EDX\n");
+            break;
+        
+        case OP_XOR:
+            tmp += Common::String("XOR EDX\n");
+            break;
+        
+        case OP_AND:
+            tmp += Common::String("AND EDX\n");
+            break;
+        
+        case OP_NEG:
+            tmp += Common::String("NEG EAX\n");
+            break;
+        
+        case OP_SAR:
+            tmp += Common::String("SAR EAX, EDX,EAX // edx>>eax\n");
+            break;
+        
+        case OP_SHL:
+            tmp += Common::String("SHL EAX, EDX,EAX // edx<<eax\n");
+            break;
+        
+        case OP_LOAD:
+            tmp += Common::String::format("MOV EAX, %x\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_INC:
+            tmp += Common::String("INC EAX\n");
+            break;
+
+        case OP_DEC:
+            tmp += Common::String("DEC EAX\n");
+            break;
+        
+        case OP_XCHG:
+            tmp += Common::String("XCHG EAX,EDX\n");
+            break;
+
+        case OP_PUSH_EAX:
+            tmp += Common::String("PUSH EAX\n");
+            break;
+        
+        case OP_POP_EDX:
+            tmp += Common::String("POP EDX\n");
+            break;
+
+        case OP_LOAD_OFFSET_EDI:
+        case OP_LOAD_OFFSET_EDI2:
+            tmp += Common::String::format("LEA EAX, [EDI + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_LOAD_OFFSET_EBX:
+            tmp += Common::String::format("LEA EAX, [EBX + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_LOAD_OFFSET_ESP:
+            tmp += Common::String::format("LEA EAX, [SP + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_PTR_EDX_AL:
+            tmp += Common::String("MOV byte ptr [EDX], AL\n");
+            break;
+
+        case OP_MOV_PTR_EDX_EAX:
+            tmp += Common::String("MOV dword ptr [EDX], EAX\n");
+            break;
+
+        case OP_SHL_2:
+            tmp += Common::String("SHL EAX, 2\n");
+            break;
+        
+        case OP_ADD_4:
+            tmp += Common::String("ADD EAX, 4\n");
+            break;
+        
+        case OP_SUB_4:
+            tmp += Common::String("SUB EAX, 4\n");
+            break;
+
+        case OP_XCHG_ESP:
+            tmp += Common::String("XCHG EAX, [SP]\n");
+            break;
+
+        case OP_NEG_ADD:
+            tmp += Common::String("EAX = EDX - EAX (OP_NEG_ADD)\n");
+            break;
+        
+        case OP_DIV:
+            tmp += Common::String("EAX = EDX / EAX  |   EDX = EDX %% EAX (DIV)\n");
+            break;
+        
+        case OP_MOV_EAX_BPTR_EDI:
+            tmp += Common::String::format("MOV EAX, byte ptr [EDI + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EAX_BPTR_EBX:
+            tmp += Common::String::format("MOV EAX, byte ptr [EBX + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EAX_DPTR_EDI:
+            tmp += Common::String::format("MOV EAX, dword ptr [EDI + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_MOV_EAX_DPTR_EBX:
+            tmp += Common::String::format("MOV EAX, dword ptr [EBX + %x]\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+
+        case OP_MOV_EAX_BPTR_EAX:
+            tmp += Common::String("MOV EAX, byte ptr [EAX]\n");
+            break;
+        
+        case OP_MOV_EAX_DPTR_EAX:
+            tmp += Common::String("MOV EAX, dword ptr [EAX]\n");
+            break;
+        
+        case OP_PUSH_ESI_ADD_EDI:
+            tmp += Common::String::format("CALL %x\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+
+        case OP_CALL_FUNC:
+            tmp += Common::String::format("CALL FUNC %x\n", getMemBlockU32(addr));
+            addr += 4;
+            break;
+        
+        case OP_PUSH_ESI_SET_EDX_EDI:
+            tmp += Common::String("CALL EDX\n");
+            break;
+        }
+    }
+
+    return tmp;
+}
+
+
+}
\ No newline at end of file
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
new file mode 100644
index 00000000000..7fb1ad698b4
--- /dev/null
+++ b/engines/gamos/vm.h
@@ -0,0 +1,179 @@
+/* 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/array.h>
+#include <common/hashmap.h>
+
+namespace Gamos {
+
+class Sprite;
+
+class VM {
+public:
+    enum OP{
+        OP_EXIT = 0,
+        OP_CMP_EQ = 1,
+        OP_CMP_NE = 2,
+        OP_CMP_LE = 3,
+        OP_CMP_LEQ = 4,
+        OP_CMP_GR = 5,
+        OP_CMP_GREQ = 6,
+        OP_CMP_NAE = 7,
+        OP_CMP_NA = 8,
+        OP_CMP_A = 9,
+        OP_CMP_AE = 10,
+        OP_BRANCH = 11,
+        OP_JMP = 12,
+        OP_SP_ADD = 13,
+        OP_MOV_EDI_ECX_AL = 14,
+        OP_MOV_EBX_ECX_AL = 15,
+        OP_MOV_EDI_ECX_EAX = 16,
+        OP_MOV_EBX_ECX_EAX = 17,
+        OP_POP_ESI = 18,
+        OP_POP_ESI_ADD_ESP = 19,
+        OP_MOV_EDX_EAX = 20,
+        OP_ADD_EAX_EDX = 21,
+        OP_MUL = 22,
+        OP_OR = 23,
+        OP_XOR = 24,
+        OP_AND = 25,
+        OP_NEG = 26,
+        OP_SAR = 27,
+        OP_SHL = 28,
+        OP_LOAD = 29,
+        OP_INC = 30,
+        OP_DEC = 31,
+        OP_XCHG = 32,
+        OP_PUSH_EAX = 33,
+        OP_POP_EDX = 34,
+        OP_LOAD_OFFSET_EDI = 35,
+        OP_LOAD_OFFSET_EDI2 = 36,
+        OP_LOAD_OFFSET_EBX = 37,
+        OP_LOAD_OFFSET_ESP = 38,
+        OP_MOV_PTR_EDX_AL = 39,
+        OP_MOV_PTR_EDX_EAX = 40,
+        OP_SHL_2 = 41,
+        OP_ADD_4 = 42,
+        OP_SUB_4 = 43,
+        OP_XCHG_ESP = 44,
+        OP_NEG_ADD = 45,
+        OP_DIV = 46,
+        OP_MOV_EAX_BPTR_EDI = 47,
+        OP_MOV_EAX_BPTR_EBX = 48,
+        OP_MOV_EAX_DPTR_EDI = 49,
+        OP_MOV_EAX_DPTR_EBX = 50,
+        OP_MOV_EAX_BPTR_EAX = 51,
+        OP_MOV_EAX_DPTR_EAX = 52,
+        OP_PUSH_ESI_ADD_EDI = 53,
+        OP_CALL_FUNC = 54,
+        OP_PUSH_ESI_SET_EDX_EDI = 55,
+    };
+
+    enum MEMREF {
+        REF_UNK = 0,
+        REF_STACK = 1,
+        REF_EBX = 2,
+        REF_EDI = 3
+    };
+
+    struct Reg {
+        uint32 val = 0;
+        byte ref = REF_UNK;
+    };
+
+    typedef uint32 (* CallDispatcher)(void *object, VM *state, uint32 funcID); 
+
+    struct DataSlice {
+        uint32 address = 0;
+        Common::Array<byte> data;
+    };
+
+    struct MemoryBlock {
+        uint32 address = 0;
+        byte data[256];
+
+        MemoryBlock() {
+            address = 0;
+            memset(data, sizeof(data), 0);
+        }
+    };
+
+public:
+    void clearMemory();
+    void writeMemory(uint32 address, const byte* data, uint32 dataSize);
+    MemoryBlock *findMemoryBlock(uint32 address);
+    uint8 getMemBlockU8(uint32 address);
+    uint32 getMemBlockU32(uint32 address);
+
+    MemoryBlock *createBlock(uint32 address);
+
+    void setMemBlockU8(uint32 address, uint8 val);
+    void setMemBlockU32(uint32 address, uint32 val);
+
+    Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+
+    Common::String readMemString(uint32 address, uint32 maxLen = 256);
+
+    Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
+
+    uint32 doScript(uint32 scriptAddress);
+
+    int32 getS32(const void *);
+    uint32 getU32(const void *);
+    void setU32(void *, uint32 val);
+
+    void push32(uint32 val);
+    uint32 pop32();
+
+    void pushReg(Reg reg);
+    Reg popReg();
+
+    uint32 getMem32(int memtype, uint32 offset);
+    uint8 getMem8(int memtype, uint32 offset);
+
+    void setMem32(int memtype, uint32 offset, uint32 val);
+    void setMem8(int memtype, uint32 offset, uint8 val);
+
+    Common::String disassembly(uint32 address);
+
+public:
+    uint32 ESI = 0;
+    byte *EBX = nullptr;
+    Reg EAX;
+    Reg EDX;
+    Reg ECX;
+    uint32 SP = 0;
+    Common::Array<byte> _stack;
+    Common::Array<byte> _stackT;
+
+    CallDispatcher _callFuncs = nullptr;
+    void *_callingObject = nullptr;
+
+    Common::HashMap<uint32, MemoryBlock> _memMap;
+
+    bool _interrupt = false;
+private:
+    MemoryBlock *_currentReadMemBlock = nullptr;
+    MemoryBlock *_currentWriteMemBlock = nullptr;
+};
+
+
+}
\ No newline at end of file


Commit: 44c60ebae4d12b42b70e3993f44eb86f4ea188c9
    https://github.com/scummvm/scummvm/commit/44c60ebae4d12b42b70e3993f44eb86f4ea188c9
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:14+01:00

Commit Message:
GAMOS: Fix memset() arguments

Changed paths:
    engines/gamos/vm.h


diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index 7fb1ad698b4..6fdd60acc34 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -99,7 +99,7 @@ public:
         byte ref = REF_UNK;
     };
 
-    typedef uint32 (* CallDispatcher)(void *object, VM *state, uint32 funcID); 
+    typedef uint32 (* CallDispatcher)(void *object, VM *state, uint32 funcID);
 
     struct DataSlice {
         uint32 address = 0;
@@ -112,7 +112,7 @@ public:
 
         MemoryBlock() {
             address = 0;
-            memset(data, sizeof(data), 0);
+            memset(data, 0, sizeof(data));
         }
     };
 
@@ -176,4 +176,4 @@ private:
 };
 
 
-}
\ No newline at end of file
+}


Commit: b1226329b92fdc9a53f9dce7d532b1bb8acfbd7f
    https://github.com/scummvm/scummvm/commit/b1226329b92fdc9a53f9dce7d532b1bb8acfbd7f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:14+01:00

Commit Message:
GAMOS: Fix warning

Changed paths:
    engines/gamos/vm.h


diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index 6fdd60acc34..bad9cc27494 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -24,7 +24,7 @@
 
 namespace Gamos {
 
-class Sprite;
+struct Sprite;
 
 class VM {
 public:


Commit: 578ef8b7ef7d5f90b9497b0e18189e011de5af70
    https://github.com/scummvm/scummvm/commit/578ef8b7ef7d5f90b9497b0e18189e011de5af70
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:15+01:00

Commit Message:
GAMOS: Remove superfluous semicolon

Changed paths:
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4cb6dc94a0f..7eb86d13904 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -164,11 +164,11 @@ struct Object {
 
 	/* 80 - drawable
 	   40 -
-	   20 - 
+	   20 -
 	   10 -
 	   8 - has storage
-	   4 - 
-	   2 - 
+	   4 -
+	   2 -
 	   1 - used */
 	uint8 flags = 0;
 	uint8 actID = 0;
@@ -191,11 +191,11 @@ private:
 	const ADGameDescription *_gameDescription;
 	Common::RandomSource _randomSource;
 
-	bool _errSet = false;;
+	bool _errSet = false;
 	Common::String _errMessage;
 
 	Archive _arch;
-	
+
 	byte _cmdByte;
 
 	bool _runReadDataMod;
@@ -304,9 +304,9 @@ private:
 	uint8 BYTE_004177f6 = 0;
 	uint8 BYTE_004177fc = 0;
 	bool DAT_004177ff = false;
-	
 
-	byte *PTR_004173e8 = nullptr;	
+
+	byte *PTR_004173e8 = nullptr;
 
 	int32 DAT_00417220 = 0;
 	int32 DAT_00417224 = 0;
@@ -336,7 +336,7 @@ private:
 
 private:
 	static const uint16 _winkeyMap[256];
-	
+
 protected:
 	// Engine APIs
 	Common::Error run() override;
@@ -456,7 +456,7 @@ protected:
 	};
 
 	static uint32 vmCallDispatcher(void *engine, VM *vm, uint32 funcID);
-	
+
 public:
 
 	inline void rndSeed(uint32 seed) {


Commit: 700cc69a1bb88ab4221dbc73fbf1f7890e64a82f
    https://github.com/scummvm/scummvm/commit/700cc69a1bb88ab4221dbc73fbf1f7890e64a82f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:15+01:00

Commit Message:
JANITORIAL: Remove trailing spaces

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 187b293d315..0f1dc4bfe66 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -31,7 +31,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_stdout
 
 
-#include "gamos/gamos.h" 
+#include "gamos/gamos.h"
 #include "graphics/framelimiter.h"
 #include "gamos/detection.h"
 #include "gamos/console.h"
@@ -55,9 +55,9 @@ namespace Gamos {
 GamosEngine *g_engine;
 
 
-const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c, 
-										 0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47, 
-										 0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c, 
+const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c,
+										 0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47,
+										 0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
 										 0x32, 0x57, 0xdd, 0xb2, 0x38, 0xa7, 0x95, 0x7a};
 
 GamosEngine::GamosEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
@@ -88,7 +88,7 @@ Common::Error GamosEngine::run() {
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot != -1)
 		(void)loadGameState(saveSlot);
-	
+
 	g_system->showMouse(true);
 
 	Common::String mname("solgamer.exe");
@@ -116,11 +116,11 @@ Common::Error GamosEngine::run() {
 
 			if (!result)
 				break;
-			
+
 			_messageProc._act2 = ACT_NONE;
 			_messageProc._act1 = ACT_NONE;
 			_messageProc._rawKeyCode = ACT_NONE;
-			
+
 			doDraw();
 		}
 
@@ -147,7 +147,7 @@ bool GamosEngine::loader2() {
 
 	if (_arch.readByte() != 7)
 		return false;
-	
+
 	RawData data;
 	if (!_arch.readCompressedData(&data))
 		return false;
@@ -161,7 +161,7 @@ bool GamosEngine::loader2() {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
 	while (!dataStream.eos()) {
 		byte curByte = dataStream.readByte();
-		
+
 		if (curByte == 0) {
 			break;
 		} else if (curByte == 0x80) {
@@ -180,25 +180,25 @@ bool GamosEngine::loader2() {
 			resType = 0x40;
 			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
 				return false;
-			
+
 			dataStream.skip(resSize);
 		} else if (curByte == 0x41 || curByte == 0x42) {
 			resSize = dataStream.readSint32LE();
 			resType = curByte;
 			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
 				return false;
-			
+
 			_loadedDataSize += (resSize + 3) & (~3);
-			
+
 			dataStream.skip(resSize);
 		} else if (curByte == 0x43) {
 			resSize = 0x10;
 			resType = 0x43;
 			if (!loadResHandler(resType, pid, p1, p2, 0, data.data() + dataStream.pos(), resSize))
 				return false;
-			
+
 			_loadedDataSize += (resSize + 3) & (~3);
-			
+
 			dataStream.skip(resSize);
 		} else if (curByte == 0xff) {
 			//printf("0xFF  %d %d %d \n", pid, p1, p2);
@@ -235,7 +235,7 @@ bool GamosEngine::loadModule(uint id) {
 	int32 p2 = 0;
 	int32 p3 = 0;
 	int32 pid = 0;
-	
+
 	while(doLoad) {
 		byte curByte = _arch.readByte();
 
@@ -297,11 +297,11 @@ bool GamosEngine::loadModule(uint id) {
 
 					if (!loadResHandler(prevByte, pid, p1, p2, p3, data))
 						return false;
-					
+
 				}
 
 				uint32 datasz = (data.size() + 3) & (~3);
-				
+
 				switch (prevByte) {
 					case RESTP_11:
 					case RESTP_18:
@@ -310,7 +310,7 @@ bool GamosEngine::loadModule(uint id) {
 					case RESTP_40:
 					case RESTP_50:
 						break;
-					
+
 					case RESTP_43:
 						//printf("t %x sz %x sum %x\n", prevByte, data.size(), _loadedDataSize);
 						if (_onlyScanImage)
@@ -318,28 +318,28 @@ bool GamosEngine::loadModule(uint id) {
 						else
 							_loadedDataSize += datasz;
 						break;
-					
+
 					default:
 						//printf("t %x sz %x sum %x\n", prevByte, data.size(), _loadedDataSize);
 						_loadedDataSize += datasz;
 						break;
 				}
-				
+
 				break;
 			}
 			case 5: {
 				byte t = _arch.readByte();
 				if (t == 0 || (t & 0xec) != 0xec)
 					return false;
-				
+
 				byte sz = (t & 3) + 1;
 				int32 movieSize = 0;
 				for(uint i = 0; i < sz; ++i)
 					movieSize |= _arch.readByte() << (i * 8);
-				
+
 				if (prevByte == 0x14)
 					_movieOffsets[pid] = _arch.pos();
-				
+
 				_arch.skip(movieSize);
 				break;
 			}
@@ -373,13 +373,13 @@ bool GamosEngine::loadModule(uint id) {
 		if (_readingBkgMainId == -1)
 			_screen->setPalette(_bkgImages[0].palette);
 			//FUN_00405ebc(0, false);
-		else 
+		else
 			_screen->setPalette(_bkgImages[_readingBkgMainId].palette);
 			//FUN_00405ebc(0, false);
-		
+
 		addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes ));
 	} else {
-		
+
 	}
 	_screen->update();
 
@@ -397,7 +397,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		if (BYTE_004177f7 == 0) {
 			for (int i = 0; i < _thing1.size(); i++)
 				_thing1[i] = 0xf0fe;
-			
+
 			DAT_004177f8 = 1;
 			ProcessScript(true, data, dataSize);
 			if (_needReload)
@@ -406,7 +406,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 			FUN_00404fcc(pid);
 		}
 	} else if (tp == RESTP_20) {
-		if (dataSize != 4) 
+		if (dataSize != 4)
 			return false;
 		_someActsArr[pid].unk1 = getU32(data);
 	} else if (tp == RESTP_21) {
@@ -440,7 +440,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_3A) {
 		_thing2[pid].field_2.assign(data, data + dataSize);
 	} else if (tp == RESTP_40) {
-		return loadRes40(pid, data, dataSize);		
+		return loadRes40(pid, data, dataSize);
 	} else if (tp == RESTP_41) {
 		return loadRes41(pid, data, dataSize);
 	} else if (tp == RESTP_42) {
@@ -489,9 +489,9 @@ bool GamosEngine::initMainDatas() {
 
 	if (!_arch.readCompressedData(&rawdata))
 		return false;
-	
+
 	Common::MemoryReadStream dataStream(rawdata.data(), rawdata.size(), DisposeAfterUse::NO);
-	
+
 	_magic = dataStream.readUint32LE();
 	_pages1kbCount = dataStream.readUint32LE();
 	_readBufSize = dataStream.readUint32LE();
@@ -541,7 +541,7 @@ bool GamosEngine::init(const Common::String &moduleName) {
 
 	if (!loadInitModule())
 		return false;
-	
+
 
 	if (!playIntro())
 		return false;
@@ -608,7 +608,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 
 	_bkgImages.clear();
 	_bkgImages.resize(bkgnum1 * bkgnum2);
-	
+
 	_sprites.clear();
 	_sprites.resize(imageCount);
 
@@ -620,7 +620,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 
 	_someActsArr.clear();
 	_someActsArr.resize(actsCount);
-	
+
 	_loadedDataSize = 0;
 	_vm.clearMemory();
 }
@@ -645,7 +645,7 @@ bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
 
 	if (dataSize % 4)
 		printf("dataSize > 4\n");
-	
+
 	_sprites[id].field_0 = data[0];
 	_sprites[id].field_1 = data[1];
 	_sprites[id].field_2 = data[2];
@@ -738,12 +738,12 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 	bimg.palette = nullptr;
 
 	bimg.rawData.assign(data, data + dataSize);
-	
+
 	Common::MemoryReadStream strm(data, dataSize);
-	
+
 	if (_readingBkgMainId == -1 && (strm.readUint32LE() & 0x80000000) )
 		_readingBkgMainId = id;
-	
+
 	//printf("res 18 id %d 4: %x\n", id, strm.readUint32LE());
 
 	strm.seek(8);
@@ -774,7 +774,7 @@ bool GamosEngine::playMovie(int id) {
 	bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
 	if (_readingBkgMainId == -1)
 		_screen->setPalette(_bkgImages[0].palette);
-	else 
+	else
 		_screen->setPalette(_bkgImages[_readingBkgMainId].palette);
 	return res;
 }
@@ -809,7 +809,7 @@ void GamosEngine::stopSounds() {
 void GamosEngine::setErrMessage(const Common::String &msg) {
 	if (_errSet)
 		return;
-	
+
 	_errMessage = msg;
 	_errSet = true;
 }
@@ -824,13 +824,13 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 	}
 
 	static const Common::Point checkerCoords[16] = {
-		{0, 0}, {16, 32}, {48, 16}, {16, 48}, 
+		{0, 0}, {16, 32}, {48, 16}, {16, 48},
 		{0, 32}, {32, 48}, {16, 16}, {48, 0},
 		{32, 32}, {0, 48}, {32, 16}, {16, 0},
 		{48, 32}, {32, 0}, {0, 16}, {48, 48}};
-	
+
 	const int16 maxDelay = (500 / 10) - 1;
-	
+
 	for (int16 p = 0; p < 16; p++) {
 		uint32 val = g_system->getMillis();
 		const Common::Point point = checkerCoords[p];
@@ -842,7 +842,7 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 		_screen->update();
 		val = g_system->getMillis() - val;
 
-		if (val > maxDelay) 
+		if (val > maxDelay)
 			g_system->delayMillis(maxDelay - val);
 	}
 }
@@ -884,10 +884,10 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 			loop = FUN_00402fb4();
 		/*else
 			loop = FUN_00403314(_messageProc._act2);*/
-		
+
 		if (_needReload)
 			return 2;  // rerun update after loadModule
-		
+
 		while (loop) {
 			if (!PTR_00417388) {
 				if (FUN_004033a8(mouseMove) && FUN_004038b8())
@@ -900,7 +900,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 			if (!FUN_00402bc4())
 				return 0;
-			
+
 			if (!DAT_00417802)
 				loop = FUN_00402fb4();
 			/*else
@@ -970,7 +970,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 					break;
 				continue;
 			}
-			
+
 			if (t == 4) {
 				spos++;
 				if (spos == 0) {
@@ -992,7 +992,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 
 				uint16 fb = 0;
 				if (!p1) {
-					fb = _thing1[ ((int8)c[2] + DAT_00417220 + _thing1Size) % _thing1Size  +  
+					fb = _thing1[ ((int8)c[2] + DAT_00417220 + _thing1Size) % _thing1Size  +
 				                  ((((int8)c[3] + DAT_00417224 + _thing1Count) % _thing1Count) << _thing1Shift) ];
 				} else {
 					fb = _thing1[(c[3] << _thing1Shift) + c[2]];
@@ -1007,9 +1007,9 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 					if (c[0] == lb && (c[1] & hb & 0xf0)) {
 						cval = 2;
 					}
-				} else if (lb != 0xfe && 
+				} else if (lb != 0xfe &&
 					       (_thing2[c[0]].field_0[(fb >> 3) & 0xff] & (1 << fb & 7)) != 0) {
-					
+
 					if (!_thing2[c[0]].field_2.empty()) {
 						c[1] = c[1] & 0xf | _thing2[c[0]].field_2[lb];
 						preprocessData(fnc + 8, c);
@@ -1112,7 +1112,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 					if (_needReload)
 						return 0;
 				}
-				
+
 				return retval + 1;
 			} break;
 
@@ -1166,7 +1166,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 				/* Seems it's has a error in original
 				   think it's must be:
 				   min + rnd(max-min) */
-				
+
 				uint32 lb = rnd() >> 0x10;
 				uint32 idx = ((sbuf[ivar5 * 2 + 1] - sbuf[ivar5 * 2]) * lb + sbuf[ivar5 * 2]) >> 0x10;
 				uint16 tval = ARR_00412208[ idx ];
@@ -1188,10 +1188,10 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 
 			rstream.seek(nextpos);
 
-			if (dbits & 1) 
+			if (dbits & 1)
 				break;
 		}
-		
+
 	}
 	return retval + 1;
 }
@@ -1271,14 +1271,14 @@ void GamosEngine::preprocessDataB1(int id, byte *data) {
 		default:
 		case 0:
 			break;
-	
+
 		case 1:
 		case 2:
 		case 4:
 		case 8:
 			data[1] &= 0xf0;
 			break;
-	
+
 		case 3: {
 			static const uint8 lookup[2] = {0x10, 0x20};
 			data[1] = lookup[rndRange16(2)];
@@ -1386,7 +1386,7 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 	Object *obj = nullptr;
 	int index = 0;
 	byte *odat = nullptr;
-		
+
 	SomeAction &act = _someActsArr[oid];
 	if ((act.unk1 & 0xff) == 0) {
 		FUN_00402654(1, id, pos);
@@ -1411,7 +1411,7 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 		obj->fld_2 = *pv1;
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
 			obj->fld_2 |= 0x100;
-		
+
 		int storageSize = ((act.unk1 >> 24) & 0xff) + 1;
 		// if (storageSize < 5) {
 		// 	obj->pImg = nullptr;
@@ -1446,7 +1446,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 
 	if (actid == 0xfe)
 		return;
-	
+
 	SomeAction &act = _someActsArr[actid];
 	Object *povar4 = nullptr;
 	bool multidel = false;
@@ -1466,13 +1466,13 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 					povar4 = &obj;
 					if (!mode || multidel)
 						break;
-					
+
 					multidel = true;
 				}
 			} else {
-				if (mode && obj.fld_4 == pos && obj.fld_5 == id && 
+				if (mode && obj.fld_4 == pos && obj.fld_5 == id &&
 					obj.pos == 0xff && obj.blk == 0xff && (obj.flags & 0x40) == 0) {
-					
+
 					removeObjectMarkDirty(&obj);
 					if (multidel)
 						break;
@@ -1485,7 +1485,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 
 	if (povar4)
 		*pth1 = povar4->fld_2 & 0xf0ff;
-	
+
 	executeScript((*pth1) >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
 }
 
@@ -1528,7 +1528,7 @@ void GamosEngine::removeObjectMarkDirty(Object *obj) {
 void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, SomeAction *act, int32 scriptAddr) {
 	if (scriptAddr == -1)
 		return;
-	
+
 	uint8 sv1 = BYTE_004177f6;
 	byte *sv2 = PTR_004173e8;
 	int32 sv3 = DAT_0041722c;
@@ -1573,7 +1573,7 @@ bool GamosEngine::FUN_00402fb4()
 
 	for (int32 objIdx = pobj->index; objIdx < _drawElements.size(); objIdx++) {
 		pobj = &_drawElements[objIdx];
-	
+
 		if ((pobj->flags & 3) == 3) {
 			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7))) ) {
 				if (pobj->fld_2 & 0x100) {
@@ -1619,7 +1619,7 @@ bool GamosEngine::FUN_00402fb4()
 					//DAT_00417804 = 0;
 					for ( ScriptS &scr: PTR_00417214->scriptS ) {
 						BYTE_004177f6 = PTR_00417218->flags & 0xf0;
-						
+
 						int ivr8 = 0;
 						if (BYTE_004177f6 == 0x20)
 							ivr8 = 1;
@@ -1627,7 +1627,7 @@ bool GamosEngine::FUN_00402fb4()
 							ivr8 = 2;
 						else if (BYTE_004177f6 == 0x80)
 							ivr8 = 3;
-						
+
 						bool tmp = false;
 						for (int i = 0; i < 8; i++) {
 							if ((PTR_00417214->unk1 >> 8) & (1 << i)) {
@@ -1635,7 +1635,7 @@ bool GamosEngine::FUN_00402fb4()
 								int fncid = ((i & 3) + ivr8) & 3;
 								if (i > 3)
 									fncid += 4;
-								
+
 								DAT_004177ff = false;
 								_preprocDataId = fncid;
 								int32 res = ProcessScript(false, scr.data.data(), scr.data.size(), scr.codes1, scr.codes2);
@@ -1721,7 +1721,7 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 
 		if ((obj->flags & 0x40) == 0)
 			FUN_0040921c(obj);
-		
+
 		addDirtRectOnObject(obj);
 	}
 	return 0;
@@ -1731,8 +1731,8 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 	ImagePos *imgPos = obj->pImg;
 	Image *img = imgPos->image;
 
-	int32 x = obj->fld_4 * _unk2; 
-	int32 y = obj->fld_5 * _unk3; 
+	int32 x = obj->fld_4 * _unk2;
+	int32 y = obj->fld_5 * _unk3;
 
 	if (obj->pos != 255 && obj->blk != 255) {
 		Object *o = &_drawElements[(obj->blk * 0x100) + obj->pos];
@@ -1743,12 +1743,12 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 		}
 	}
 
-	if (obj->flags & 8) 
+	if (obj->flags & 8)
 		obj->x = x - (img->surface.w - _unk2 - imgPos->xoffset);
 	else
 		obj->x = x - imgPos->xoffset;
-	
-	if (obj->flags & 0x10) 
+
+	if (obj->flags & 0x10)
 		obj->y = y - (img->surface.h - _unk3 - imgPos->yoffset);
 	else
 		obj->y = y - imgPos->yoffset;
@@ -1781,9 +1781,9 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 		Common::Rect &r = _dirtyRects[i];
 		if (!rect.intersects(r))
 			continue;
-		
+
 		flags |= 1;
-		
+
 		if (rect.left < r.left) {
 			r.left = rect.left;
 			flags |= 2;
@@ -1807,10 +1807,10 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 		_dirtyRects.push_back(rect);
 		return;
 	}
-	
+
 	if ( !(flags & 2) )
 		return;
-	
+
 	rerunCheck:
 	for(int i = _dirtyRects.size() - 2; i > 0; i--) {
 		for (int j = _dirtyRects.size() - 1; j > i; j--) {
@@ -1818,7 +1818,7 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 			Common::Rect &r2 = _dirtyRects[j];
 			if (!r1.intersects(r2))
 				continue;
-			
+
 			r1.extend(r2);
 			_dirtyRects.remove_at(j);
 			goto rerunCheck;
@@ -1833,9 +1833,9 @@ void GamosEngine::doDraw() {
 	int32 bkg = _readingBkgMainId;
 	if (bkg == -1)
 		bkg = 0;
-	
+
 	Common::Array<Object *> drawList( 1024 );//_drawElements.size(), 1024) );
-	
+
 	int cnt = 0;
 	for (int i = 0; i < _drawElements.size(); i++) {
 		Object &obj = _drawElements[i];
@@ -1849,7 +1849,7 @@ void GamosEngine::doDraw() {
 		/*drawList[cnt] = &_cursorObject;
 		cnt++;*/
 	}
-	
+
 	drawList.resize(cnt);
 
 	if (cnt) {
@@ -1887,12 +1887,12 @@ void GamosEngine::doDraw() {
 bool GamosEngine::loadImage(Image *img) {
 	if (img->loaded)
 		return true;
-	
+
 	if (img->offset < 0)
 		return false;
-	
+
 	_arch.seek(img->offset, 0);
-	
+
 	img->rawData.resize((img->surface.w * img->surface.h + 16) & ~0xf);
 
 	if (img->cSize == 0) {
@@ -1920,7 +1920,7 @@ uint32 GamosEngine::vmCallDispatcher(void *engine, VM *vm, uint32 funcID) {
 	GamosEngine *gamos = (GamosEngine *)engine;
 
 	uint32 arg1 = 0, arg2 = 0, arg3 = 0;
-	
+
 	switch (funcID)
 	{
 	case 0:
@@ -1946,7 +1946,7 @@ uint32 GamosEngine::vmCallDispatcher(void *engine, VM *vm, uint32 funcID) {
 		printf("CallDispatcher 13 keycode %s\n", str.c_str());
 		return 0;
 	}
-	
+
 	case 14:
 		arg1 = vm->pop32();
 		gamos->loadModule(arg1);
@@ -1969,7 +1969,7 @@ uint32 GamosEngine::vmCallDispatcher(void *engine, VM *vm, uint32 funcID) {
 		arg1 = vm->pop32();
 		gamos->setCursor(arg1, true);
 		return 1;
-	
+
 	default:
 		break;
 	}
@@ -2007,12 +2007,12 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 	if (spr.field_1 & 1)
 		pobj->flags |= 4;
-	
+
 	pobj->fld_2 = (pobj->fld_2 & 0xFF00) | spr.field_3;
 	int32 idx = 0xffff;
 	if (!p)
 		idx = _curObjIndex;
-	
+
 	pobj->pos = idx & 0xff;
 	pobj->blk = (idx >> 8) & 0xff;
 	pobj->x = x;
@@ -2061,7 +2061,7 @@ void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
 	if (spr->field_2 == 1) {
 		obj->pImg = &spr->sequences[0][0];
 		if (BYTE_004177f6 == 0x80) {
-			if (spr->field_1 & 2) 
+			if (spr->field_1 & 2)
 				obj->flags |= 8;
 		} else if (BYTE_004177f6 == 0x40 && (spr->field_1 & 4)) {
 			obj->flags |= 0x10;
@@ -2107,7 +2107,7 @@ void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
 					if (spr->field_1 & 2) {
 						frm = 2;
 						obj->flags |= 8;
-					} 
+					}
 				} else {
 					frm = 6;
 					if (spr->field_1 & 4) {
@@ -2117,7 +2117,7 @@ void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
 						if (spr->field_1 & 2) {
 							frm = 2;
 							obj->flags |= 8;
-						} 
+						}
 					} else if (spr->field_1 & 2) {
 						frm = 4;
 						obj->flags |= 8;
@@ -2168,10 +2168,10 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 		int32 n = 0;
 		for (int32 i = 0; i < _drawElements.size(); i++) {
 			Object &robj = _drawElements[i];
-			
+
 			if (robj.index > obj->index)
 				n++;
-			
+
 			if ( (robj.flags & 3) == 3 && (_someActsArr[robj.actID].unk1 & 0xff) == 3 ) {
 				if (n) {
 					PTR_004121b4 = &robj;
@@ -2188,7 +2188,7 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 	if (_unk9 == 0) {
 		if (dirtRect && _cursorObject.spr)
 			addDirtRectOnObject(&_cursorObject);
-		
+
 		_mouseCursorImgId = id;
 
 		_cursorObject.spr = &_sprites[id];
@@ -2199,7 +2199,7 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 		_cursorObject.y = 0;
 		_cursorObject.pImg = &_sprites[id].sequences[0][0];
 
-		g_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(), 
+		g_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(),
 								 _cursorObject.pImg->image->surface.w,
 								 _cursorObject.pImg->image->surface.h,
 								 _cursorObject.pImg->xoffset,
@@ -2217,10 +2217,10 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 		tmpb = 0xa0;
 	else if (act2 == ACT_NONE)
 		actPos = move;
-	
+
 	if (act1 != 0xe)
 		tmpb |= act1 | 0x40;
-	
+
 	//actPos +=
 	printf("Not full FUN_00402c2c\n");
 
@@ -2312,7 +2312,7 @@ bool GamosEngine::FUN_00402bc4() {
 bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
 	if (obj->y == -1)
 		return false;
-	
+
 	Object &robj = _drawElements[obj->y];
 	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
 		return true;


Commit: 7c2ca07b73828622b0e21179152a8fd388700403
    https://github.com/scummvm/scummvm/commit/7c2ca07b73828622b0e21179152a8fd388700403
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:16+01:00

Commit Message:
GAMOS: Fix includes

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 0f1dc4bfe66..ca45f25ebd6 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -45,10 +45,9 @@
 #include "engines/util.h"
 #include "graphics/paletteman.h"
 #include "common/keyboard.h"
-#include "endian.h"
+#include "common/endian.h"
 #include "audio/mididrv.h"
 #include "audio/midiplayer.h"
-#include <cstdio>
 
 namespace Gamos {
 


Commit: 944fd8bcb28d46e26e2298dd327e52984b2c1b21
    https://github.com/scummvm/scummvm/commit/944fd8bcb28d46e26e2298dd327e52984b2c1b21
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:16+01:00

Commit Message:
GAMOS: Replace array with only grow block-based simple container for draw elements to prevent use after free on resize of array

Changed paths:
  A engines/gamos/pool.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index ca45f25ebd6..1cdbc4499ed 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1450,7 +1450,8 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	Object *povar4 = nullptr;
 	bool multidel = false;
 
-	for(Object &obj : _drawElements) {
+	for(uint i = 0; i < _drawElements.size(); i++) {
+		Object &obj = _drawElements[i];
 		if (obj.flags & 1) {
 			if (obj.flags & 2) {
 				if (obj.pos == pos && obj.blk == id) {
@@ -1489,7 +1490,8 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 }
 
 Object *GamosEngine::getFreeObject() {
-	for (Object &rObj : _drawElements) {
+	for (uint i = 0; i < _drawElements.size(); i++) {
+		Object &rObj = _drawElements[i];
 		if ( (rObj.flags & 1) == 0 ) {
 			rObj.flags = 1;
 			return &rObj;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 7eb86d13904..d2655b8baf2 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -38,6 +38,8 @@
 #include "engines/savestate.h"
 #include "graphics/screen.h"
 
+#include "gamos/pool.h"
+
 #include "gamos/proc.h"
 #include "gamos/music.h"
 #include "gamos/movie.h"
@@ -291,7 +293,7 @@ private:
 	Common::Array<Unknown1> _thing2;
 	Common::Array<SomeAction> _someActsArr;
 
-	Common::Array<Object> _drawElements;
+	Pool<Object> _drawElements;
 
 	uint8 BYTE_00412200 = 0;
 
diff --git a/engines/gamos/pool.h b/engines/gamos/pool.h
new file mode 100644
index 00000000000..924e2a8823a
--- /dev/null
+++ b/engines/gamos/pool.h
@@ -0,0 +1,160 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_POOL_H
+#define GAMOS_POOL_H
+
+#include "common/array.h"
+
+namespace Gamos {
+
+template<class T, int shift = 6>
+class Pool {
+public:
+    typedef uint size_type; /*!< Size type of the array. */
+
+    const size_type _blockSize = (1 << shift);
+    const size_type _blockMask = _blockSize - 1;
+
+public:
+
+    constexpr Pool() : _size(0) {}
+
+    explicit Pool(size_type count) : _size(count) {
+        alloc(count);
+
+        size_type n = _size;
+        for (T* blk : _blocks) {
+            for (size_type i = 0; n > 0 && i < _blockSize; i++) {
+                n--;
+                new (blk + i) T();
+            }
+        }
+    }
+
+    ~Pool() {
+		free();
+	}
+
+    template<class... TArgs>
+	void emplace_back(TArgs &&...args) {
+		alloc(_size + 1);
+
+        const size_type blid = _size >> shift;
+        const size_type elid = _size & _blockMask;
+
+        new (_blocks[blid] + elid)T(Common::forward<TArgs>(args)...);
+
+        _size++;
+	}
+
+    void push_back(const T &element) {
+		emplace_back(element);
+	}
+
+	void push_back(T &&element) {
+		emplace_back(Common::move(element));
+	}
+
+	T &operator[](size_type idx) {
+		assert(idx < _size);
+
+        const size_type blid = idx >> shift;
+        const size_type elid = idx & _blockMask;
+
+		return _blocks[blid][elid];
+	}
+
+	const T &operator[](size_type idx) const {
+		assert(idx < _size);
+
+		const size_type blid = idx >> shift;
+        const size_type elid = idx & _blockMask;
+
+		return _blocks[blid][elid];
+	}
+
+	size_type size() const {
+		return _size;
+	}
+
+    bool empty() const {
+		return (_size == 0);
+	}
+
+	void clear() {
+        free();
+	}
+
+    T &front() {
+		assert(_size > 0);
+		return _blocks[0][0];
+	}
+
+	const T &front() const {
+		assert(_size > 0);
+		return _blocks[0][0];
+	}
+
+	T &back() {
+		assert(_size > 0);
+		return operator[](_size - 1);
+	}
+
+	const T &back() const {
+		assert(_size > 0);
+		return operator[](_size - 1);
+	}
+
+protected:
+    void alloc(size_type count) {
+        size_type blockCount = (count + _blockSize - 1) >> shift;
+        if (_blocks.size() < blockCount) {
+            size_type oldsz = _blocks.size();
+            _blocks.resize(blockCount);
+            for (size_type i = oldsz; i < blockCount; i++) {
+                _blocks[i] = (T*)malloc(sizeof(T) * _blockSize);
+            }
+        }
+    }
+
+    void free() {
+        size_type n = _size;
+        for (T* blk : _blocks) {
+            for (size_type i = 0; n > 0 && i < _blockSize; i++) {
+                n--;
+                blk[i].~T();
+            }
+            ::free(blk);
+        }
+        _blocks.clear();
+
+        _size = 0;
+    }
+
+protected:
+    Common::Array<T*> _blocks;
+    size_type _size = 0;
+};
+
+};
+
+#endif
\ No newline at end of file


Commit: 9cecc28f6def17412a1d1146b8f0037539ce5c3f
    https://github.com/scummvm/scummvm/commit/9cecc28f6def17412a1d1146b8f0037539ce5c3f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:16+01:00

Commit Message:
GAMOS: VM improve

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 1cdbc4499ed..21bf59465d8 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -80,7 +80,7 @@ Common::Error GamosEngine::run() {
 	// Set the engine's debugger console
 	setDebugger(new Console());
 
-	_vm._callFuncs = vmCallDispatcher;
+	_vm._callFuncs = callbackVMCallDispatcher;
 	_vm._callingObject = this;
 
 	// If a savegame was selected from the launcher, load it
@@ -1917,65 +1917,116 @@ uint32 GamosEngine::doScript(uint32 scriptAddress) {
 }
 
 
-uint32 GamosEngine::vmCallDispatcher(void *engine, VM *vm, uint32 funcID) {
-	GamosEngine *gamos = (GamosEngine *)engine;
-
+void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	uint32 arg1 = 0, arg2 = 0, arg3 = 0;
 
 	switch (funcID)
 	{
 	case 0:
-		gamos->DAT_004177ff = true;
-		return 1;
+		DAT_004177ff = true;
+		vm->EAX.val = 1;
+		break;
 	case 3:
-		printf("func 3 %x check 0x10 \n", gamos->PTR_00417218->fld_4 & 0x90);
-		return (gamos->PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
+		printf("func 3 %x check 0x10 \n", PTR_00417218->fld_4 & 0x90);
+		vm->EAX.val = (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
+		break;
 	case 4:
-		printf("func 4 %x check 0x20 \n", gamos->PTR_00417218->fld_4 & 0xa0);
-		return (gamos->PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0;
+		printf("func 4 %x check 0x20 \n", PTR_00417218->fld_4 & 0xa0);
+		vm->EAX.val = (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0;
+		break;
 	case 5:
 		arg1 = vm->pop32();
-		//printf("func 5 %x check %x \n", gamos->PTR_00417218->fld_4 & 0xb0, arg1);
-		return (gamos->PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0;
+		//printf("func 5 %x check %x \n", PTR_00417218->fld_4 & 0xb0, arg1);
+		vm->EAX.val = (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0;
+		break;
 	case 6:
 		arg1 = vm->pop32();
-		printf("func 6 %x check %x \n", gamos->PTR_00417218->fld_4 & 0x4f, arg1);
-		return (gamos->PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
+		printf("func 6 %x check %x \n", PTR_00417218->fld_4 & 0x4f, arg1);
+		vm->EAX.val = (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
+		break;
 	case 13: {
 		VM::Reg regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef.ref, regRef.val);
 		printf("CallDispatcher 13 keycode %s\n", str.c_str());
-		return 0;
+		vm->EAX.val = 0;
+		break;
 	}
 
 	case 14:
 		arg1 = vm->pop32();
-		gamos->loadModule(arg1);
-		gamos->setNeedReload();
-		return 1;
-
-	case 15:
-		arg1 = vm->pop32(); //implement
+		loadModule(arg1);
+		setNeedReload();
+		vm->EAX.val = 1;
 		break;
 
 	case 16:
 		arg1 = vm->pop32();
-		return gamos->scriptFunc16(arg1);
+		vm->EAX.val = scriptFunc16(arg1);
+		break;
+
+	case 17:
+		arg1 = vm->pop32();
+		//playsound
+		vm->EAX.val = 1;
+		break;
 
 	case 19:
 		arg1 = vm->pop32();
-		return gamos->scriptFunc19(arg1);
+		vm->EAX.val = scriptFunc19(arg1);
+		break;
+
+	case 25: {
+		arg1 = vm->pop32();
+		if (PTR_00417218->fld_5 != arg1) {
+			PTR_00417218->fld_5 = arg1;
+			if (PTR_00417218->x != -1) {
+				Object &obj = _drawElements[PTR_00417218->x];
+				obj.fld_3 = arg1;
+			}
+			if (PTR_00417218->y != -1) {
+				Object &obj = _drawElements[PTR_00417218->y];
+				obj.fld_3 = arg1;
+				addDirtRectOnObject(&obj);
+			}
+		}
+		vm->EAX.val = 1;
+	} break;
+
+	case 30: {
+		if (PTR_00417218->y != -1) {
+			Object *obj = &_drawElements[PTR_00417218->y];
+			PTR_00417218->x = -1;
+			PTR_00417218->y = -1;
+			removeObjectMarkDirty(obj);
+		}
+	} break;
 
 	case 31:
 		arg1 = vm->pop32();
-		gamos->setCursor(arg1, true);
-		return 1;
+		setCursor(arg1, true);
+		vm->EAX.val = 1;
+		break;
+
+	case 32:
+		setCursor(0, false);
+		vm->EAX.val = 1;
+		break;
+
+	case 54:
+		arg1 = vm->pop32();
+		vm->EAX.val = rndRange16(arg1);
+		break;
 
 	default:
+		printf("Call Dispatcher %d\n", funcID);
+		vm->EAX.val = 0;
 		break;
 	}
-	printf("Call Dispatcher %d\n", funcID);
-	return 0;
+}
+
+void GamosEngine::callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID) {
+	GamosEngine *gamos = (GamosEngine *)engine;
+	gamos->vmCallDispatcher(vm, funcID);
 }
 
 uint32 GamosEngine::scriptFunc19(uint32 id) {
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 4e5e2fdd064..0f7730ed12a 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -19,6 +19,10 @@
  *
  */
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
+#define FORBIDDEN_SYMBOL_EXCEPTION_fopen
+#define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
+#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
+#define FORBIDDEN_SYMBOL_EXCEPTION_fclose
 #include <gamos/gamos.h>
 
 namespace Gamos {
@@ -36,13 +40,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
     _stack.resize(0x480);
     _stackT.resize(0x480);
 
-    struct vmcmd {
-        uint32 addr;
-        OP op;
-        uint32 sp;
-    };
-
-    Common::Array<vmcmd> cmdlog;
+    Common::Array<OpLog> cmdlog;
     
     bool loop = true;
     while (loop) {
@@ -169,15 +167,16 @@ uint32 VM::doScript(uint32 scriptAddress) {
             ESI += 4;
             break;
         
-        case OP_POP_ESI:
+        case OP_RET:
             ESI = pop32();
-            ESI += 4; /* ? */
+            ESI += 4;
             break;
         
-        case OP_POP_ESI_ADD_ESP:
+        case OP_RETX:
             ECX = popReg();
             SP += getMemBlockU32(ESI);
             ESI = ECX.val;
+            ESI += 4;
             break;
         
         case OP_MOV_EDX_EAX:
@@ -344,13 +343,12 @@ uint32 VM::doScript(uint32 scriptAddress) {
             EAX.val = getMemBlockU32(ESI);
             ESI += 4;
             if (_callFuncs)
-                EAX.val = _callFuncs(_callingObject, this, EAX.val);
-            // call funcs[ EAX ]
+                _callFuncs(_callingObject, this, EAX.val);
             break;
         
         case OP_PUSH_ESI_SET_EDX_EDI:
             push32(ESI);
-            ESI = EDX.val; // + EDI ?
+            ESI = EDX.val;
             break;
         }
     }
@@ -528,14 +526,14 @@ uint32 VM::getMemBlockU32(uint32 address) {
         return 0; // ERROR!
     
     uint32 pos = address - _currentReadMemBlock->address;
-    if (0x100 - pos >= 4)
+    if ((int32)0x100 - (int32)pos >= 4)
         return getU32(_currentReadMemBlock->data + pos); //easy
 
     MemoryBlock *block = _currentReadMemBlock;
     uint32 val = block->data[ pos ];
     pos++;
     for (int i = 1; i < 4; i++) {
-        if (pos > 0x100) {
+        if (pos >= 0x100) {
             block = findMemoryBlock(address + i);
             if (!block)
                 break;
@@ -583,7 +581,7 @@ void VM::setMemBlockU32(uint32 address, uint32 val) {
     MemoryBlock *block = _currentWriteMemBlock;
 
     for (int i = 1; i < 4; i++) {
-        if (pos > 0x100) {
+        if (pos >= 0x100) {
             block = createBlock(address + i);
             if (!block)
                 break;
@@ -640,7 +638,7 @@ Common::String VM::readMemString(uint32 address, uint32 maxLen) {
         s += c;
 
         pos++;
-        if (pos > 0x100) {
+        if (pos >= 0x100) {
             blk = findMemoryBlock(blk->address + 0x100);
             pos = 0;
         }
@@ -678,264 +676,299 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
 }
 
 
-Common::String VM::disassembly(uint32 address) {
+Common::String VM::decodeOp(uint32 address, int *size) {
     Common::String tmp;
 
-    uint32 addr = address;
+    int sz = 1;
+    byte op = getMemBlockU8(address);
+
+    address++;
+
+    switch (op) {
+    default:
+    case OP_EXIT:
+        tmp = Common::String("EXIT");
+        break;
     
-    bool loop = true;
-    while (loop) {
-        tmp += Common::String::format("%0.8x: ", addr);
+    case OP_CMP_EQ:
+        tmp = Common::String("EAX =  EDX == EAX (CMP_EQ)");
+        break;
+    
+    case OP_CMP_NE:
+        tmp = Common::String("EAX =  EDX != EAX (CMP_NE)");
+        break;
+    
+    case OP_CMP_LE:
+        tmp = Common::String("EAX =  EDX < EAX (CMP_LE) //signed");
+        break;
+    
+    case OP_CMP_LEQ:
+        tmp = Common::String("EAX =  EDX <= EAX (CMP_LEQ) //signed");
+        break;
 
-        byte op = getMemBlockU8(addr);
-        addr++;
+    case OP_CMP_GR:
+        tmp = Common::String("EAX =  EDX > EAX (CMP_GR) //signed");
+        break;
+    
+    case OP_CMP_GREQ:
+        tmp = Common::String("EAX =  EDX >= EAX (CMP_GREQ) //signed");
+        break;
+    
+    case OP_CMP_NAE:
+        tmp = Common::String("EAX =  EDX < EAX (CMP_NAE) //unsigned");
+        break;
 
-        switch (op) {
-        default:
-        case OP_EXIT:
-            loop = false;
-            tmp += Common::String("EXIT\n");
-            break;
-        
-        case OP_CMP_EQ:
-            tmp += Common::String("EAX =  EDX == EAX (CMP_EQ)\n");
-            break;
-        
-        case OP_CMP_NE:
-            tmp += Common::String("EAX =  EDX != EAX (CMP_NE)\n");
-            break;
-        
-        case OP_CMP_LE:
-            tmp += Common::String("EAX =  EDX < EAX (CMP_LE) //signed\n");
-            break;
-        
-        case OP_CMP_LEQ:
-            tmp += Common::String("EAX =  EDX <= EAX (CMP_LEQ) //signed\n");
-            break;
+    case OP_CMP_NA:
+        tmp = Common::String("EAX =  EDX <= EAX (CMP_NA) //unsigned");
+        break;
+    
+    case OP_CMP_A:
+        tmp = Common::String("EAX =  EDX > EAX (CMP_A) //unsigned");
+        break;
 
-        case OP_CMP_GR:
-            tmp += Common::String("EAX =  EDX > EAX (CMP_GR) //signed\n");
-            break;
-        
-        case OP_CMP_GREQ:
-            tmp += Common::String("EAX =  EDX >= EAX (CMP_GREQ) //signed\n");
-            break;
-        
-        case OP_CMP_NAE:
-            tmp += Common::String("EAX =  EDX < EAX (CMP_NAE) //unsigned\n");
-            break;
+    case OP_CMP_AE:
+        tmp = Common::String("EAX =  EDX >= EAX (CMP_AE) //unsigned");
+        break;
+    
+    case OP_BRANCH:
+        tmp = Common::String::format("BR %x", address + (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_JMP:
+        tmp = Common::String::format("JMP %x", (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_SP_ADD:
+        tmp = Common::String::format("ADD SP, %x", (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EDI_ECX_AL:
+        tmp = Common::String::format("MOV byte ptr[EDI + %x], AL", (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EBX_ECX_AL:
+        tmp = Common::String::format("MOV byte ptr[EBX + %x], AL", (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EDI_ECX_EAX:
+        tmp = Common::String::format("MOV dword ptr[EDI + %x], EAX", (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EBX_ECX_EAX:
+        tmp = Common::String::format("MOV dword ptr[EBX + %x], EAX", (int32)getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_RET:
+        tmp = Common::String("RET");
+        break;
+    
+    case OP_RETX:
+        tmp = Common::String::format("RET%x", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EDX_EAX:
+        tmp = Common::String("MOV EDX, EAX");
+        break;
+    
+    case OP_ADD_EAX_EDX:
+        tmp = Common::String("ADD EAX, EDX");
+        break;
 
-        case OP_CMP_NA:
-            tmp += Common::String("EAX =  EDX <= EAX (CMP_NA) //unsigned\n");
-            break;
-        
-        case OP_CMP_A:
-            tmp += Common::String("EAX =  EDX > EAX (CMP_A) //unsigned\n");
-            break;
+    case OP_MUL:
+        tmp = Common::String("MUL EDX");
+        break;
+    
+    case OP_OR:
+        tmp = Common::String("OR EDX");
+        break;
+    
+    case OP_XOR:
+        tmp = Common::String("XOR EDX");
+        break;
+    
+    case OP_AND:
+        tmp = Common::String("AND EDX");
+        break;
+    
+    case OP_NEG:
+        tmp = Common::String("NEG EAX");
+        break;
+    
+    case OP_SAR:
+        tmp = Common::String("SAR EAX, EDX,EAX // edx>>eax");
+        break;
+    
+    case OP_SHL:
+        tmp = Common::String("SHL EAX, EDX,EAX // edx<<eax");
+        break;
+    
+    case OP_LOAD:
+        tmp = Common::String::format("MOV EAX, %x", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_INC:
+        tmp = Common::String("INC EAX");
+        break;
 
-        case OP_CMP_AE:
-            tmp += Common::String("EAX =  EDX >= EAX (CMP_AE) //unsigned\n");
-            break;
-        
-        case OP_BRANCH:
-            tmp += Common::String::format("BR %x\n", addr + (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_JMP:
-            tmp += Common::String::format("JMP %x\n", (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_SP_ADD:
-            tmp += Common::String::format("ADD SP, %x\n", (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EDI_ECX_AL:
-            tmp += Common::String::format("MOV byte ptr[EDI + %x], AL\n", (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EBX_ECX_AL:
-            tmp += Common::String::format("MOV byte ptr[EBX + %x], AL\n", (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EDI_ECX_EAX:
-            tmp += Common::String::format("MOV dword ptr[EDI + %x], EAX\n", (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EBX_ECX_EAX:
-            tmp += Common::String::format("MOV dword ptr[EBX + %x], EAX\n", (int32)getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_POP_ESI:
-            tmp += Common::String("POP ESI + 4 //RET?\n");
-            break;
-        
-        case OP_POP_ESI_ADD_ESP:
-            tmp += Common::String::format("ADD SP, %x | POP ESI\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EDX_EAX:
-            tmp += Common::String("MOV EDX, EAX\n");
-            break;
-        
-        case OP_ADD_EAX_EDX:
-            tmp += Common::String("ADD EAX, EDX\n");
-            break;
+    case OP_DEC:
+        tmp = Common::String("DEC EAX");
+        break;
+    
+    case OP_XCHG:
+        tmp = Common::String("XCHG EAX,EDX");
+        break;
 
-        case OP_MUL:
-            tmp += Common::String("MUL EDX\n");
-            break;
-        
-        case OP_OR:
-            tmp += Common::String("OR EDX\n");
-            break;
-        
-        case OP_XOR:
-            tmp += Common::String("XOR EDX\n");
-            break;
-        
-        case OP_AND:
-            tmp += Common::String("AND EDX\n");
-            break;
-        
-        case OP_NEG:
-            tmp += Common::String("NEG EAX\n");
-            break;
-        
-        case OP_SAR:
-            tmp += Common::String("SAR EAX, EDX,EAX // edx>>eax\n");
-            break;
-        
-        case OP_SHL:
-            tmp += Common::String("SHL EAX, EDX,EAX // edx<<eax\n");
-            break;
-        
-        case OP_LOAD:
-            tmp += Common::String::format("MOV EAX, %x\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_INC:
-            tmp += Common::String("INC EAX\n");
-            break;
+    case OP_PUSH_EAX:
+        tmp = Common::String("PUSH EAX");
+        break;
+    
+    case OP_POP_EDX:
+        tmp = Common::String("POP EDX");
+        break;
 
-        case OP_DEC:
-            tmp += Common::String("DEC EAX\n");
-            break;
-        
-        case OP_XCHG:
-            tmp += Common::String("XCHG EAX,EDX\n");
-            break;
+    case OP_LOAD_OFFSET_EDI:
+    case OP_LOAD_OFFSET_EDI2:
+        tmp = Common::String::format("LEA EAX, [EDI + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_LOAD_OFFSET_EBX:
+        tmp = Common::String::format("LEA EAX, [EBX + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_LOAD_OFFSET_ESP:
+        tmp = Common::String::format("LEA EAX, [SP + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_PTR_EDX_AL:
+        tmp = Common::String("MOV byte ptr [EDX], AL");
+        break;
 
-        case OP_PUSH_EAX:
-            tmp += Common::String("PUSH EAX\n");
-            break;
-        
-        case OP_POP_EDX:
-            tmp += Common::String("POP EDX\n");
-            break;
+    case OP_MOV_PTR_EDX_EAX:
+        tmp = Common::String("MOV dword ptr [EDX], EAX");
+        break;
 
-        case OP_LOAD_OFFSET_EDI:
-        case OP_LOAD_OFFSET_EDI2:
-            tmp += Common::String::format("LEA EAX, [EDI + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_LOAD_OFFSET_EBX:
-            tmp += Common::String::format("LEA EAX, [EBX + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_LOAD_OFFSET_ESP:
-            tmp += Common::String::format("LEA EAX, [SP + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_PTR_EDX_AL:
-            tmp += Common::String("MOV byte ptr [EDX], AL\n");
-            break;
+    case OP_SHL_2:
+        tmp = Common::String("SHL EAX, 2");
+        break;
+    
+    case OP_ADD_4:
+        tmp = Common::String("ADD EAX, 4");
+        break;
+    
+    case OP_SUB_4:
+        tmp = Common::String("SUB EAX, 4");
+        break;
 
-        case OP_MOV_PTR_EDX_EAX:
-            tmp += Common::String("MOV dword ptr [EDX], EAX\n");
-            break;
+    case OP_XCHG_ESP:
+        tmp = Common::String("XCHG EAX, [SP]");
+        break;
 
-        case OP_SHL_2:
-            tmp += Common::String("SHL EAX, 2\n");
-            break;
-        
-        case OP_ADD_4:
-            tmp += Common::String("ADD EAX, 4\n");
-            break;
-        
-        case OP_SUB_4:
-            tmp += Common::String("SUB EAX, 4\n");
-            break;
+    case OP_NEG_ADD:
+        tmp = Common::String("EAX = EDX - EAX (OP_NEG_ADD)");
+        break;
+    
+    case OP_DIV:
+        tmp = Common::String("EAX = EDX / EAX  |   EDX = EDX %% EAX (DIV)");
+        break;
+    
+    case OP_MOV_EAX_BPTR_EDI:
+        tmp = Common::String::format("MOV EAX, byte ptr [EDI + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EAX_BPTR_EBX:
+        tmp = Common::String::format("MOV EAX, byte ptr [EBX + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EAX_DPTR_EDI:
+        tmp = Common::String::format("MOV EAX, dword ptr [EDI + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_MOV_EAX_DPTR_EBX:
+        tmp = Common::String::format("MOV EAX, dword ptr [EBX + %x]", getMemBlockU32(address));
+        sz += 4;
+        break;
 
-        case OP_XCHG_ESP:
-            tmp += Common::String("XCHG EAX, [SP]\n");
-            break;
+    case OP_MOV_EAX_BPTR_EAX:
+        tmp = Common::String("MOV EAX, byte ptr [EAX]");
+        break;
+    
+    case OP_MOV_EAX_DPTR_EAX:
+        tmp = Common::String("MOV EAX, dword ptr [EAX]");
+        break;
+    
+    case OP_PUSH_ESI_ADD_EDI:
+        tmp = Common::String::format("CALL %x", getMemBlockU32(address));
+        sz += 4;
+        break;
 
-        case OP_NEG_ADD:
-            tmp += Common::String("EAX = EDX - EAX (OP_NEG_ADD)\n");
-            break;
-        
-        case OP_DIV:
-            tmp += Common::String("EAX = EDX / EAX  |   EDX = EDX %% EAX (DIV)\n");
-            break;
-        
-        case OP_MOV_EAX_BPTR_EDI:
-            tmp += Common::String::format("MOV EAX, byte ptr [EDI + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EAX_BPTR_EBX:
-            tmp += Common::String::format("MOV EAX, byte ptr [EBX + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EAX_DPTR_EDI:
-            tmp += Common::String::format("MOV EAX, dword ptr [EDI + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_MOV_EAX_DPTR_EBX:
-            tmp += Common::String::format("MOV EAX, dword ptr [EBX + %x]\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
+    case OP_CALL_FUNC:
+        tmp = Common::String::format("CALL FUNC %d", getMemBlockU32(address));
+        sz += 4;
+        break;
+    
+    case OP_PUSH_ESI_SET_EDX_EDI:
+        tmp = Common::String("CALL EDX");
+        break;
+    }
 
-        case OP_MOV_EAX_BPTR_EAX:
-            tmp += Common::String("MOV EAX, byte ptr [EAX]\n");
-            break;
-        
-        case OP_MOV_EAX_DPTR_EAX:
-            tmp += Common::String("MOV EAX, dword ptr [EAX]\n");
-            break;
-        
-        case OP_PUSH_ESI_ADD_EDI:
-            tmp += Common::String::format("CALL %x\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
+    if (size)
+        *size = sz;
 
-        case OP_CALL_FUNC:
-            tmp += Common::String::format("CALL FUNC %x\n", getMemBlockU32(addr));
-            addr += 4;
-            break;
-        
-        case OP_PUSH_ESI_SET_EDX_EDI:
-            tmp += Common::String("CALL EDX\n");
+    return tmp;
+}
+
+
+Common::String VM::disassembly(uint32 address) {
+    Common::String tmp;
+
+    uint32 addr = address;
+    
+    while (true) {
+        tmp += Common::String::format("%08x: ", addr);
+
+        byte op = getMemBlockU8(addr);
+
+        int sz = 1;
+        tmp += decodeOp(addr, &sz);
+        tmp += "\n";
+
+        addr += sz;
+
+        if (op == OP_EXIT)
             break;
-        }
     }
 
     return tmp;
 }
 
 
+Common::String VM::opLog(const Common::Array<OpLog> &log) {
+    Common::String tmp;
+
+    for (const OpLog &l : log) {
+        tmp += Common::String::format("%08x: SP:%04x OP:[%02d] ", l.addr, l.sp, l.op) + decodeOp(l.addr) + "\n";
+    }
+
+    FILE *f = fopen("oplog", "wb");
+    fwrite(tmp.c_str(), tmp.size(), 1, f);
+    fclose(f);
+
+    return tmp;
+}
+
 }
\ No newline at end of file
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index bad9cc27494..ce6ff4d9848 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -18,6 +18,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+#ifndef GAMOS_VM_H
+#define GAMOS_VM_H
 
 #include <common/array.h>
 #include <common/hashmap.h>
@@ -47,8 +49,8 @@ public:
         OP_MOV_EBX_ECX_AL = 15,
         OP_MOV_EDI_ECX_EAX = 16,
         OP_MOV_EBX_ECX_EAX = 17,
-        OP_POP_ESI = 18,
-        OP_POP_ESI_ADD_ESP = 19,
+        OP_RET = 18,
+        OP_RETX = 19,
         OP_MOV_EDX_EAX = 20,
         OP_ADD_EAX_EDX = 21,
         OP_MUL = 22,
@@ -85,6 +87,8 @@ public:
         OP_PUSH_ESI_ADD_EDI = 53,
         OP_CALL_FUNC = 54,
         OP_PUSH_ESI_SET_EDX_EDI = 55,
+
+        OP_MAX
     };
 
     enum MEMREF {
@@ -116,6 +120,12 @@ public:
         }
     };
 
+    struct OpLog {
+        uint32 addr;
+        OP op;
+        uint32 sp;
+    };
+
 public:
     void clearMemory();
     void writeMemory(uint32 address, const byte* data, uint32 dataSize);
@@ -152,8 +162,11 @@ public:
     void setMem32(int memtype, uint32 offset, uint32 val);
     void setMem8(int memtype, uint32 offset, uint8 val);
 
+    Common::String decodeOp(uint32 address, int *size = nullptr);
     Common::String disassembly(uint32 address);
 
+    Common::String opLog(const Common::Array<OpLog> &log);
+
 public:
     uint32 ESI = 0;
     byte *EBX = nullptr;
@@ -177,3 +190,5 @@ private:
 
 
 }
+
+#endif


Commit: 8b13a14829403afa47eff6d322d86517a575db09
    https://github.com/scummvm/scummvm/commit/8b13a14829403afa47eff6d322d86517a575db09
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:17+01:00

Commit Message:
GAMOS: Split object field

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 21bf59465d8..6b12116540b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1407,9 +1407,10 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 		obj->blk = id;
 		obj->x = -1;
 		obj->y = -1;
-		obj->fld_2 = *pv1;
+		obj->fld_2 = (*pv1) & 0xff;
+		obj->fld_3 = ((*pv1) >> 8 ) & 0xff;
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
-			obj->fld_2 |= 0x100;
+			obj->fld_3 |= 1;
 
 		int storageSize = ((act.unk1 >> 24) & 0xff) + 1;
 		// if (storageSize < 5) {
@@ -1484,8 +1485,13 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	}
 
 	if (povar4)
+<<<<<<< HEAD
 		*pth1 = povar4->fld_2 & 0xf0ff;
 
+=======
+		*pth1 = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
+
+>>>>>>> 04fdf49 (Split object field)
 	executeScript((*pth1) >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
 }
 
@@ -1577,8 +1583,8 @@ bool GamosEngine::FUN_00402fb4()
 
 		if ((pobj->flags & 3) == 3) {
 			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7))) ) {
-				if (pobj->fld_2 & 0x100) {
-					pobj->fld_2 &= ~0x100;
+				if (pobj->fld_3 & 1) {
+					pobj->fld_3 &= ~1;
 				} else {
 					if ((pobj->flags & 4) == 0) {
 						if (pobj->y != -1 && FUN_00402f34(true, false, &_drawElements[pobj->y])) {
@@ -1696,8 +1702,7 @@ exit:
 }
 
 bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
-	uint8 v = obj->fld_2 & 0xff;
-	if (v < 2) {
+	if (obj->fld_2 < 2) {
 		if (p2 || (obj->flags & 4)) {
 			addDirtRectOnObject(obj);
 			if (p1)
@@ -1707,9 +1712,9 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 	} else {
 		addDirtRectOnObject(obj);
 		obj->actID++;
-		if (obj->actID == v) {
+		if (obj->actID == obj->fld_2) {
 			obj->actID = 0;
-			obj->pImg = obj->pImg - (v - 1);
+			obj->pImg = obj->pImg - (obj->fld_2 - 1);
 			if (p2 || (obj->flags & 4)) {
 				addDirtRectOnObject(obj);
 				if (p1)
@@ -1739,8 +1744,8 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 		Object *o = &_drawElements[(obj->blk * 0x100) + obj->pos];
 		if (o->flags & 4) {
 			int t = obj->actID + 1;
-			x += (o->pos - obj->fld_4) * _unk2 * t / (obj->fld_2 & 0xFF);
-			y += (o->blk - obj->fld_5) * _unk3 * t / (obj->fld_2 & 0xFF);
+			x += (o->pos - obj->fld_4) * _unk2 * t / obj->fld_2;
+			y += (o->blk - obj->fld_5) * _unk3 * t / obj->fld_2;
 		}
 	}
 
@@ -1858,7 +1863,7 @@ void GamosEngine::doDraw() {
 			for (int j = i + 1; j < drawList.size(); j++) {
 				Object *o1 = drawList[i];
 				Object *o2 = drawList[j];
-				if ((o1->fld_2 & 0xff00) < (o2->fld_2 & 0xff00)) {
+				if (o1->fld_3 < o2->fld_3) {
 					drawList[i] = o2;
 					drawList[j] = o1;
 				}
@@ -2059,8 +2064,13 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 	if (spr.field_1 & 1)
 		pobj->flags |= 4;
+<<<<<<< HEAD
 
 	pobj->fld_2 = (pobj->fld_2 & 0xFF00) | spr.field_3;
+=======
+
+	pobj->fld_2 = spr.field_3;
+>>>>>>> 04fdf49 (Split object field)
 	int32 idx = 0xffff;
 	if (!p)
 		idx = _curObjIndex;
@@ -2072,7 +2082,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 	if (!p) {
 		if (!PTR_00417218) {
-			pobj->fld_2 = (pobj->fld_2 & 0xff) | (((PTR_00417214->unk1 >> 2) & 0xFF) << 8);
+			pobj->fld_3 = (PTR_00417214->unk1 >> 16) & 0xFF;
 		} else {
 			int32 index = pobj->index;
 			if (PTR_00417218->y != -1) {
@@ -2090,15 +2100,15 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 				PTR_00417218->x = index;
 			}
 
-			pobj->fld_2 = (pobj->fld_2 & 0xff) | ((PTR_00417218->fld_5) << 8);
+			pobj->fld_3 = PTR_00417218->fld_5;
 			if (DAT_00417220 != DAT_00417228 || DAT_00417224 != DAT_0041722c) {
 				PTR_00417218->flags |= 4;
 			}
 		}
 	} else {
+		pobj->fld_3 = PTR_00417218->fld_5;
 		pobj->fld_4 = 0xff;
 		pobj->fld_5 = 0xff;
-		pobj->fld_2 = (pobj->fld_2 & 0xff) | ((PTR_00417218->fld_5) << 8);
 	}
 
 	FUN_00409378(&spr, pobj, p);
@@ -2194,7 +2204,7 @@ void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
 void GamosEngine::FUN_004095a0(Object *obj) {
 	if (obj->y != -1) {
 		Object &yobj = _drawElements[obj->y];
-		Sprite *spr = yobj.spr; //FUN_00409568
+		Sprite *spr = yobj.spr; //getSprite
 		addDirtRectOnObject(&yobj);
 		if (DAT_00417228 != DAT_00417220 || DAT_0041722c != DAT_00417224)
 			obj->flags |= 4;
@@ -2203,8 +2213,8 @@ void GamosEngine::FUN_004095a0(Object *obj) {
 }
 
 void GamosEngine::FUN_004023d8(Object *obj) {
-	if (obj->fld_2 & 0x200) {
-		obj->fld_2 &= ~0x200;
+	if (obj->fld_3 & 2) {
+		obj->fld_3 &= ~2;
 		int32 index = obj->index;
 		for (int index = obj->index; index < _drawElements.size(); index++) {
 			Object *pobj = &_drawElements[index];
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index d2655b8baf2..216d456d8f0 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -174,7 +174,8 @@ struct Object {
 	   1 - used */
 	uint8 flags = 0;
 	uint8 actID = 0;
-	uint16 fld_2 = 0;
+	uint8 fld_2 = 0;
+	uint8 fld_3 = 0;
 	uint8 fld_4 = 0;
 	uint8 fld_5 = 0;
 	uint8 pos = 0xff;


Commit: 58754bceaab25bc9ec58d8b44a03945a8f6e6cb2
    https://github.com/scummvm/scummvm/commit/58754bceaab25bc9ec58d8b44a03945a8f6e6cb2
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:17+01:00

Commit Message:
GAMOS: Small improvements

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 6b12116540b..901a9411dc9 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1485,13 +1485,8 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	}
 
 	if (povar4)
-<<<<<<< HEAD
-		*pth1 = povar4->fld_2 & 0xf0ff;
-
-=======
 		*pth1 = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
 
->>>>>>> 04fdf49 (Split object field)
 	executeScript((*pth1) >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
 }
 
@@ -1638,7 +1633,7 @@ bool GamosEngine::FUN_00402fb4()
 						bool tmp = false;
 						for (int i = 0; i < 8; i++) {
 							if ((PTR_00417214->unk1 >> 8) & (1 << i)) {
-								//DAT_004173ec = (i & 3) + ivr8;
+								//DAT_004173ec = ((i & 3) + ivr8) & 3;
 								int fncid = ((i & 3) + ivr8) & 3;
 								if (i > 3)
 									fncid += 4;
@@ -1730,7 +1725,7 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 
 		addDirtRectOnObject(obj);
 	}
-	return 0;
+	return false;
 }
 
 void GamosEngine::FUN_0040921c(Object *obj) {
@@ -2064,13 +2059,8 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 	if (spr.field_1 & 1)
 		pobj->flags |= 4;
-<<<<<<< HEAD
-
-	pobj->fld_2 = (pobj->fld_2 & 0xFF00) | spr.field_3;
-=======
 
 	pobj->fld_2 = spr.field_3;
->>>>>>> 04fdf49 (Split object field)
 	int32 idx = 0xffff;
 	if (!p)
 		idx = _curObjIndex;
@@ -2269,6 +2259,17 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 	}
 }
 
+
+bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
+	if (obj->y == -1)
+		return false;
+
+	Object &robj = _drawElements[obj->y];
+	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
+		return true;
+	return false;
+}
+
 void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1) {
 	uint8 tmpb = 0;
 	if (act2 == ACT2_8f)
@@ -2344,12 +2345,14 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 		DAT_004173f8 = DAT_004173f0;
 	} else {
 		if (act2 == ACT2_81)
-			DAT_004177fe = 14;
-		DAT_00417805 = 14;
+			DAT_004177fe = ACT_NONE;
+		DAT_00417805 = ACT_NONE;
 	}
 
 }
 
+
+
 void GamosEngine::FUN_00404fcc(int32 id) {
 	printf("Not implemented FUN_00404fcc\n");
 }
@@ -2371,15 +2374,6 @@ bool GamosEngine::FUN_00402bc4() {
 	return true;
 }
 
-bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
-	if (obj->y == -1)
-		return false;
-
-	Object &robj = _drawElements[obj->y];
-	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
-		return true;
-	return false;
-}
 
 
 } // End of namespace Gamos


Commit: 846c23a8791dd82e6725247972c0a003e118be3b
    https://github.com/scummvm/scummvm/commit/846c23a8791dd82e6725247972c0a003e118be3b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:17+01:00

Commit Message:
GAMOS: Fix mouse click handle object priority logic

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 901a9411dc9..e2289622ec7 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2307,7 +2307,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 					obj.fld_4 = 0;
 			}
 
-			if (!pobj || ((obj.fld_5 <= pobjF5) && FUN_00409600(&obj, actPos))) {
+			if ((!pobj || obj.fld_5 <= pobjF5) && FUN_00409600(&obj, actPos)) {
 				actT = tp;
 				pobjF5 = obj.fld_5;
 				pobj = &obj;


Commit: 8bf60ceb6b3095da89aa53e28ca7ddfafb636d3f
    https://github.com/scummvm/scummvm/commit/8bf60ceb6b3095da89aa53e28ca7ddfafb636d3f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:18+01:00

Commit Message:
JANITORIAL: Remove trailing spaces

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index e2289622ec7..a096e15fea8 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2374,6 +2374,15 @@ bool GamosEngine::FUN_00402bc4() {
 	return true;
 }
 
+bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
+	if (obj->y == -1)
+		return false;
+
+	Object &robj = _drawElements[obj->y];
+	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
+		return true;
+	return false;
+}
 
 
 } // End of namespace Gamos


Commit: a9365bab14323e1efd97d0c7c82c6c5327e49827
    https://github.com/scummvm/scummvm/commit/a9365bab14323e1efd97d0c7c82c6c5327e49827
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:18+01:00

Commit Message:
GAMOS: printf -> warning

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index a096e15fea8..c3c8b94b5c1 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -432,7 +432,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		_someActsArr[pid].scriptS[p1].codes2 = _loadedDataSize + p3;
 		//printf("RESTP_2C %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
-		printf("Data 38 size %d\n", dataSize);
+		warning("Data 38 size %zu", dataSize);
 		_thing2[pid].field_0.assign(data, data + dataSize);
 	} else if (tp == RESTP_39) {
 		_thing2[pid].field_1.assign(data, data + dataSize);
@@ -460,7 +460,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_XORSEQ2) {
 		loadXorSeq(data, dataSize, 2);
 	} else {
-		printf("Unk Res %x at %x sz %x\n", tp, _loadedDataSize, dataSize);
+		warning("Unk Res %x at %x sz %x", tp, _loadedDataSize, dataSize);
 	}
 	return true;
 }
@@ -643,7 +643,7 @@ bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
 		return false;
 
 	if (dataSize % 4)
-		printf("dataSize > 4\n");
+		warning("dataSize > 4");
 
 	_sprites[id].field_0 = data[0];
 	_sprites[id].field_1 = data[1];
@@ -657,11 +657,11 @@ bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
 
 bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
 	if (*(const uint32 *)data != 0) {
-		printf("41 not null!!!\n");
+		warning("41 not null!!!");
 		exit(0);
 	}
 	if (dataSize % 4)
-		printf("loadRes41 datasize > 4 \n");
+		warning("loadRes41 datasize > 4");
 	_sprites[id].sequences.resize(dataSize / 4);
 	return true;
 }
@@ -679,7 +679,7 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 	for(int i = 0; i < count; ++i) {
 		int32 dataz = strm.readSint32LE();
 		if (dataz != 0) {
-			printf("42    nut null \n");
+			warning("42    nut null");
 			exit(0);
 		}
 
@@ -796,11 +796,11 @@ void GamosEngine::stopMidi() {
 }
 
 void GamosEngine::stopMCI() {
-	printf("Not implemented stopMCI\n");
+	warning("Not implemented stopMCI");
 }
 
 void GamosEngine::stopSounds() {
-	printf("Not implemented stopSounds\n");
+	warning("Not implemented stopSounds");
 }
 
 
@@ -1927,11 +1927,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 		break;
 	case 3:
-		printf("func 3 %x check 0x10 \n", PTR_00417218->fld_4 & 0x90);
+		warning("func 3 %x check 0x10 \n", PTR_00417218->fld_4 & 0x90);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
 		break;
 	case 4:
-		printf("func 4 %x check 0x20 \n", PTR_00417218->fld_4 & 0xa0);
+		warning("func 4 %x check 0x20 \n", PTR_00417218->fld_4 & 0xa0);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0;
 		break;
 	case 5:
@@ -1941,13 +1941,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		break;
 	case 6:
 		arg1 = vm->pop32();
-		printf("func 6 %x check %x \n", PTR_00417218->fld_4 & 0x4f, arg1);
+		warning("func 6 %x check %x \n", PTR_00417218->fld_4 & 0x4f, arg1);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
 		break;
 	case 13: {
 		VM::Reg regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef.ref, regRef.val);
-		printf("CallDispatcher 13 keycode %s\n", str.c_str());
+		warning("CallDispatcher 13 keycode %s\n", str.c_str());
 		vm->EAX.val = 0;
 		break;
 	}
@@ -2018,7 +2018,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		break;
 
 	default:
-		printf("Call Dispatcher %d\n", funcID);
+		warning("Call Dispatcher %d", funcID);
 		vm->EAX.val = 0;
 		break;
 	}
@@ -2285,7 +2285,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 		tmpb |= act1 | 0x40;
 
 	//actPos +=
-	printf("Not full FUN_00402c2c\n");
+	warning("Not full FUN_00402c2c");
 
 	Object *pobj = nullptr;
 	uint8 actT = 0;
@@ -2354,23 +2354,23 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 
 
 void GamosEngine::FUN_00404fcc(int32 id) {
-	printf("Not implemented FUN_00404fcc\n");
+	warning("Not implemented FUN_00404fcc");
 }
 
 bool GamosEngine::FUN_004033a8(Common::Point mouseMove) {
 	_cursorObject.x = mouseMove.x;
 	_cursorObject.y = mouseMove.y;
-	printf("Not implemented FUN_004033a8\n");
+	warning("Not implemented FUN_004033a8");
 	return true;
 }
 
 bool GamosEngine::FUN_004038b8() {
-	printf("Not implemented FUN_004038b8\n");
+	warning("Not implemented FUN_004038b8");
 	return true;
 }
 
 bool GamosEngine::FUN_00402bc4() {
-	printf("Not implemented FUN_00402bc4\n");
+	warning("Not implemented FUN_00402bc4");
 	return true;
 }
 


Commit: 7debb8b363cef5bc0fca9bf8b6045d19e3560139
    https://github.com/scummvm/scummvm/commit/7debb8b363cef5bc0fca9bf8b6045d19e3560139
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:18+01:00

Commit Message:
GAMOS: Fix warnings

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index c3c8b94b5c1..6306d1bf47c 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -460,7 +460,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_XORSEQ2) {
 		loadXorSeq(data, dataSize, 2);
 	} else {
-		warning("Unk Res %x at %x sz %x", tp, _loadedDataSize, dataSize);
+		warning("Unk Res %x at %x sz %zx", tp, _loadedDataSize, dataSize);
 	}
 	return true;
 }
@@ -1010,7 +1010,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 					       (_thing2[c[0]].field_0[(fb >> 3) & 0xff] & (1 << fb & 7)) != 0) {
 
 					if (!_thing2[c[0]].field_2.empty()) {
-						c[1] = c[1] & 0xf | _thing2[c[0]].field_2[lb];
+						c[1] = (c[1] & 0xf) | _thing2[c[0]].field_2[lb];
 						preprocessData(fnc + 8, c);
 					}
 
@@ -1019,7 +1019,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 					}
 				}
 
-				if (c[1] & 2 == cval) {
+				if ((c[1] & 2) == cval) {
 					if ((c[1] & 0xc) == 0) {
 						rstream.skip((sz - read) * 4);
 						break;
@@ -1684,10 +1684,11 @@ bool GamosEngine::FUN_00402fb4()
 				}
 			}
 		} else {
-			if (!PTR_00417388 && (pobj->flags & 0x83) == 0x81 && pobj->pos == -1 && pobj->blk == -1)
+			if (!PTR_00417388 && (pobj->flags & 0x83) == 0x81 && pobj->pos == 0xff && pobj->blk == 0xff)
 				FUN_00402f34(true, false, pobj);
 		}
 continue_to_next_object:
+		;
 	}
 
 exit:


Commit: 3af52c5670c110d08de5a393334b0991b634f068
    https://github.com/scummvm/scummvm/commit/3af52c5670c110d08de5a393334b0991b634f068
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:19+01:00

Commit Message:
GAMOS: Fix shadowed variable warnings

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 6306d1bf47c..72acc440126 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1371,9 +1371,9 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 		Unknown1 &unk1 = _thing2[ oid ];
 		uint8 index = rndRange16( unk1.field_1[0] );
 		if (!unk1.field_2.empty()) {
-			byte id = td[1];
+			byte id1 = td[1];
 			td[1] = unk1.field_2[ unk1.field_1[ index + 1 ] ];
-			preprocessData(8 + (id >> 4), td);
+			preprocessData(8 + (id1 >> 4), td);
 		}
 	}
 


Commit: a778e76b6480a803d49d074b41d0f34aa22e53e9
    https://github.com/scummvm/scummvm/commit/a778e76b6480a803d49d074b41d0f34aa22e53e9
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:19+01:00

Commit Message:
GAMOS: Fix warning

Changed paths:
    engines/gamos/vm.h


diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index ce6ff4d9848..adb9c41573d 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -103,12 +103,7 @@ public:
         byte ref = REF_UNK;
     };
 
-    typedef uint32 (* CallDispatcher)(void *object, VM *state, uint32 funcID);
-
-    struct DataSlice {
-        uint32 address = 0;
-        Common::Array<byte> data;
-    };
+    typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
 
     struct MemoryBlock {
         uint32 address = 0;


Commit: 6d8fec85205de1356ff25ecfffe341d419f4f14b
    https://github.com/scummvm/scummvm/commit/6d8fec85205de1356ff25ecfffe341d419f4f14b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:20+01:00

Commit Message:
GAMOS: Add vm call functions

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 72acc440126..75c80fc8ce7 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -611,6 +611,9 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_sprites.clear();
 	_sprites.resize(imageCount);
 
+	for (uint i = 0; i < imageCount; i++)
+		_sprites[i].index = i;
+
 	_midiTracks.clear();
 	_midiTracks.resize(midiCount);
 
@@ -1927,6 +1930,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		DAT_004177ff = true;
 		vm->EAX.val = 1;
 		break;
+	case 2:
+		arg1 = vm->pop32();
+		if (PTR_00417218->x == -1)
+			vm->EAX.val = 0;
+		else
+			vm->EAX.val = _drawElements[ PTR_00417218->x ].spr->index == arg1 ? 1 : 0;
+		break;
 	case 3:
 		warning("func 3 %x check 0x10 \n", PTR_00417218->fld_4 & 0x90);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
@@ -2013,11 +2023,23 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 		break;
 
+	case 33:
+		PTR_00417218->fld_5 = _thing1Count - PTR_00417218->blk;
+		vm->EAX.val = 1;
+		break;
+
 	case 54:
 		arg1 = vm->pop32();
 		vm->EAX.val = rndRange16(arg1);
 		break;
 
+	case 57: {
+		VM::Reg regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef.ref, regRef.val);
+		warning("CallDispatcher 57 keycode %s", str.c_str());
+		vm->EAX.val = 0;
+	} break;
+
 	default:
 		warning("Call Dispatcher %d", funcID);
 		vm->EAX.val = 0;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 216d456d8f0..bd0974d49f1 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -125,6 +125,7 @@ struct ImagePos {
 typedef Common::Array<ImagePos> ImageSeq;
 
 struct Sprite {
+	uint32 index = 0;
 	byte field_0;
 	byte field_1;
 	byte field_2;
@@ -161,7 +162,7 @@ struct SomeAction {
 
 struct Object {
 	/* additional data */
-	int16 index;
+	int16 index = 0;
 	Sprite *spr = nullptr;
 
 	/* 80 - drawable


Commit: 629beeb7b0f3a8563349f39fbdcca0b8be48390d
    https://github.com/scummvm/scummvm/commit/629beeb7b0f3a8563349f39fbdcca0b8be48390d
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:20+01:00

Commit Message:
GAMOS: Implement missing code

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 75c80fc8ce7..f4e63684091 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1054,7 +1054,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 		preprocessDataB1(b[1] >> 4, b);
 		rnd();
 		b[1] = (b[1] & 0xf0) | (s & 0xf);
-		//FUN_00402a68(b);
+		FUN_00402a68(b);
 		if (_needReload)
 			return 0;
 	}
@@ -1353,6 +1353,42 @@ int GamosEngine::processData(int id, byte *data) {
 	}
 }
 
+void GamosEngine::FUN_00402a68(const byte *d) {
+	if (d[2] != 0 || d[3] != 0) {
+		DAT_00417220 = ((int8)d[2] + DAT_00417220 + _thing1Size) % _thing1Size;
+        DAT_00417224 = ((int8)d[3] + DAT_00417224 + _thing1Count) % _thing1Count;
+
+        _thing1[(DAT_0041722c << _thing1Shift) + DAT_00417228] = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
+
+        FUN_00402654(0, DAT_00417224, DAT_00417220);
+
+        PTR_00417218->pos = DAT_00417220;
+        PTR_00417218->blk = DAT_00417224;
+
+		uint8 t = PTR_00417218->fld_3;
+
+        uint16 thing = _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ];
+
+        PTR_00417218->fld_2 = thing & 0xff;
+        PTR_00417218->fld_3 = (PTR_00417218->fld_3 & 0xf) | ((thing >> 8) & 0xf0);
+
+        _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ] = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
+
+        BYTE_00412200 = 1;
+	}
+
+	if ((d[1] & 0xf0) != BYTE_004177f6) {
+        BYTE_004177f6 = d[1] & 0xf0;
+        PTR_00417218->flags = PTR_00417218->flags & 0xf;
+        PTR_00417218->flags = PTR_00417218->flags | BYTE_004177f6;
+
+		uint16 &tref = _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ];
+		tref = (tref & 0xff) | (BYTE_004177f6 << 8);
+
+        BYTE_00412200 = 1;
+    }
+}
+
 void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 	byte td[4];
 	memcpy(td, data, 4);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index bd0974d49f1..cffeb7e8ec0 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -412,6 +412,8 @@ protected:
 
 	void executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, SomeAction *act, int32 scriptAddr);
 
+	void FUN_00402a68(const byte *d);
+
 	void FUN_0040283c(int id, int pos, const byte *data);
 
 	void FUN_00402654(int mode, int id, int pos);


Commit: 0cfb4ecb2038b1e872a49f972b8ee27abbad561c
    https://github.com/scummvm/scummvm/commit/0cfb4ecb2038b1e872a49f972b8ee27abbad561c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:20+01:00

Commit Message:
GAMOS: Fix load of first solgamer game

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index f4e63684091..17e97835cde 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -347,7 +347,8 @@ bool GamosEngine::loadModule(uint id) {
 					return false;
 				break;
 			case 0xFF:
-				return false;
+				if (!reuseLastResource(prevByte, pid, p1, p2, 0))
+					return false;
 				break;
 			default:
 				p1 = 0;


Commit: 81bb5acf91cf6136b876f32cc38304bdd64afdef
    https://github.com/scummvm/scummvm/commit/81bb5acf91cf6136b876f32cc38304bdd64afdef
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:21+01:00

Commit Message:
GAMOS: Add additional 4 header bytes for loading compressed images

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 17e97835cde..76ff5c995a4 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1935,12 +1935,14 @@ bool GamosEngine::loadImage(Image *img) {
 
 	_arch.seek(img->offset, 0);
 
-	img->rawData.resize((img->surface.w * img->surface.h + 16) & ~0xf);
-
 	if (img->cSize == 0) {
+		img->rawData.resize((img->surface.w * img->surface.h + 16) & ~0xf);
+
 		_arch.read(img->rawData.data(), img->surface.w * img->surface.h);
 		img->surface.setPixels(img->rawData.data());
 	} else {
+		img->rawData.resize((img->surface.w * img->surface.h + 4 + 16) & ~0xf);
+
 		RawData tmp(img->cSize);
 		_arch.read(tmp.data(), tmp.size());
 		_arch.decompress(&tmp, &img->rawData);
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index adb9c41573d..95d2f25d118 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -26,8 +26,6 @@
 
 namespace Gamos {
 
-struct Sprite;
-
 class VM {
 public:
     enum OP{


Commit: a29a9f27798ea40924640a443e60fffee4d38ae5
    https://github.com/scummvm/scummvm/commit/a29a9f27798ea40924640a443e60fffee4d38ae5
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:21+01:00

Commit Message:
GAMOS: Add play sounds

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 76ff5c995a4..c92d5eb59f1 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -450,6 +450,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_50) {
 		//printf("data 50 size %d\n", dataSize);
 	} else if (tp == RESTP_51) {
+		_soundSamples[pid].assign(data, data + dataSize);
 		//printf("sound  size %d\n", dataSize);
 	} else if (tp == RESTP_52) {
 		return loadRes52(pid, data, dataSize);
@@ -591,7 +592,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	uint32 actsCount = dataStream.readUint32LE(); // 1c
 	uint32 unk1Count = dataStream.readUint32LE(); // 20
 	uint32 imageCount = dataStream.readUint32LE(); // 24
-	dataStream.readUint32LE(); // 28
+	uint32 soundCount = dataStream.readUint32LE(); // 28
 	uint32 midiCount = dataStream.readUint32LE(); // 2c
 	dataStream.readUint32LE(); // 30
 
@@ -618,6 +619,10 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_midiTracks.clear();
 	_midiTracks.resize(midiCount);
 
+	_mixer->stopAll();
+	_soundSamples.clear();
+	_soundSamples.resize(soundCount);
+
 	_thing2.clear();
 	_thing2.resize(unk1Count);
 
@@ -876,6 +881,12 @@ bool GamosEngine::playMidi(Common::Array<byte> *buffer) {
 	return _midiStarted;
 }
 
+bool GamosEngine::playSound(uint id) {
+	Audio::SeekableAudioStream *stream = Audio::makeRawStream(_soundSamples[id].data(), _soundSamples[id].size(), 11025, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
+	_mixer->playStream(Audio::Mixer::kPlainSoundType, nullptr, stream, id);
+	return true;
+}
+
 uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
 	_needReload = false;
 
@@ -2016,7 +2027,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 
 	case 17:
 		arg1 = vm->pop32();
-		//playsound
+		playSound(arg1);
 		vm->EAX.val = 1;
 		break;
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index cffeb7e8ec0..c0efba181a4 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -37,6 +37,9 @@
 #include "engines/engine.h"
 #include "engines/savestate.h"
 #include "graphics/screen.h"
+#include "audio/mixer.h"
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
 
 #include "gamos/pool.h"
 
@@ -244,6 +247,8 @@ private:
 
 	Common::Array< Common::Array<byte> >  _midiTracks;
 
+	Common::Array< Common::Array<byte> > _soundSamples;
+
 	uint32 _delayTime = 0;
 	uint32 _lastTimeStamp = 0;
 
@@ -382,6 +387,8 @@ protected:
 
 	bool playMidi(Common::Array<byte> *buffer);
 
+	bool playSound(uint id);
+
 	void stopMidi();
 	void stopMCI();
 	void stopSounds();


Commit: 8773450d2727a2b4045215bac759f0cfe44c521e
    https://github.com/scummvm/scummvm/commit/8773450d2727a2b4045215bac759f0cfe44c521e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:21+01:00

Commit Message:
GAMOS: Various fixes

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/vm.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index c92d5eb59f1..da91e29718d 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1022,7 +1022,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 						cval = 2;
 					}
 				} else if (lb != 0xfe &&
-					       (_thing2[c[0]].field_0[(fb >> 3) & 0xff] & (1 << fb & 7)) != 0) {
+					       (_thing2[c[0]].field_0[(fb & 0xff) >> 3] & (1 << fb & 7)) != 0) {
 
 					if (!_thing2[c[0]].field_2.empty()) {
 						c[1] = (c[1] & 0xf) | _thing2[c[0]].field_2[lb];
@@ -1370,6 +1370,8 @@ void GamosEngine::FUN_00402a68(const byte *d) {
 		DAT_00417220 = ((int8)d[2] + DAT_00417220 + _thing1Size) % _thing1Size;
         DAT_00417224 = ((int8)d[3] + DAT_00417224 + _thing1Count) % _thing1Count;
 
+		uint8 t = PTR_00417218->fld_3;
+
         _thing1[(DAT_0041722c << _thing1Shift) + DAT_00417228] = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
 
         FUN_00402654(0, DAT_00417224, DAT_00417220);
@@ -1377,12 +1379,10 @@ void GamosEngine::FUN_00402a68(const byte *d) {
         PTR_00417218->pos = DAT_00417220;
         PTR_00417218->blk = DAT_00417224;
 
-		uint8 t = PTR_00417218->fld_3;
-
         uint16 thing = _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ];
 
         PTR_00417218->fld_2 = thing & 0xff;
-        PTR_00417218->fld_3 = (PTR_00417218->fld_3 & 0xf) | ((thing >> 8) & 0xf0);
+        PTR_00417218->fld_3 = (t & 0xf) | ((thing >> 8) & 0xf0);
 
         _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ] = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
 
@@ -1966,8 +1966,11 @@ bool GamosEngine::loadImage(Image *img) {
 }
 
 uint32 GamosEngine::doScript(uint32 scriptAddress) {
+	byte *tmp = _vm.EBX;
 	_vm.EBX = PTR_004173e8;
-	return _vm.doScript(scriptAddress);
+	uint32 res = _vm.doScript(scriptAddress);
+	_vm.EBX = tmp;
+	return res;
 }
 
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index c0efba181a4..d082cc2c812 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -206,7 +206,7 @@ private:
 	byte _cmdByte;
 
 	bool _runReadDataMod;
-	bool _currentModuleID;
+	int _currentModuleID;
 
 	byte _saveLoadID;
 
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 0f7730ed12a..cba8680d3df 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -296,8 +296,8 @@ uint32 VM::doScript(uint32 scriptAddress) {
         
         case OP_DIV:
             ECX = EAX;
-            EAX.val = EDX.val / ECX.val;
-            EDX.val = EDX.val % ECX.val;
+            EAX.val = (int32)EDX.val / (int32)ECX.val;
+            EDX.val = (int32)EDX.val % (int32)ECX.val;
             break;
         
         case OP_MOV_EAX_BPTR_EDI:
@@ -531,13 +531,13 @@ uint32 VM::getMemBlockU32(uint32 address) {
 
     MemoryBlock *block = _currentReadMemBlock;
     uint32 val = block->data[ pos ];
-    pos++;
     for (int i = 1; i < 4; i++) {
+        pos++;
         if (pos >= 0x100) {
             block = findMemoryBlock(address + i);
             if (!block)
                 break;
-            pos = (address + i) - block->address;
+            pos = 0;
         }
         val |= block->data[ pos ] << (i * 8);
     }
@@ -574,13 +574,13 @@ void VM::setMemBlockU32(uint32 address, uint32 val) {
         setU32(_currentWriteMemBlock->data + pos, val);
         return;
     }
-    
-    _currentWriteMemBlock->data[ pos ] = val & 0xff;
-    pos++;
 
     MemoryBlock *block = _currentWriteMemBlock;
 
+    _currentWriteMemBlock->data[ pos ] = val & 0xff;
+
     for (int i = 1; i < 4; i++) {
+        pos++;
         if (pos >= 0x100) {
             block = createBlock(address + i);
             if (!block)
@@ -736,7 +736,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         break;
     
     case OP_JMP:
-        tmp = Common::String::format("JMP %x", (int32)getMemBlockU32(address));
+        tmp = Common::String::format("JMP %x", address + (int32)getMemBlockU32(address));
         sz += 4;
         break;
     


Commit: 65ab2c12a2b6736781a7d1df74a8d4f4cd842bf5
    https://github.com/scummvm/scummvm/commit/65ab2c12a2b6736781a7d1df74a8d4f4cd842bf5
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:22+01:00

Commit Message:
GAMOS: Functions for debug purpose

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index da91e29718d..8540686f12b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -27,6 +27,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_fopen
 #define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
 #define FORBIDDEN_SYMBOL_EXCEPTION_fclose
+#define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
 #define FORBIDDEN_SYMBOL_EXCEPTION_setbuf
 #define FORBIDDEN_SYMBOL_EXCEPTION_stdout
 
@@ -2460,5 +2461,53 @@ bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
 	return false;
 }
 
+void GamosEngine::dumpActions() {
+	Common::String t = Common::String::format("actions_%d.txt", _currentModuleID);
+	FILE *f = fopen(t.c_str(), "wb");
+	int i = 0;
+	for (SomeAction &act : _someActsArr) {
+		fprintf(f, "Act %d : %x\n", i, act.unk1);
+		if (act.script1 != -1) {
+			Common::String t = _vm.disassembly(act.script1);
+			fprintf(f, "Script1 : \n");
+			fwrite(t.c_str(), t.size(), 1, f);
+			fprintf(f, "\n");
+		}
+
+		if (act.script2 != -1) {
+			Common::String t = _vm.disassembly(act.script2);
+			fprintf(f, "Script2 : \n");
+			fwrite(t.c_str(), t.size(), 1, f);
+			fprintf(f, "\n");
+		}
+
+		int j = 0;
+		for (ScriptS &sc : act.scriptS) {
+			fprintf(f, "subscript %d : \n", j);
+
+			if (sc.codes1 != -1) {
+				Common::String t = _vm.disassembly(sc.codes1);
+				fprintf(f, "condition : \n");
+				fwrite(t.c_str(), t.size(), 1, f);
+				fprintf(f, "\n");
+			}
+
+			if (sc.codes2 != -1) {
+				Common::String t = _vm.disassembly(sc.codes2);
+				fprintf(f, "action : \n");
+				fwrite(t.c_str(), t.size(), 1, f);
+				fprintf(f, "\n");
+			}
+
+			j++;
+		}
+
+
+		fprintf(f, "\n\n#############################################\n\n");
+
+		i++;
+	}
+}
+
 
 } // End of namespace Gamos
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index d082cc2c812..14183b5cfd0 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -468,7 +468,12 @@ protected:
 		_vm._interrupt = true;
 	};
 
-	static uint32 vmCallDispatcher(void *engine, VM *vm, uint32 funcID);
+	void vmCallDispatcher(VM *vm, uint32 funcID);
+
+
+	void dumpActions();
+
+	static void callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID);
 
 public:
 
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index cba8680d3df..78ec825b6a5 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -971,4 +971,9 @@ Common::String VM::opLog(const Common::Array<OpLog> &log) {
     return tmp;
 }
 
+void VM::printDisassembly(uint32 address) {
+    Common::String tmp = disassembly(address);
+    warning(tmp.c_str());
+}
+
 }
\ No newline at end of file
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index 95d2f25d118..61a5565c1d4 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -160,6 +160,8 @@ public:
 
     Common::String opLog(const Common::Array<OpLog> &log);
 
+    void printDisassembly(uint32 address);
+
 public:
     uint32 ESI = 0;
     byte *EBX = nullptr;


Commit: b3aa23f5802d79850b1222f05d1e77931cd16ab0
    https://github.com/scummvm/scummvm/commit/b3aa23f5802d79850b1222f05d1e77931cd16ab0
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:22+01:00

Commit Message:
JANITORIAL: Remove trailing whitespaces and added missing newlines and end-of-files

Changed paths:
    engines/gamos/file.cpp
    engines/gamos/file.h
    engines/gamos/movie.cpp
    engines/gamos/movie.h
    engines/gamos/music.cpp
    engines/gamos/music.h
    engines/gamos/pool.h
    engines/gamos/proc.cpp
    engines/gamos/proc.h
    engines/gamos/vm.cpp


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index 3f08332cb00..1f50e489ae8 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -45,7 +45,7 @@ bool Archive::open(const Common::Path &name) {
 
     if (magic != 0x3d53563d) // =VS=
         return false;
-    
+
     seek(-_dirOffset, SEEK_END);
 
     _dirCount = readUint32LE();
@@ -69,12 +69,12 @@ bool Archive::seekDir(uint id) {
     int16 idx = findDirByID(id);
     if (idx < 0)
         return false;
-    
+
     const ArchiveDir &dir = _directories[idx];
 
     if ( !seek(_dataOffset + dir.offset, SEEK_SET) )
         return false;
-    
+
     return true;
 }
 
@@ -82,23 +82,23 @@ int32 Archive::readPackedInt() {
     byte b = readByte();
     if ( !(b & 0x80) )
         return b;
-    
+
     byte num = 0;
     byte skipsz = 0;
     if ( !(b & 0x20) )
         num = b & 0x1f;
     else
         num = 1 + ((b >> 2) & 3);
-    
+
     if (num > 4) {
         skipsz = num - 4;
         num = 4;
     }
-    
+
     int32 val = 0;
     for(int i = 0; i < num; ++i)
         val |= readByte() << (i << 3);
-    
+
     if (skipsz) {
         skip(skipsz);
         /* warning !!!! */
@@ -132,7 +132,7 @@ bool Archive::readCompressedData(RawData *out) {
     const byte t = readByte();
     if ((t & 0x80) == 0)
         return false;
-    
+
     _lastReadDecompressedSize = 0;
     _lastReadSize = 0;
 
@@ -146,7 +146,7 @@ bool Archive::readCompressedData(RawData *out) {
         /* big data size */
         for (uint i = 0; i < szsize; ++i)
             _lastReadSize |= readByte() << (i << 3);
-        
+
         /* is compressed */
         if (t & 0xC) {
             for (uint i = 0; i < szsize; ++i)
@@ -156,7 +156,7 @@ bool Archive::readCompressedData(RawData *out) {
 
     if (!_lastReadSize)
         return false;
-    
+
     _lastReadDataOffset = pos();
     out->resize(_lastReadSize);
     read(out->data(), _lastReadSize);
@@ -208,4 +208,4 @@ void Archive::decompress(RawData const *in, RawData *out) {
 }
 
 
-};
\ No newline at end of file
+};
diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index 46b527b0c45..c98faaff57d 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -37,9 +37,9 @@ public:
 
     RawData *readCompressedData();
     bool readCompressedData(RawData *out);
-    
+
     static void decompress(RawData const *in, RawData *out);
-    
+
 public:
 
 uint32 _lastReadSize = 0;
@@ -63,4 +63,4 @@ private:
 
 }; // namespace Gamos
 
-#endif // GAMOS_FILE_H
\ No newline at end of file
+#endif // GAMOS_FILE_H
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 08d6f82e80c..536bfd6c0fd 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -70,7 +70,7 @@ bool MoviePlayer::deinit() {
 bool MoviePlayer::playMovie(Common::File *file, uint32 offset, GamosEngine *gamos) {
     if (!init(file, offset, gamos))
         return error();
-    
+
     while (true) {
         int status = 0;
 
@@ -145,25 +145,25 @@ int MoviePlayer::processControlChunk() {
             return 0;
         }
         return 3;
-    
+
     case 1:
         _loopCount = 1;
         _loopPoint = 0;
 
         if (_hdrBytes[2] != 0)
             _loopCount = _hdrValue1;
-        
+
         if (_hdrBytes[3] != 0)
             _frameTime = _hdrValue2;
         break;
-    
+
     case 2:
         if (_hdrBytes[2] != 0) {
             _packedBufferSize = _hdrValue1;
             _packedBuffer.resize(_hdrValue1);
         }
         break;
-    
+
     case 3:
         if (_hdrBytes[2] != 0) {
             _bufferSize = _hdrValue1;
@@ -174,7 +174,7 @@ int MoviePlayer::processControlChunk() {
             _paletteBuffer.resize(_hdrValue2);
         }
         break;
-    
+
     case 4:
         if (_hdrBytes[2] != 0) {
             _soundBufferSize = _hdrValue1;
@@ -185,7 +185,7 @@ int MoviePlayer::processControlChunk() {
             _midiBuffer.resize(_hdrValue2);
         }
         break;
-    
+
     case 5:
         if (_hdrBytes[2] != 0) {
             _pos.x = _hdrValue1;
@@ -194,7 +194,7 @@ int MoviePlayer::processControlChunk() {
             _pos.y = _hdrValue2; /* BUG? Originally here same _pos.x */
         }
         break;
-    
+
     case 6:
         if (_hdrBytes[2] != 0) {
             _frameSize.x = _hdrValue1;
@@ -230,7 +230,7 @@ int MoviePlayer::processImageChunk() {
         if (_loopCount != 0)
             _file->seek(_loopPoint, 0);
     }
-    
+
     if (_hdrValue1 != 0) {
         byte *pdata = _buffer.data();
         Common::Point xy;
@@ -277,12 +277,12 @@ int MoviePlayer::processImageChunk() {
             }
 
             printf("movie blit%d %d %d %d %d\n", val & 3, xy.x, xy.y, wh.x, wh.y);
-            static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) = 
-               {&blit0, 
-                &blit1, 
-                &blit2, 
+            static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) =
+               {&blit0,
+                &blit1,
+                &blit2,
                 &blit3};
-            
+
             pdata = blitters[val & 3](Common::Rect(xy, xy + wh), pdata, _screen->surfacePtr());
 
             if (_doUpdateScreen) {
@@ -292,7 +292,7 @@ int MoviePlayer::processImageChunk() {
             if (val & 0x80)
                 break;
         }
-        
+
     }
 
     if (_doUpdateScreen) {
@@ -331,10 +331,10 @@ int MoviePlayer::processImageChunk() {
                 act = processMessages(false, &tstamp);
                 if (act == ACT2_82)
                     return 2;
-                
+
                 if (act == ACT2_83)
                     return 3;
-                
+
                 if ((tstamp - _firstFrameTime) / _currentFrame >= _frameTime)
                     break;
 
@@ -348,7 +348,7 @@ int MoviePlayer::processImageChunk() {
 
     _screen->update();
     _currentFrame++;
-    
+
     return 1;
 }
 
@@ -356,10 +356,10 @@ int MoviePlayer::processPaletteChunk() {
     printf("%x movieProcessPaletteChunk\n", _file->pos());
     if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
         return 0;
-    
+
     _screen->setPalette(_paletteBuffer.data());
     //g_system->getPaletteManager()->setPalette(PalColors.data(), 0, 256);
-    
+
     return 1;
 }
 
@@ -440,7 +440,7 @@ byte* MoviePlayer::blit1(Common::Rect rect, byte *in, Graphics::Surface *surface
     int16 y = rect.top;
     int16 x = rect.left;
     while (y < rect.bottom) {
-        
+
         byte b = *in;
         in++;
         if (b & 0x80) {
@@ -495,7 +495,7 @@ byte* MoviePlayer::blit2(Common::Rect rect, byte *in, Graphics::Surface *surface
     int16 y = rect.top;
     int16 x = rect.left;
     while (y < rect.bottom) {
-        
+
         byte b = *in;
         in++;
         if (b & 0x80) {
@@ -546,7 +546,7 @@ byte* MoviePlayer::blit3(Common::Rect rect, byte *in, Graphics::Surface *surface
     int16 y = rect.top;
     int16 x = rect.left;
     while (y < rect.bottom) {
-        
+
         byte b = *in;
         in++;
         if (b & 0x80) {
@@ -617,4 +617,4 @@ uint8 MoviePlayer::processMessages(bool keepAct, uint32 *msecs) {
 	return act;
 }
 
-}
\ No newline at end of file
+}
diff --git a/engines/gamos/movie.h b/engines/gamos/movie.h
index 9e70e6862b7..339a40fd5be 100644
--- a/engines/gamos/movie.h
+++ b/engines/gamos/movie.h
@@ -37,12 +37,12 @@ class MoviePlayer {
 
 
     private:
-    
+
     bool init(Common::File *file, uint32 offset, GamosEngine *gamos);
 	bool deinit();
 	bool error();
 
-	int processControlChunk();	
+	int processControlChunk();
 	int processImageChunk();
 	int processPaletteChunk();
 	int processSoundChunk();
@@ -57,7 +57,7 @@ class MoviePlayer {
 	static byte* blit1(Common::Rect rect, byte *in, Graphics::Surface *surface);
 	static byte* blit2(Common::Rect rect, byte *in, Graphics::Surface *surface);
 	static byte* blit3(Common::Rect rect, byte *in, Graphics::Surface *surface);
-        
+
 
 
     private:
@@ -103,6 +103,6 @@ class MoviePlayer {
 	int32_t _hdrValue2 = 0;
 };
 
-} 
+}
 
-#endif //GAMOS_MOVIE_H
\ No newline at end of file
+#endif //GAMOS_MOVIE_H
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index 809b297b7e9..0c837e83610 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -117,9 +117,9 @@ void MidiMusic::update() {
             bool doSend = true;
 
             uint8 cmd = _midiOp & 0xf0;
-            if (cmd != MidiDriver_BASE::MIDI_COMMAND_PROGRAM_CHANGE && 
+            if (cmd != MidiDriver_BASE::MIDI_COMMAND_PROGRAM_CHANGE &&
                 cmd != MidiDriver_BASE::MIDI_COMMAND_CHANNEL_AFTERTOUCH) {
-                if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_OFF || 
+                if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_OFF ||
                     cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_ON) {
                     if (_midiMute)
                         doSend = false;
@@ -150,7 +150,7 @@ void MidiMusic::update() {
 int16 MidiMusic::midi2low() {
     if (_dataPos >= _pMidiData.size())
         return -1;
-    
+
     int16 dat = _pMidiData[_dataPos];
     _dataPos++;
 
@@ -177,7 +177,7 @@ void MidiMusic::_timerProc(void *data) {
         _this->_midiDelayCount--;
         if (_this->_midiDelayCount != 0)
             return;
-        
+
         _this->_midiTimeStamp = g_system->getMillis();
     }
 
@@ -187,4 +187,4 @@ void MidiMusic::_timerProc(void *data) {
     }
 }
 
-};
\ No newline at end of file
+};
diff --git a/engines/gamos/music.h b/engines/gamos/music.h
index 186b7931484..5a6fbbb3722 100644
--- a/engines/gamos/music.h
+++ b/engines/gamos/music.h
@@ -40,7 +40,7 @@ private:
     Common::Array<byte> _pMidiData;
 
     Common::Mutex _mutex;
-    
+
     uint32 _dataPos = 0;
     uint32 _dataStart = 0;
     int32 _midiDelayTicks = 0;
@@ -48,7 +48,7 @@ private:
     uint32 _midiTimeStamp = 0;
     uint32 _midiOp = 0; /* save midi event type between update cycles */
     bool _midiMute = false;
-	
+
 public:
 
 	MidiMusic();
@@ -64,4 +64,4 @@ public:
 
 };
 
-#endif //GAMOS_MUSIC_H
\ No newline at end of file
+#endif //GAMOS_MUSIC_H
diff --git a/engines/gamos/pool.h b/engines/gamos/pool.h
index 924e2a8823a..403b334fe38 100644
--- a/engines/gamos/pool.h
+++ b/engines/gamos/pool.h
@@ -157,4 +157,4 @@ protected:
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index 17d2d884c79..1af3bf28043 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -22,13 +22,13 @@
 #include "gamos/gamos.h"
 
 namespace Gamos {
-	
+
 void SystemProc::processMessage(const Common::Event &ev) {
 	switch(ev.type) {
 	case Common::EVENT_KEYDOWN:
 		if ((_gd2flags & 1) == 0)
 			return;
-		
+
 		_ascii = ev.kbd.ascii;
 
 		if (ev.kbd.keycode == _keyCodes[0])
@@ -56,7 +56,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 				_act2 = ACT2_8f;
 			else if (ev.kbd.keycode == _keyCodes[11])
 				_act2 = ACT2_84;
-			else 
+			else
 				return;
 
 			_rawKeyCode = ev.kbd.keycode;
@@ -68,45 +68,45 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 		_mouseActPos = _mouseReportedPos;
 		break;
-	
+
 	case Common::EVENT_MOUSEMOVE:
 		if ((_gd2flags & 2) == 0)
 			return;
 
 		_mouseReportedPos = ev.mouse;
-		
+
 		break;
-	
+
 	case Common::EVENT_LBUTTONDOWN:
 	case Common::EVENT_RBUTTONDOWN:
 		if ((_gd2flags & 2) == 0)
 			return;
-		
+
 		_mouseActPos = ev.mouse;
-		_act2 = ACT2_81;		
+		_act2 = ACT2_81;
 		break;
-	
+
 	case Common::EVENT_LBUTTONUP:
 		if ((_gd2flags & 2) == 0)
 			return;
-		
+
 		_mouseActPos = ev.mouse;
 		_act2 = ACT2_82;
 		_rawKeyCode = _keyCodes[8];
 		break;
-	
+
 	case Common::EVENT_RBUTTONUP:
 		if ((_gd2flags & 2) == 0)
 			return;
-		
+
 		_mouseActPos = ev.mouse;
 		_act2 = ACT2_83;
 		_rawKeyCode = _keyCodes[9];
 		break;
-	
+
 	default:
 		break;
 	}
 }
 
-}
\ No newline at end of file
+}
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index 5488c4cc03a..bc6393fb8c8 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -47,17 +47,17 @@ public:
 
     uint16 _rawKeyCode = 0;
     uint16 _ascii = 0;
-    
+
 
     Common::Point _mouseReportedPos;
     Common::Point _mouseActPos;
 
     uint8 _gd2flags = 0; /* 0x4 */
     uint16 _keyCodes[12]; /* 0x40 */
-    
+
 };
 
 
 }
 
-#endif //GAMOS_PROC_H
\ No newline at end of file
+#endif //GAMOS_PROC_H
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 78ec825b6a5..aaf9f6570a7 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -41,12 +41,12 @@ uint32 VM::doScript(uint32 scriptAddress) {
     _stackT.resize(0x480);
 
     Common::Array<OpLog> cmdlog;
-    
+
     bool loop = true;
     while (loop) {
         if (_interrupt)
             return 0;
-            
+
         byte op = getMemBlockU8(ESI);
         cmdlog.push_back({ESI, (OP)op, SP});
         ESI++;
@@ -56,28 +56,28 @@ uint32 VM::doScript(uint32 scriptAddress) {
         case OP_EXIT:
             loop = false;
             break;
-        
+
         case OP_CMP_EQ:
             if (EDX.val == EAX.val)
                 EAX.val = 1;
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_CMP_NE:
             if (EDX.val != EAX.val)
                 EAX.val = 1;
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_CMP_LE:
             if ((int32)EDX.val < (int32)EAX.val)
                 EAX.val = 1;
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_CMP_LEQ:
             if ((int32)EDX.val <= (int32)EAX.val)
                 EAX.val = 1;
@@ -91,14 +91,14 @@ uint32 VM::doScript(uint32 scriptAddress) {
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_CMP_GREQ:
             if ((int32)EDX.val >= (int32)EAX.val)
                 EAX.val = 1;
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_CMP_NAE:
             if (EDX.val < EAX.val)
                 EAX.val = 1;
@@ -112,7 +112,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_CMP_A:
             if (EDX.val > EAX.val)
                 EAX.val = 1;
@@ -126,63 +126,63 @@ uint32 VM::doScript(uint32 scriptAddress) {
             else
                 EAX.val = 0;
             break;
-        
+
         case OP_BRANCH:
-            if (EAX.val != 0) 
+            if (EAX.val != 0)
                 ESI += 4;
             else
                 ESI += (int32)getMemBlockU32(ESI);
             break;
-        
+
         case OP_JMP:
             ESI += (int32)getMemBlockU32(ESI);
             break;
-        
+
         case OP_SP_ADD:
             SP += (int32)getMemBlockU32(ESI);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EDI_ECX_AL:
             ECX.val = getMemBlockU32(ESI);
             setMem8(REF_EDI, ECX.val, EAX.val & 0xff);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EBX_ECX_AL:
             ECX.val = getMemBlockU32(ESI);
             setMem8(REF_EBX, ECX.val, EAX.val & 0xff);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EDI_ECX_EAX:
             ECX.val = getMemBlockU32(ESI);
             setMem32(REF_EDI, ECX.val, EAX.val);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EBX_ECX_EAX:
             ECX.val = getMemBlockU32(ESI);
             setMem32(REF_EBX, ECX.val, EAX.val);
             ESI += 4;
             break;
-        
+
         case OP_RET:
             ESI = pop32();
             ESI += 4;
             break;
-        
+
         case OP_RETX:
             ECX = popReg();
             SP += getMemBlockU32(ESI);
             ESI = ECX.val;
             ESI += 4;
             break;
-        
+
         case OP_MOV_EDX_EAX:
             EDX = EAX;
             break;
-        
+
         case OP_ADD_EAX_EDX:
             EAX.val += EDX.val;
             if (EAX.ref == REF_UNK && EDX.ref != REF_UNK)
@@ -192,37 +192,37 @@ uint32 VM::doScript(uint32 scriptAddress) {
         case OP_MUL:
             EAX.val *= EDX.val;
             break;
-        
+
         case OP_OR:
             EAX.val |= EDX.val;
             break;
-        
+
         case OP_XOR:
             EAX.val ^= EDX.val;
             break;
-        
+
         case OP_AND:
             EAX.val &= EDX.val;
             break;
-        
+
         case OP_NEG:
             EAX.val = (uint32)(-((int32)EAX.val));
             break;
-        
+
         case OP_SAR:
             EAX.val = (uint32)(((int32)EDX.val) >> (EAX.val & 0xff)); /* must be arythmetic shift! */
             break;
-        
+
         case OP_SHL:
             EAX.val = EDX.val << (EAX.val & 0xff);
             break;
-        
+
         case OP_LOAD:
             EAX.val = getMemBlockU32(ESI);
             EAX.ref = REF_UNK;
             ESI += 4;
             break;
-        
+
         case OP_INC:
             EAX.val += 1;
             break;
@@ -230,7 +230,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
         case OP_DEC:
             EAX.val -= 1;
             break;
-        
+
         case OP_XCHG:
             ECX = EAX;
             EAX = EDX;
@@ -240,7 +240,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
         case OP_PUSH_EAX:
             pushReg(EAX);
             break;
-        
+
         case OP_POP_EDX:
             EDX = popReg();
             break;
@@ -251,19 +251,19 @@ uint32 VM::doScript(uint32 scriptAddress) {
             EAX.ref = REF_EDI;
             ESI += 4;
             break;
-        
+
         case OP_LOAD_OFFSET_EBX:
             EAX.val = getMemBlockU32(ESI);
             EAX.ref = REF_EBX;
             ESI += 4;
             break;
-        
+
         case OP_LOAD_OFFSET_ESP:
             EAX.val = getMemBlockU32(ESI) + SP;
             EAX.ref = REF_STACK;
             ESI += 4;
             break;
-        
+
         case OP_MOV_PTR_EDX_AL:
             setMem8(EDX.ref, EDX.val, EAX.val & 0xff);
             break;
@@ -275,11 +275,11 @@ uint32 VM::doScript(uint32 scriptAddress) {
         case OP_SHL_2:
             EAX.val <<= 2;
             break;
-        
+
         case OP_ADD_4:
             EAX.val += 4;
             break;
-        
+
         case OP_SUB_4:
             EAX.val -= 4;
             break;
@@ -293,31 +293,31 @@ uint32 VM::doScript(uint32 scriptAddress) {
         case OP_NEG_ADD:
             EAX.val = (uint32)(-((int32)EAX.val)) + EDX.val;
             break;
-        
+
         case OP_DIV:
             ECX = EAX;
             EAX.val = (int32)EDX.val / (int32)ECX.val;
             EDX.val = (int32)EDX.val % (int32)ECX.val;
             break;
-        
+
         case OP_MOV_EAX_BPTR_EDI:
             ECX.val = getMemBlockU32(ESI);
             EAX.val = (int8)getMem8(REF_EDI, ECX.val);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EAX_BPTR_EBX:
             ECX.val = getMemBlockU32(ESI);
             EAX.val = (int8)getMem8(REF_EBX, ECX.val);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EAX_DPTR_EDI:
             ECX.val = getMemBlockU32(ESI);
             EAX.val = getMem32(REF_EDI, ECX.val);
             ESI += 4;
             break;
-        
+
         case OP_MOV_EAX_DPTR_EBX:
             ECX.val = getMemBlockU32(ESI);
             EAX.val = getMem32(REF_EBX, ECX.val);
@@ -328,12 +328,12 @@ uint32 VM::doScript(uint32 scriptAddress) {
             EAX.val = (int8)getMem8(EAX.ref, EAX.val);
             EAX.ref = REF_UNK;
             break;
-        
+
         case OP_MOV_EAX_DPTR_EAX:
             EAX.val = getMem32(EAX.ref, EAX.val);
             EAX.ref = REF_UNK;
             break;
-        
+
         case OP_PUSH_ESI_ADD_EDI:
             push32(ESI);
             ESI = getMemBlockU32(ESI);
@@ -345,7 +345,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
             if (_callFuncs)
                 _callFuncs(_callingObject, this, EAX.val);
             break;
-        
+
         case OP_PUSH_ESI_SET_EDX_EDI:
             push32(ESI);
             ESI = EDX.val;
@@ -404,13 +404,13 @@ uint32 VM::getMem32(int memtype, uint32 offset) {
     default:
     case REF_UNK:
         return 0;
-    
+
     case REF_STACK:
         return getU32(_stack.data() + offset);
-    
+
     case REF_EBX:
         return getU32(EBX + offset);
-    
+
     case REF_EDI:
         return getMemBlockU32(offset);
     }
@@ -421,13 +421,13 @@ uint8 VM::getMem8(int memtype, uint32 offset) {
     default:
     case REF_UNK:
         return 0;
-    
+
     case REF_STACK:
         return _stack[offset];
-    
+
     case REF_EBX:
         return EBX[offset];
-    
+
     case REF_EDI:
         return getMemBlockU8(offset);
     }
@@ -444,7 +444,7 @@ void VM::setMem32(int memtype, uint32 offset, uint32 val) {
     case REF_EBX:
         setU32(EBX + offset, val);
         break;
-    
+
     case REF_EDI:
         setMemBlockU32(offset, val);
         break;
@@ -462,7 +462,7 @@ void VM::setMem8(int memtype, uint32 offset, uint8 val) {
     case REF_EBX:
         EBX[offset] = val;
         break;
-    
+
     case REF_EDI:
         setMemBlockU8(offset, val);
         break;
@@ -482,13 +482,13 @@ void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
     uint32 remain = dataSize;
 
     printf("Write memory at %x sz %x\n", address, dataSize);
-    
+
     for (uint32 addr = blockAddr; addr < address + dataSize; addr += 0x100) {
         MemoryBlock &block = _memMap.getOrCreateVal(addr);
 
-        block.address = addr; // update it 
+        block.address = addr; // update it
 
-        uint32 copyCnt = (addr + 0x100) - (address + pos); 
+        uint32 copyCnt = (addr + 0x100) - (address + pos);
         if (copyCnt > remain)
             copyCnt = remain;
 
@@ -504,27 +504,27 @@ VM::MemoryBlock *VM::findMemoryBlock(uint32 address) {
     Common::HashMap<uint32, MemoryBlock>::iterator it = _memMap.find(address & (~0xff));
     if (it == _memMap.end())
         return nullptr;
-    
+
     return &it->_value;
 }
 
 uint8 VM::getMemBlockU8(uint32 address) {
     if (!_currentReadMemBlock || address < _currentReadMemBlock->address || address >= (_currentReadMemBlock->address + 0x100))
         _currentReadMemBlock = findMemoryBlock(address);
-    
+
     if (!_currentReadMemBlock)
         return 0; // ERROR!
-    
+
     return _currentReadMemBlock->data[ address - _currentReadMemBlock->address ];
 }
 
 uint32 VM::getMemBlockU32(uint32 address) {
     if (!_currentReadMemBlock || address < _currentReadMemBlock->address || address >= (_currentReadMemBlock->address + 0x100))
         _currentReadMemBlock = findMemoryBlock(address);
-    
+
     if (!_currentReadMemBlock)
         return 0; // ERROR!
-    
+
     uint32 pos = address - _currentReadMemBlock->address;
     if ((int32)0x100 - (int32)pos >= 4)
         return getU32(_currentReadMemBlock->data + pos); //easy
@@ -598,7 +598,7 @@ Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
     MemoryBlock *blk = _currentReadMemBlock;
     if (!blk || address < blk->address || address >= (blk->address + 0x100))
         blk = findMemoryBlock(address);
-    
+
     uint32 pos = 0;
     uint32 blockAddr = address & (~0xff);
     uint32 remain = count;
@@ -612,7 +612,7 @@ Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
         } else {
             memcpy(data.data() + pos, blk->data + (address + pos - blk->address), dataCpyCount);
         }
-        
+
         pos += dataCpyCount;
         remain -= dataCpyCount;
         blockAddr += 0x100;
@@ -627,10 +627,10 @@ Common::String VM::readMemString(uint32 address, uint32 maxLen) {
     MemoryBlock *blk = _currentReadMemBlock;
     if (!blk || address < blk->address || address >= (blk->address + 0x100))
         blk = findMemoryBlock(address);
-    
+
     if (!blk)
         return s;
-    
+
     uint32 pos = address - blk->address;
     char c = blk->data[pos];
 
@@ -645,7 +645,7 @@ Common::String VM::readMemString(uint32 address, uint32 maxLen) {
 
         if (!blk)
             break;
-        
+
         c = blk->data[pos];
     }
     return s;
@@ -669,7 +669,7 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
                 s.erase(maxLen);
             return s;
         }
-        
+
         case REF_EDI:
             return readMemString(offset, maxLen);
     }
@@ -689,19 +689,19 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_EXIT:
         tmp = Common::String("EXIT");
         break;
-    
+
     case OP_CMP_EQ:
         tmp = Common::String("EAX =  EDX == EAX (CMP_EQ)");
         break;
-    
+
     case OP_CMP_NE:
         tmp = Common::String("EAX =  EDX != EAX (CMP_NE)");
         break;
-    
+
     case OP_CMP_LE:
         tmp = Common::String("EAX =  EDX < EAX (CMP_LE) //signed");
         break;
-    
+
     case OP_CMP_LEQ:
         tmp = Common::String("EAX =  EDX <= EAX (CMP_LEQ) //signed");
         break;
@@ -709,11 +709,11 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_CMP_GR:
         tmp = Common::String("EAX =  EDX > EAX (CMP_GR) //signed");
         break;
-    
+
     case OP_CMP_GREQ:
         tmp = Common::String("EAX =  EDX >= EAX (CMP_GREQ) //signed");
         break;
-    
+
     case OP_CMP_NAE:
         tmp = Common::String("EAX =  EDX < EAX (CMP_NAE) //unsigned");
         break;
@@ -721,7 +721,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_CMP_NA:
         tmp = Common::String("EAX =  EDX <= EAX (CMP_NA) //unsigned");
         break;
-    
+
     case OP_CMP_A:
         tmp = Common::String("EAX =  EDX > EAX (CMP_A) //unsigned");
         break;
@@ -729,55 +729,55 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_CMP_AE:
         tmp = Common::String("EAX =  EDX >= EAX (CMP_AE) //unsigned");
         break;
-    
+
     case OP_BRANCH:
         tmp = Common::String::format("BR %x", address + (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_JMP:
         tmp = Common::String::format("JMP %x", address + (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_SP_ADD:
         tmp = Common::String::format("ADD SP, %x", (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EDI_ECX_AL:
         tmp = Common::String::format("MOV byte ptr[EDI + %x], AL", (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EBX_ECX_AL:
         tmp = Common::String::format("MOV byte ptr[EBX + %x], AL", (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EDI_ECX_EAX:
         tmp = Common::String::format("MOV dword ptr[EDI + %x], EAX", (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EBX_ECX_EAX:
         tmp = Common::String::format("MOV dword ptr[EBX + %x], EAX", (int32)getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_RET:
         tmp = Common::String("RET");
         break;
-    
+
     case OP_RETX:
         tmp = Common::String::format("RET%x", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EDX_EAX:
         tmp = Common::String("MOV EDX, EAX");
         break;
-    
+
     case OP_ADD_EAX_EDX:
         tmp = Common::String("ADD EAX, EDX");
         break;
@@ -785,36 +785,36 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_MUL:
         tmp = Common::String("MUL EDX");
         break;
-    
+
     case OP_OR:
         tmp = Common::String("OR EDX");
         break;
-    
+
     case OP_XOR:
         tmp = Common::String("XOR EDX");
         break;
-    
+
     case OP_AND:
         tmp = Common::String("AND EDX");
         break;
-    
+
     case OP_NEG:
         tmp = Common::String("NEG EAX");
         break;
-    
+
     case OP_SAR:
         tmp = Common::String("SAR EAX, EDX,EAX // edx>>eax");
         break;
-    
+
     case OP_SHL:
         tmp = Common::String("SHL EAX, EDX,EAX // edx<<eax");
         break;
-    
+
     case OP_LOAD:
         tmp = Common::String::format("MOV EAX, %x", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_INC:
         tmp = Common::String("INC EAX");
         break;
@@ -822,7 +822,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_DEC:
         tmp = Common::String("DEC EAX");
         break;
-    
+
     case OP_XCHG:
         tmp = Common::String("XCHG EAX,EDX");
         break;
@@ -830,7 +830,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_PUSH_EAX:
         tmp = Common::String("PUSH EAX");
         break;
-    
+
     case OP_POP_EDX:
         tmp = Common::String("POP EDX");
         break;
@@ -840,17 +840,17 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         tmp = Common::String::format("LEA EAX, [EDI + %x]", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_LOAD_OFFSET_EBX:
         tmp = Common::String::format("LEA EAX, [EBX + %x]", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_LOAD_OFFSET_ESP:
         tmp = Common::String::format("LEA EAX, [SP + %x]", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_PTR_EDX_AL:
         tmp = Common::String("MOV byte ptr [EDX], AL");
         break;
@@ -862,11 +862,11 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_SHL_2:
         tmp = Common::String("SHL EAX, 2");
         break;
-    
+
     case OP_ADD_4:
         tmp = Common::String("ADD EAX, 4");
         break;
-    
+
     case OP_SUB_4:
         tmp = Common::String("SUB EAX, 4");
         break;
@@ -878,26 +878,26 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_NEG_ADD:
         tmp = Common::String("EAX = EDX - EAX (OP_NEG_ADD)");
         break;
-    
+
     case OP_DIV:
         tmp = Common::String("EAX = EDX / EAX  |   EDX = EDX %% EAX (DIV)");
         break;
-    
+
     case OP_MOV_EAX_BPTR_EDI:
         tmp = Common::String::format("MOV EAX, byte ptr [EDI + %x]", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EAX_BPTR_EBX:
         tmp = Common::String::format("MOV EAX, byte ptr [EBX + %x]", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EAX_DPTR_EDI:
         tmp = Common::String::format("MOV EAX, dword ptr [EDI + %x]", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_MOV_EAX_DPTR_EBX:
         tmp = Common::String::format("MOV EAX, dword ptr [EBX + %x]", getMemBlockU32(address));
         sz += 4;
@@ -906,11 +906,11 @@ Common::String VM::decodeOp(uint32 address, int *size) {
     case OP_MOV_EAX_BPTR_EAX:
         tmp = Common::String("MOV EAX, byte ptr [EAX]");
         break;
-    
+
     case OP_MOV_EAX_DPTR_EAX:
         tmp = Common::String("MOV EAX, dword ptr [EAX]");
         break;
-    
+
     case OP_PUSH_ESI_ADD_EDI:
         tmp = Common::String::format("CALL %x", getMemBlockU32(address));
         sz += 4;
@@ -920,7 +920,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         tmp = Common::String::format("CALL FUNC %d", getMemBlockU32(address));
         sz += 4;
         break;
-    
+
     case OP_PUSH_ESI_SET_EDX_EDI:
         tmp = Common::String("CALL EDX");
         break;
@@ -937,7 +937,7 @@ Common::String VM::disassembly(uint32 address) {
     Common::String tmp;
 
     uint32 addr = address;
-    
+
     while (true) {
         tmp += Common::String::format("%08x: ", addr);
 
@@ -976,4 +976,4 @@ void VM::printDisassembly(uint32 address) {
     warning(tmp.c_str());
 }
 
-}
\ No newline at end of file
+}


Commit: aed49c2e992be3a7bffec6b91908b1914275078e
    https://github.com/scummvm/scummvm/commit/aed49c2e992be3a7bffec6b91908b1914275078e
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:22+01:00

Commit Message:
GAMOS: Fix includes

Changed paths:
    engines/gamos/proc.h
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index bc6393fb8c8..41f0e8dafa9 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -23,7 +23,7 @@
 #ifndef GAMOS_PROC_H
 #define GAMOS_PROC_H
 
-#include <common/events.h>
+#include "common/events.h"
 
 namespace Gamos {
 
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index aaf9f6570a7..20c8cd6df9b 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -23,7 +23,7 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
 #define FORBIDDEN_SYMBOL_EXCEPTION_FILE
 #define FORBIDDEN_SYMBOL_EXCEPTION_fclose
-#include <gamos/gamos.h>
+#include "gamos/gamos.h"
 
 namespace Gamos {
 
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index 61a5565c1d4..feecd8c4b59 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -21,8 +21,8 @@
 #ifndef GAMOS_VM_H
 #define GAMOS_VM_H
 
-#include <common/array.h>
-#include <common/hashmap.h>
+#include "common/array.h"
+#include "common/hashmap.h"
 
 namespace Gamos {
 


Commit: 39be5925e2900da085909423824be926b3f974eb
    https://github.com/scummvm/scummvm/commit/39be5925e2900da085909423824be926b3f974eb
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:23+01:00

Commit Message:
GAMOS: Added missing game title

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index bc041c4b9b3..73192af3093 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -23,6 +23,7 @@ namespace Gamos {
 
 const PlainGameDescriptor gamosGames[] = {
 	{ "gamos", "Gamos" },
+	{ "solgamer", "21 Solitaire" },
 	{ 0, 0 }
 };
 


Commit: ee0db9646c7069b5a7079f8c87c2c40ba98ec20d
    https://github.com/scummvm/scummvm/commit/ee0db9646c7069b5a7079f8c87c2c40ba98ec20d
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:23+01:00

Commit Message:
JANITORIAL: Add missing copyright header

Changed paths:
    engines/gamos/file.h


diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index c98faaff57d..fb3179b3df6 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -1,3 +1,24 @@
+/* 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/>.
+ *
+ */
+
 #ifndef GAMOS_FILE_H
 #define GAMOS_FILE_H
 


Commit: 4121a3948b76f3f3c11d92cfd4e4d1a9c76f08a3
    https://github.com/scummvm/scummvm/commit/4121a3948b76f3f3c11d92cfd4e4d1a9c76f08a3
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:23+01:00

Commit Message:
GAMOS: Fix bug

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 8540686f12b..8b60239fbe0 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1023,7 +1023,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 						cval = 2;
 					}
 				} else if (lb != 0xfe &&
-					       (_thing2[c[0]].field_0[(fb & 0xff) >> 3] & (1 << fb & 7)) != 0) {
+					       (_thing2[c[0]].field_0[(fb & 0xff) >> 3] & (1 << (fb & 7))) != 0) {
 
 					if (!_thing2[c[0]].field_2.empty()) {
 						c[1] = (c[1] & 0xf) | _thing2[c[0]].field_2[lb];


Commit: 0fe94dcee1f6c16fb57fdde3ab2fd4cf81a41993
    https://github.com/scummvm/scummvm/commit/0fe94dcee1f6c16fb57fdde3ab2fd4cf81a41993
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:24+01:00

Commit Message:
GAMOS: Add games entries

Changed paths:
    engines/gamos/detection_tables.h
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 73192af3093..2b2b07df8c9 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -24,6 +24,8 @@ namespace Gamos {
 const PlainGameDescriptor gamosGames[] = {
 	{ "gamos", "Gamos" },
 	{ "solgamer", "21 Solitaire" },
+	{ "pilots", "Pilots 1" },
+	{ "pilots2", "Pilots 2" },
 	{ 0, 0 }
 };
 
@@ -37,7 +39,24 @@ const ADGameDescription gameDescriptions[] = {
 		ADGF_UNSTABLE,
 		GUIO1(GUIO_NONE)
 	},
-
+	{
+		"pilots",
+		0,
+		AD_ENTRY1s("pilots.exe", "152f751d3c1b325e91411dd75de54e95", 48357155),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_UNSTABLE,
+		GUIO1(GUIO_NONE)
+	},
+	{
+		"pilots2",
+		0,
+		AD_ENTRY1s("pilots2.exe", "a0353dfb46043d1b2d1ef8ab6c204b33", 582283983),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_UNSTABLE,
+		GUIO1(GUIO_NONE)
+	},
 	AD_TABLE_END_MARKER
 };
 
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 8b60239fbe0..46b120848ae 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -91,7 +91,14 @@ Common::Error GamosEngine::run() {
 
 	g_system->showMouse(true);
 
-	Common::String mname("solgamer.exe");
+	Common::String mname;
+	if (Common::String(_gameDescription->gameId) == Common::String("solgamer"))
+		mname = "solgamer.exe";
+	else if (Common::String(_gameDescription->gameId) == Common::String("pilots"))
+		mname = "pilots.exe";
+	else if (Common::String(_gameDescription->gameId) == Common::String("pilots2"))
+		mname = "pilots2.exe";
+
 	init(mname);
 
 	Common::Event e;


Commit: bfdcf6a5b19be5aad1717e2670e1f1f2d8723708
    https://github.com/scummvm/scummvm/commit/bfdcf6a5b19be5aad1717e2670e1f1f2d8723708
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:24+01:00

Commit Message:
GAMOS: Make possible run few VM contexts

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 46b120848ae..14c5d457b43 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -81,8 +81,8 @@ Common::Error GamosEngine::run() {
 	// Set the engine's debugger console
 	setDebugger(new Console());
 
-	_vm._callFuncs = callbackVMCallDispatcher;
-	_vm._callingObject = this;
+	VM::_callFuncs = callbackVMCallDispatcher;
+	VM::_callingObject = this;
 
 	// If a savegame was selected from the launcher, load it
 	int saveSlot = ConfMan.getInt("save_slot");
@@ -398,7 +398,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	if (tp == RESTP_12) {
 		setFPS(_fps);
 	} else if (tp == RESTP_13) {
-		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		VM::writeMemory(_loadedDataSize, data, dataSize);
 	} else if (tp == RESTP_18) {
 		loadRes18(pid, data, dataSize);
 	} else if (tp == RESTP_19) {
@@ -418,11 +418,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 			return false;
 		_someActsArr[pid].unk1 = getU32(data);
 	} else if (tp == RESTP_21) {
-		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_someActsArr[pid].script1 = _loadedDataSize + p3;
 		//printf("RESTP_21 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_22) {
-		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_someActsArr[pid].script2 = _loadedDataSize + p3;
 		//printf("RESTP_22 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_23) {
@@ -433,11 +433,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		ScriptS &scr = _someActsArr[pid].scriptS[p1];
 		scr.data.assign(data, data + dataSize);
 	} else if (tp == RESTP_2B) {
-		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_someActsArr[pid].scriptS[p1].codes1 = _loadedDataSize + p3;
 		//printf("RESTP_2B %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_2C) {
-		_vm.writeMemory(_loadedDataSize, data, dataSize);
+		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_someActsArr[pid].scriptS[p1].codes2 = _loadedDataSize + p3;
 		//printf("RESTP_2C %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
@@ -638,7 +638,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_someActsArr.resize(actsCount);
 
 	_loadedDataSize = 0;
-	_vm.clearMemory();
+	VM::clearMemory();
 }
 
 void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
@@ -897,6 +897,7 @@ bool GamosEngine::playSound(uint id) {
 
 uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
 	_needReload = false;
+	VM::_interrupt = false;
 
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
 
@@ -1974,10 +1975,7 @@ bool GamosEngine::loadImage(Image *img) {
 }
 
 uint32 GamosEngine::doScript(uint32 scriptAddress) {
-	byte *tmp = _vm.EBX;
-	_vm.EBX = PTR_004173e8;
-	uint32 res = _vm.doScript(scriptAddress);
-	_vm.EBX = tmp;
+	uint32 res = VM::doScript(scriptAddress, PTR_004173e8);
 	return res;
 }
 
@@ -2475,14 +2473,14 @@ void GamosEngine::dumpActions() {
 	for (SomeAction &act : _someActsArr) {
 		fprintf(f, "Act %d : %x\n", i, act.unk1);
 		if (act.script1 != -1) {
-			Common::String t = _vm.disassembly(act.script1);
+			t = VM::disassembly(act.script1);
 			fprintf(f, "Script1 : \n");
 			fwrite(t.c_str(), t.size(), 1, f);
 			fprintf(f, "\n");
 		}
 
 		if (act.script2 != -1) {
-			Common::String t = _vm.disassembly(act.script2);
+			t = VM::disassembly(act.script2);
 			fprintf(f, "Script2 : \n");
 			fwrite(t.c_str(), t.size(), 1, f);
 			fprintf(f, "\n");
@@ -2493,14 +2491,14 @@ void GamosEngine::dumpActions() {
 			fprintf(f, "subscript %d : \n", j);
 
 			if (sc.codes1 != -1) {
-				Common::String t = _vm.disassembly(sc.codes1);
+				t = VM::disassembly(sc.codes1);
 				fprintf(f, "condition : \n");
 				fwrite(t.c_str(), t.size(), 1, f);
 				fprintf(f, "\n");
 			}
 
 			if (sc.codes2 != -1) {
-				Common::String t = _vm.disassembly(sc.codes2);
+				t = VM::disassembly(sc.codes2);
 				fprintf(f, "action : \n");
 				fwrite(t.c_str(), t.size(), 1, f);
 				fprintf(f, "\n");
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 14183b5cfd0..bf913c80522 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -287,8 +287,6 @@ private:
 	SystemProc _messageProc;
 	MoviePlayer _moviePlayer;
 
-	VM _vm;
-
 	uint32 _thing1Size = 0;
 	uint32 _thing1Count = 0;
 	uint32 _thing1Shift = 0;
@@ -465,7 +463,7 @@ protected:
 
 	void setNeedReload() {
 		_needReload = true;
-		_vm._interrupt = true;
+		VM::_interrupt = true;
 	};
 
 	void vmCallDispatcher(VM *vm, uint32 funcID);
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 20c8cd6df9b..97006d852fd 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -27,18 +27,111 @@
 
 namespace Gamos {
 
-uint32 VM::doScript(uint32 scriptAddress) {
+VM::CallDispatcher VM::_callFuncs = nullptr;
+void *VM::_callingObject = nullptr;
+
+Common::HashMap<uint32, VM::MemoryBlock> VM::_memMap;
+bool VM::_interrupt = false;
+
+VM VM::_threads[THREADS_COUNT];
+
+VM::MemAccess VM::_memAccess;
+
+
+
+
+
+uint8 VM::MemAccess::getU8(uint32 address) {
+    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+        _currentBlock = findMemoryBlock(address);
+
+    if (!_currentBlock)
+        return 0; // ERROR!
+
+    return _currentBlock->data[ address - _currentBlock->address ];
+}
+
+uint32 VM::MemAccess::getU32(uint32 address) {
+    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+        _currentBlock = findMemoryBlock(address);
+
+    if (!_currentBlock)
+        return 0; // ERROR!
+
+    uint32 pos = address - _currentBlock->address;
+    if ((int32)0x100 - (int32)pos >= 4)
+        return VM::getU32(_currentBlock->data + pos); //easy
+
+    MemoryBlock *block = _currentBlock;
+    uint32 val = block->data[ pos ];
+    for (int i = 1; i < 4; i++) {
+        pos++;
+        if (pos >= 0x100) {
+            block = findMemoryBlock(address + i);
+            if (!block)
+                break;
+            pos = 0;
+        }
+        val |= block->data[ pos ] << (i * 8);
+    }
+
+    return val;
+}
+
+void VM::MemAccess::setU8(uint32 address, uint8 val) {
+    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+        _currentBlock = findMemoryBlock(address);
+
+    if (!_currentBlock)
+        _currentBlock = createBlock(address);
+
+    _currentBlock->data[ address - _currentBlock->address ] = val;
+}
+
+void VM::MemAccess::setU32(uint32 address, uint32 val) {
+    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+        _currentBlock = findMemoryBlock(address);
+
+    if (!_currentBlock)
+        _currentBlock = createBlock(address);
+
+    uint32 pos = address - _currentBlock->address;
+
+    if (address + 4 <= _currentBlock->address + 0x100) {
+        VM::setU32(_currentBlock->data + pos, val);
+        return;
+    }
+
+    MemoryBlock *block = _currentBlock;
+
+    _currentBlock->data[ pos ] = val & 0xff;
+
+    for (int i = 1; i < 4; i++) {
+        pos++;
+        if (pos >= 0x100) {
+            block = createBlock(address + i);
+            if (!block)
+                break;
+            pos = 0;
+        }
+        block->data[ pos ] = (val >> (i * 8)) & 0xff;
+    }
+}
+
+
+
+
+
+uint32 VM::execute(uint32 scriptAddress, byte *storage) {
     //Common::String disasm = disassembly(scriptAddress);
 
-    _interrupt = false;
     ESI = scriptAddress;
+    EBX = storage;
 
-    _currentReadMemBlock = findMemoryBlock(ESI);
-    _currentWriteMemBlock = _currentReadMemBlock;
+    _readAccess.reset();
+    _writeAccess.reset();
 
-    SP = 0x400;
-    _stack.resize(0x480);
-    _stackT.resize(0x480);
+    SP = STACK_POS;
 
     Common::Array<OpLog> cmdlog;
 
@@ -47,7 +140,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
         if (_interrupt)
             return 0;
 
-        byte op = getMemBlockU8(ESI);
+        byte op = _readAccess.getU8(ESI);
         cmdlog.push_back({ESI, (OP)op, SP});
         ESI++;
 
@@ -131,38 +224,38 @@ uint32 VM::doScript(uint32 scriptAddress) {
             if (EAX.val != 0)
                 ESI += 4;
             else
-                ESI += (int32)getMemBlockU32(ESI);
+                ESI += (int32)_readAccess.getU32(ESI);
             break;
 
         case OP_JMP:
-            ESI += (int32)getMemBlockU32(ESI);
+            ESI += (int32)_readAccess.getU32(ESI);
             break;
 
         case OP_SP_ADD:
-            SP += (int32)getMemBlockU32(ESI);
+            SP += (int32)_readAccess.getU32(ESI);
             ESI += 4;
             break;
 
         case OP_MOV_EDI_ECX_AL:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             setMem8(REF_EDI, ECX.val, EAX.val & 0xff);
             ESI += 4;
             break;
 
         case OP_MOV_EBX_ECX_AL:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             setMem8(REF_EBX, ECX.val, EAX.val & 0xff);
             ESI += 4;
             break;
 
         case OP_MOV_EDI_ECX_EAX:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             setMem32(REF_EDI, ECX.val, EAX.val);
             ESI += 4;
             break;
 
         case OP_MOV_EBX_ECX_EAX:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             setMem32(REF_EBX, ECX.val, EAX.val);
             ESI += 4;
             break;
@@ -174,7 +267,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
 
         case OP_RETX:
             ECX = popReg();
-            SP += getMemBlockU32(ESI);
+            SP += _readAccess.getU32(ESI);
             ESI = ECX.val;
             ESI += 4;
             break;
@@ -218,7 +311,7 @@ uint32 VM::doScript(uint32 scriptAddress) {
             break;
 
         case OP_LOAD:
-            EAX.val = getMemBlockU32(ESI);
+            EAX.val = _readAccess.getU32(ESI);
             EAX.ref = REF_UNK;
             ESI += 4;
             break;
@@ -247,19 +340,19 @@ uint32 VM::doScript(uint32 scriptAddress) {
 
         case OP_LOAD_OFFSET_EDI:
         case OP_LOAD_OFFSET_EDI2:
-            EAX.val = getMemBlockU32(ESI);
+            EAX.val = _readAccess.getU32(ESI);
             EAX.ref = REF_EDI;
             ESI += 4;
             break;
 
         case OP_LOAD_OFFSET_EBX:
-            EAX.val = getMemBlockU32(ESI);
+            EAX.val = _readAccess.getU32(ESI);
             EAX.ref = REF_EBX;
             ESI += 4;
             break;
 
         case OP_LOAD_OFFSET_ESP:
-            EAX.val = getMemBlockU32(ESI) + SP;
+            EAX.val = _readAccess.getU32(ESI) + SP;
             EAX.ref = REF_STACK;
             ESI += 4;
             break;
@@ -301,25 +394,25 @@ uint32 VM::doScript(uint32 scriptAddress) {
             break;
 
         case OP_MOV_EAX_BPTR_EDI:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             EAX.val = (int8)getMem8(REF_EDI, ECX.val);
             ESI += 4;
             break;
 
         case OP_MOV_EAX_BPTR_EBX:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             EAX.val = (int8)getMem8(REF_EBX, ECX.val);
             ESI += 4;
             break;
 
         case OP_MOV_EAX_DPTR_EDI:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             EAX.val = getMem32(REF_EDI, ECX.val);
             ESI += 4;
             break;
 
         case OP_MOV_EAX_DPTR_EBX:
-            ECX.val = getMemBlockU32(ESI);
+            ECX.val = _readAccess.getU32(ESI);
             EAX.val = getMem32(REF_EBX, ECX.val);
             ESI += 4;
             break;
@@ -336,11 +429,11 @@ uint32 VM::doScript(uint32 scriptAddress) {
 
         case OP_PUSH_ESI_ADD_EDI:
             push32(ESI);
-            ESI = getMemBlockU32(ESI);
+            ESI = _readAccess.getU32(ESI);
             break;
 
         case OP_CALL_FUNC:
-            EAX.val = getMemBlockU32(ESI);
+            EAX.val = _readAccess.getU32(ESI);
             ESI += 4;
             if (_callFuncs)
                 _callFuncs(_callingObject, this, EAX.val);
@@ -356,6 +449,28 @@ uint32 VM::doScript(uint32 scriptAddress) {
     return EAX.val;
 }
 
+
+uint32 VM::doScript(uint32 scriptAddress, byte *storage) {
+    if (_interrupt)
+        return 0;
+
+    for (int i = 0; i < THREADS_COUNT; i++) {
+        if (!_threads[i]._inUse) {
+            _threads[i]._inUse = true;
+            uint32 res = _threads[i].execute(scriptAddress, storage);
+            _threads[i]._inUse = false;
+            return res;
+        }
+    }
+
+    VM *tmpcontext = new VM();
+    uint32 res = tmpcontext->execute(scriptAddress, storage);
+    delete tmpcontext;
+    return res;
+}
+
+
+
 int32 VM::getS32(const void *mem) {
     const uint8 *mem8 = (const uint8 *)mem;
     return (int32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
@@ -376,24 +491,24 @@ void VM::setU32(void *mem, uint32 val) {
 
 void VM::push32(uint32 val) {
     SP -= 4;
-    setU32(_stack.data() + SP, val);
+    setU32(_stack + SP, val);
 }
 
 uint32 VM::pop32() {
-    uint32 val = getU32(_stack.data() + SP);
+    uint32 val = getU32(_stack + SP);
     SP += 4;
     return val;
 }
 
 void VM::pushReg(Reg reg) {
     SP -= 4;
-    setU32(_stack.data() + SP, reg.val);
+    setU32(_stack + SP, reg.val);
     _stackT[SP] = reg.ref;
 }
 
 VM::Reg VM::popReg() {
     Reg tmp;
-    tmp.val = getU32(_stack.data() + SP);
+    tmp.val = getU32(_stack + SP);
     tmp.ref = _stackT[SP];
     SP += 4;
     return tmp;
@@ -406,13 +521,13 @@ uint32 VM::getMem32(int memtype, uint32 offset) {
         return 0;
 
     case REF_STACK:
-        return getU32(_stack.data() + offset);
+        return getU32(_stack + offset);
 
     case REF_EBX:
         return getU32(EBX + offset);
 
     case REF_EDI:
-        return getMemBlockU32(offset);
+        return _readAccess.getU32(offset);
     }
 }
 
@@ -429,7 +544,7 @@ uint8 VM::getMem8(int memtype, uint32 offset) {
         return EBX[offset];
 
     case REF_EDI:
-        return getMemBlockU8(offset);
+        return _readAccess.getU8(offset);
     }
 }
 
@@ -439,14 +554,14 @@ void VM::setMem32(int memtype, uint32 offset, uint32 val) {
     case REF_UNK:
         break;
     case REF_STACK:
-        setU32(_stack.data() + offset, val);
+        setU32(_stack + offset, val);
         break;
     case REF_EBX:
         setU32(EBX + offset, val);
         break;
 
     case REF_EDI:
-        setMemBlockU32(offset, val);
+        _writeAccess.setU32(offset, val);
         break;
     }
 }
@@ -464,15 +579,14 @@ void VM::setMem8(int memtype, uint32 offset, uint8 val) {
         break;
 
     case REF_EDI:
-        setMemBlockU8(offset, val);
+        _writeAccess.setU8(offset, val);
         break;
     }
 }
 
 void VM::clearMemory() {
     _memMap.clear();
-    _currentReadMemBlock = nullptr;
-    _currentWriteMemBlock = nullptr;
+    _memAccess.reset();
 }
 
 void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
@@ -508,96 +622,19 @@ VM::MemoryBlock *VM::findMemoryBlock(uint32 address) {
     return &it->_value;
 }
 
-uint8 VM::getMemBlockU8(uint32 address) {
-    if (!_currentReadMemBlock || address < _currentReadMemBlock->address || address >= (_currentReadMemBlock->address + 0x100))
-        _currentReadMemBlock = findMemoryBlock(address);
-
-    if (!_currentReadMemBlock)
-        return 0; // ERROR!
-
-    return _currentReadMemBlock->data[ address - _currentReadMemBlock->address ];
-}
-
-uint32 VM::getMemBlockU32(uint32 address) {
-    if (!_currentReadMemBlock || address < _currentReadMemBlock->address || address >= (_currentReadMemBlock->address + 0x100))
-        _currentReadMemBlock = findMemoryBlock(address);
-
-    if (!_currentReadMemBlock)
-        return 0; // ERROR!
-
-    uint32 pos = address - _currentReadMemBlock->address;
-    if ((int32)0x100 - (int32)pos >= 4)
-        return getU32(_currentReadMemBlock->data + pos); //easy
-
-    MemoryBlock *block = _currentReadMemBlock;
-    uint32 val = block->data[ pos ];
-    for (int i = 1; i < 4; i++) {
-        pos++;
-        if (pos >= 0x100) {
-            block = findMemoryBlock(address + i);
-            if (!block)
-                break;
-            pos = 0;
-        }
-        val |= block->data[ pos ] << (i * 8);
-    }
-
-    return val;
-}
-
 VM::MemoryBlock *VM::createBlock(uint32 address) {
     MemoryBlock &blk = _memMap.getOrCreateVal(address & (~0xff));
     blk.address = address & (~0xff);
     return &blk;
 }
 
-void VM::setMemBlockU8(uint32 address, uint8 val) {
-    if (!_currentWriteMemBlock || address < _currentWriteMemBlock->address || address >= (_currentWriteMemBlock->address + 0x100))
-        _currentWriteMemBlock = findMemoryBlock(address);
-
-    if (!_currentWriteMemBlock)
-        _currentWriteMemBlock = createBlock(address);
-
-    _currentWriteMemBlock->data[ address - _currentWriteMemBlock->address ] = val;
-}
-
-void VM::setMemBlockU32(uint32 address, uint32 val) {
-    if (!_currentWriteMemBlock || address < _currentWriteMemBlock->address || address >= (_currentWriteMemBlock->address + 0x100))
-        _currentWriteMemBlock = findMemoryBlock(address);
-
-    if (!_currentWriteMemBlock)
-        _currentWriteMemBlock = createBlock(address);
-
-    uint32 pos = address - _currentWriteMemBlock->address;
-
-    if (address + 4 <= _currentWriteMemBlock->address + 0x100) {
-        setU32(_currentWriteMemBlock->data + pos, val);
-        return;
-    }
 
-    MemoryBlock *block = _currentWriteMemBlock;
-
-    _currentWriteMemBlock->data[ pos ] = val & 0xff;
-
-    for (int i = 1; i < 4; i++) {
-        pos++;
-        if (pos >= 0x100) {
-            block = createBlock(address + i);
-            if (!block)
-                break;
-            pos = 0;
-        }
-        block->data[ pos ] = (val >> (i * 8)) & 0xff;
-    }
-}
 
 Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
     Common::Array<byte> data;
     data.resize(count);
 
-    MemoryBlock *blk = _currentReadMemBlock;
-    if (!blk || address < blk->address || address >= (blk->address + 0x100))
-        blk = findMemoryBlock(address);
+    MemoryBlock *blk = findMemoryBlock(address);
 
     uint32 pos = 0;
     uint32 blockAddr = address & (~0xff);
@@ -624,9 +661,7 @@ Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
 Common::String VM::readMemString(uint32 address, uint32 maxLen) {
     Common::String s;
 
-    MemoryBlock *blk = _currentReadMemBlock;
-    if (!blk || address < blk->address || address >= (blk->address + 0x100))
-        blk = findMemoryBlock(address);
+    MemoryBlock *blk = findMemoryBlock(address);
 
     if (!blk)
         return s;
@@ -658,7 +693,7 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
             return Common::String();
 
         case REF_STACK: {
-            Common::String s = Common::String((const char *)_stack.data() + offset);
+            Common::String s = Common::String((const char *)_stack + offset);
             if (s.size() > maxLen)
                 s.erase(maxLen);
             return s;
@@ -679,8 +714,10 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
 Common::String VM::decodeOp(uint32 address, int *size) {
     Common::String tmp;
 
+    MemAccess readmem;
+
     int sz = 1;
-    byte op = getMemBlockU8(address);
+    byte op = readmem.getU8(address);
 
     address++;
 
@@ -731,37 +768,37 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         break;
 
     case OP_BRANCH:
-        tmp = Common::String::format("BR %x", address + (int32)getMemBlockU32(address));
+        tmp = Common::String::format("BR %x", address + (int32)readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_JMP:
-        tmp = Common::String::format("JMP %x", address + (int32)getMemBlockU32(address));
+        tmp = Common::String::format("JMP %x", address + (int32)readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_SP_ADD:
-        tmp = Common::String::format("ADD SP, %x", (int32)getMemBlockU32(address));
+        tmp = Common::String::format("ADD SP, %x", (int32)readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EDI_ECX_AL:
-        tmp = Common::String::format("MOV byte ptr[EDI + %x], AL", (int32)getMemBlockU32(address));
+        tmp = Common::String::format("MOV byte ptr[EDI + %x], AL", (int32)readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EBX_ECX_AL:
-        tmp = Common::String::format("MOV byte ptr[EBX + %x], AL", (int32)getMemBlockU32(address));
+        tmp = Common::String::format("MOV byte ptr[EBX + %x], AL", (int32)readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EDI_ECX_EAX:
-        tmp = Common::String::format("MOV dword ptr[EDI + %x], EAX", (int32)getMemBlockU32(address));
+        tmp = Common::String::format("MOV dword ptr[EDI + %x], EAX", (int32)readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EBX_ECX_EAX:
-        tmp = Common::String::format("MOV dword ptr[EBX + %x], EAX", (int32)getMemBlockU32(address));
+        tmp = Common::String::format("MOV dword ptr[EBX + %x], EAX", (int32)readmem.getU32(address));
         sz += 4;
         break;
 
@@ -770,7 +807,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         break;
 
     case OP_RETX:
-        tmp = Common::String::format("RET%x", getMemBlockU32(address));
+        tmp = Common::String::format("RET%x", readmem.getU32(address));
         sz += 4;
         break;
 
@@ -811,7 +848,7 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         break;
 
     case OP_LOAD:
-        tmp = Common::String::format("MOV EAX, %x", getMemBlockU32(address));
+        tmp = Common::String::format("MOV EAX, %x", readmem.getU32(address));
         sz += 4;
         break;
 
@@ -837,17 +874,17 @@ Common::String VM::decodeOp(uint32 address, int *size) {
 
     case OP_LOAD_OFFSET_EDI:
     case OP_LOAD_OFFSET_EDI2:
-        tmp = Common::String::format("LEA EAX, [EDI + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("LEA EAX, [EDI + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_LOAD_OFFSET_EBX:
-        tmp = Common::String::format("LEA EAX, [EBX + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("LEA EAX, [EBX + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_LOAD_OFFSET_ESP:
-        tmp = Common::String::format("LEA EAX, [SP + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("LEA EAX, [SP + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
@@ -884,22 +921,22 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         break;
 
     case OP_MOV_EAX_BPTR_EDI:
-        tmp = Common::String::format("MOV EAX, byte ptr [EDI + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("MOV EAX, byte ptr [EDI + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EAX_BPTR_EBX:
-        tmp = Common::String::format("MOV EAX, byte ptr [EBX + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("MOV EAX, byte ptr [EBX + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EAX_DPTR_EDI:
-        tmp = Common::String::format("MOV EAX, dword ptr [EDI + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("MOV EAX, dword ptr [EDI + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_MOV_EAX_DPTR_EBX:
-        tmp = Common::String::format("MOV EAX, dword ptr [EBX + %x]", getMemBlockU32(address));
+        tmp = Common::String::format("MOV EAX, dword ptr [EBX + %x]", readmem.getU32(address));
         sz += 4;
         break;
 
@@ -912,12 +949,12 @@ Common::String VM::decodeOp(uint32 address, int *size) {
         break;
 
     case OP_PUSH_ESI_ADD_EDI:
-        tmp = Common::String::format("CALL %x", getMemBlockU32(address));
+        tmp = Common::String::format("CALL %x", readmem.getU32(address));
         sz += 4;
         break;
 
     case OP_CALL_FUNC:
-        tmp = Common::String::format("CALL FUNC %d", getMemBlockU32(address));
+        tmp = Common::String::format("CALL FUNC %d", readmem.getU32(address));
         sz += 4;
         break;
 
@@ -937,11 +974,12 @@ Common::String VM::disassembly(uint32 address) {
     Common::String tmp;
 
     uint32 addr = address;
+    MemAccess readmem;
 
     while (true) {
         tmp += Common::String::format("%08x: ", addr);
 
-        byte op = getMemBlockU8(addr);
+        byte op = readmem.getU8(addr);
 
         int sz = 1;
         tmp += decodeOp(addr, &sz);
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index feecd8c4b59..1f7d7739f10 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -28,6 +28,10 @@ namespace Gamos {
 
 class VM {
 public:
+    static constexpr const uint THREADS_COUNT = 2;
+    static constexpr const uint STACK_SIZE = 0x100;
+    static constexpr const uint STACK_POS = 0x80;
+
     enum OP{
         OP_EXIT = 0,
         OP_CMP_EQ = 1,
@@ -119,29 +123,41 @@ public:
         uint32 sp;
     };
 
+    struct MemAccess {
+        MemoryBlock *_currentBlock = nullptr;
+
+        uint8 getU8(uint32 address);
+        uint32 getU32(uint32 address);
+
+        void setU8(uint32 address, uint8 val);
+        void setU32(uint32 address, uint32 val);
+
+        void reset() { _currentBlock = nullptr; }
+    };
+
 public:
-    void clearMemory();
-    void writeMemory(uint32 address, const byte* data, uint32 dataSize);
-    MemoryBlock *findMemoryBlock(uint32 address);
-    uint8 getMemBlockU8(uint32 address);
-    uint32 getMemBlockU32(uint32 address);
+    inline static MemAccess& memory() {return _memAccess;};
 
-    MemoryBlock *createBlock(uint32 address);
+    static void clearMemory();
+    static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
 
-    void setMemBlockU8(uint32 address, uint8 val);
-    void setMemBlockU32(uint32 address, uint32 val);
+    static MemoryBlock *findMemoryBlock(uint32 address);
 
-    Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+    static MemoryBlock *createBlock(uint32 address);
 
-    Common::String readMemString(uint32 address, uint32 maxLen = 256);
+    static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+
+    static Common::String readMemString(uint32 address, uint32 maxLen = 256);
 
     Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
 
-    uint32 doScript(uint32 scriptAddress);
+    uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
+
+    static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
 
-    int32 getS32(const void *);
-    uint32 getU32(const void *);
-    void setU32(void *, uint32 val);
+    static int32 getS32(const void *);
+    static uint32 getU32(const void *);
+    static void setU32(void *, uint32 val);
 
     void push32(uint32 val);
     uint32 pop32();
@@ -155,32 +171,40 @@ public:
     void setMem32(int memtype, uint32 offset, uint32 val);
     void setMem8(int memtype, uint32 offset, uint8 val);
 
-    Common::String decodeOp(uint32 address, int *size = nullptr);
-    Common::String disassembly(uint32 address);
+    static Common::String decodeOp(uint32 address, int *size = nullptr);
+    static Common::String disassembly(uint32 address);
 
-    Common::String opLog(const Common::Array<OpLog> &log);
+    static Common::String opLog(const Common::Array<OpLog> &log);
 
-    void printDisassembly(uint32 address);
+    static void printDisassembly(uint32 address);
+
+private:
 
 public:
+    bool _inUse = false;
+
     uint32 ESI = 0;
     byte *EBX = nullptr;
     Reg EAX;
     Reg EDX;
     Reg ECX;
     uint32 SP = 0;
-    Common::Array<byte> _stack;
-    Common::Array<byte> _stackT;
+    byte _stack[STACK_SIZE];
+    byte _stackT[STACK_SIZE];
 
-    CallDispatcher _callFuncs = nullptr;
-    void *_callingObject = nullptr;
+private:
+    MemAccess _readAccess;
+    MemAccess _writeAccess;
 
-    Common::HashMap<uint32, MemoryBlock> _memMap;
+public:
+    static CallDispatcher _callFuncs;
+    static void *_callingObject;
 
-    bool _interrupt = false;
-private:
-    MemoryBlock *_currentReadMemBlock = nullptr;
-    MemoryBlock *_currentWriteMemBlock = nullptr;
+    static Common::HashMap<uint32, MemoryBlock> _memMap;
+    static bool _interrupt;
+
+    static VM _threads[THREADS_COUNT];
+    static MemAccess _memAccess;
 };
 
 


Commit: 0affb7084fa75a71a06a8c34658331f9ed9e276c
    https://github.com/scummvm/scummvm/commit/0affb7084fa75a71a06a8c34658331f9ed9e276c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:25+01:00

Commit Message:
GAMOS: Disable and modify debug things

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 14c5d457b43..d1b8e6708bc 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -28,7 +28,6 @@
 #define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
 #define FORBIDDEN_SYMBOL_EXCEPTION_fclose
 #define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
-#define FORBIDDEN_SYMBOL_EXCEPTION_setbuf
 #define FORBIDDEN_SYMBOL_EXCEPTION_stdout
 
 
@@ -232,8 +231,6 @@ bool GamosEngine::loadModule(uint id) {
 
 	/* Complete me */
 
-	setbuf(stdout, 0);
-
 	bool prefixLoaded = false;
 	byte prevByte = 0;
 	bool doLoad = true;
@@ -409,7 +406,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 			DAT_004177f8 = 1;
 			ProcessScript(true, data, dataSize);
 			if (_needReload)
-				printf(" need reload from loadResHandler, CANT HAPPEN! \n ");
+				warning("needs reload from loadResHandler, CANT HAPPEN!");
 			DAT_004177f8 = 0;
 			FUN_00404fcc(pid);
 		}
@@ -456,7 +453,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_43) {
 		return loadRes43(pid, p1, p2, data, dataSize);
 	} else if (tp == RESTP_50) {
-		//printf("data 50 size %d\n", dataSize);
+		/* just ignore it? */
 	} else if (tp == RESTP_51) {
 		_soundSamples[pid].assign(data, data + dataSize);
 		//printf("sound  size %d\n", dataSize);
@@ -596,7 +593,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_thing1Count = dataStream.readUint32LE(); // c
 	_bkgUpdateSizes.x = dataStream.readUint32LE(); // 10
 	_bkgUpdateSizes.y = dataStream.readUint32LE(); // 14
-	dataStream.readUint32LE(); // 18
+	/* bkgbufferSize */ dataStream.readUint32LE(); // 18
 	uint32 actsCount = dataStream.readUint32LE(); // 1c
 	uint32 unk1Count = dataStream.readUint32LE(); // 20
 	uint32 imageCount = dataStream.readUint32LE(); // 24
@@ -1997,11 +1994,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			vm->EAX.val = _drawElements[ PTR_00417218->x ].spr->index == arg1 ? 1 : 0;
 		break;
 	case 3:
-		warning("func 3 %x check 0x10 \n", PTR_00417218->fld_4 & 0x90);
+		//warning("func 3 %x check 0x10", PTR_00417218->fld_4 & 0x90);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
 		break;
 	case 4:
-		warning("func 4 %x check 0x20 \n", PTR_00417218->fld_4 & 0xa0);
+		//warning("func 4 %x check 0x20", PTR_00417218->fld_4 & 0xa0);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0;
 		break;
 	case 5:
@@ -2011,13 +2008,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		break;
 	case 6:
 		arg1 = vm->pop32();
-		warning("func 6 %x check %x \n", PTR_00417218->fld_4 & 0x4f, arg1);
+		//warning("func 6 %x check %x", PTR_00417218->fld_4 & 0x4f, arg1);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
 		break;
 	case 13: {
 		VM::Reg regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef.ref, regRef.val);
-		warning("CallDispatcher 13 keycode %s\n", str.c_str());
+		//warning("CallDispatcher 13 keycode %s", str.c_str());
 		vm->EAX.val = 0;
 		break;
 	}


Commit: 6cf5df6de92799eba740a52da3aeba9cf66a3f5f
    https://github.com/scummvm/scummvm/commit/6cf5df6de92799eba740a52da3aeba9cf66a3f5f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:25+01:00

Commit Message:
GAMOS: Partially implement resources 0x60 and 0x61

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index d1b8e6708bc..81de1a92ebc 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -460,6 +460,22 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_52) {
 		return loadRes52(pid, data, dataSize);
 		//printf("midi  size %d\n", dataSize);
+	} else if (tp == RESTP_60) {
+		_dat60[pid].assign(data, data + dataSize);
+	} else if (tp == RESTP_61) {
+		Common::MemoryReadStream dataStream(data, dataSize, DisposeAfterUse::NO);
+		const int count = dataSize / 8;
+		_dat61[pid].resize(count);
+
+		for (int i = 0; i < count; i++) {
+			Dat61 &d = _dat61[pid][i];
+
+			d.x = dataStream.readSint16LE();
+			d.y = dataStream.readSint16LE();
+			d.v = dataStream.readUint16LE();
+
+			dataStream.skip(2);
+		}
 	} else if (tp == RESTP_XORSEQ0) {
 		loadXorSeq(data, dataSize, 0);
 	} else if (tp == RESTP_XORSEQ1) {
@@ -599,7 +615,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	uint32 imageCount = dataStream.readUint32LE(); // 24
 	uint32 soundCount = dataStream.readUint32LE(); // 28
 	uint32 midiCount = dataStream.readUint32LE(); // 2c
-	dataStream.readUint32LE(); // 30
+	uint32 dat6xCount = dataStream.readUint32LE(); // 30
 
 	_thing1Shift = 2;
 	for(int i = 2; i < 9; i++) {
@@ -634,6 +650,12 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_someActsArr.clear();
 	_someActsArr.resize(actsCount);
 
+	_dat60.clear();
+	_dat61.clear();
+
+	_dat60.resize(dat6xCount);
+	_dat61.resize(dat6xCount);
+
 	_loadedDataSize = 0;
 	VM::clearMemory();
 }
@@ -2011,6 +2033,10 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		//warning("func 6 %x check %x", PTR_00417218->fld_4 & 0x4f, arg1);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
 		break;
+	case 9:
+		arg1 = vm->pop32();
+		vm->EAX.val = FUN_004070f8(_dat60[arg1].data(), _dat60[arg1].size());
+		break;
 	case 13: {
 		VM::Reg regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef.ref, regRef.val);
@@ -2042,6 +2068,23 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = scriptFunc19(arg1);
 		break;
 
+	case 20: {
+		arg1 = vm->pop32();
+		for (const Dat61 &d : _dat61[arg1]) {
+			FUN_0040738c(d.v, d.x, d.y, true);
+		}
+		vm->EAX.val = FUN_004070f8(_dat60[arg1].data(), _dat60[arg1].size());
+	} break;
+
+	case 24: {
+		VM::Reg regRef = vm->popReg();
+		arg2 = vm->pop32();
+		const Dat61 &d = _dat61[arg2][0];
+		FUN_00407a68(vm, regRef.ref, regRef.val, d.v, d.x, d.y);
+
+		vm->EAX.val = 1;
+	} break;
+
 	case 25: {
 		arg1 = vm->pop32();
 		if (PTR_00417218->fld_5 != arg1) {
@@ -2430,6 +2473,129 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 
 }
 
+uint32 GamosEngine::FUN_004070f8(const byte *data, size_t dataSize) {
+	uint8 sv1 = BYTE_004177fc;
+	uint8 sv2 = BYTE_004177f6;
+	byte *sv3 = PTR_004173e8;
+	//uVar11 = DAT_0041723c;
+	//uVar10 = DAT_00417238;
+	uint8 sv6 = _preprocDataId;
+	int32 sv7 = DAT_0041722c;
+	int32 sv8 = DAT_00417228;
+	int32 sv9 = DAT_00417224;
+	int32 sv10 = DAT_00417220;
+	int sv11 = _curObjIndex;
+	Object *sv12 = PTR_00417218;
+	SomeAction *sv13 = PTR_00417214;
+
+	uint32 res = ProcessScript(true, data, dataSize);
+
+	BYTE_004177fc = sv1;
+	BYTE_004177f6 = sv2;
+	PTR_004173e8 = sv3;
+	//DAT_0041723c = uVar11;
+	//DAT_00417238 = uVar10;
+	_preprocDataId = sv6;
+	DAT_0041722c = sv7;
+	DAT_00417228 = sv8;
+	DAT_00417224 = sv9;
+	DAT_00417220 = sv10;
+	_curObjIndex = sv11;
+	PTR_00417218 = sv12;
+	PTR_00417214 = sv13;
+
+	return res;
+}
+
+void GamosEngine::FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, int32 x, int32 y) {
+	FUN_004023d8(PTR_00417218);
+	PTR_00417218->fld_3 |= 2;
+
+	while (true) {
+		byte ib = vm->getMem8(memtype, offset);
+		offset++;
+
+		if (ib == 0)
+			break;
+
+		if (ib == 0xf) {
+			byte flg = vm->getMem8(memtype, offset);
+			offset++;
+			byte b2 = vm->getMem8(memtype, offset);
+			offset++;
+
+			if ((flg & 0x70) == 0x20) {
+				byte funcid = vm->getMem8(memtype, offset);
+				offset++;
+				warning("CHECKIT and write funcid %d", funcid);
+			} else {
+				if ((flg & 0x70) == 0 || (flg & 0x70) == 0x10) {
+					int32 boff = 0;
+					byte btp = VM::REF_EDI;
+
+					if ((flg & 0x70) == 0x10)
+						btp = VM::REF_EBX;
+
+					if ((flg & 0x80) == 0) {
+						boff = vm->getMem8(memtype, offset);
+						offset++;
+					} else {
+						boff = vm->getMem32(memtype, offset);
+						offset += 4;
+					}
+
+					warning("FUN_00407a68 unimplemented part");
+
+					switch( flg & 7 ) {
+					case 0:
+						break;
+
+					case 1:
+						break;
+
+					case 2:
+						break;
+
+					case 3:
+						break;
+
+					case 4:
+						break;
+
+					case 5:
+						break;
+					}
+				}
+			}
+		} else {
+			FUN_00407588(ib, val, &x, y);
+		}
+	}
+
+}
+
+Object *GamosEngine::FUN_00407588(int32 seq, int32 spr, int32 *pX, int32 y) {
+	Object *obj = getFreeObject();
+	obj->flags |= 0xe0;
+	obj->actID = 0;
+	obj->fld_2 = 1;
+	obj->fld_3 = PTR_00417218->fld_5;
+	obj->fld_4 = 0xff;
+	obj->fld_5 = 0xff;
+	obj->pos = _curObjIndex & 0xff;
+	obj->blk = (_curObjIndex >> 8) & 0xff;
+	obj->x = *pX;
+	obj->y = y;
+	obj->spr = &_sprites[spr];
+	obj->pImg = &_sprites[spr].sequences[0][seq - _sprites[spr].field_1];
+
+	*pX += obj->pImg->image->surface.w - obj->pImg->xoffset;
+
+	addDirtRectOnObject(obj);
+	return obj;
+}
+
+}
 
 
 void GamosEngine::FUN_00404fcc(int32 id) {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index bf913c80522..85de574a1e8 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -90,6 +90,8 @@ enum RESTYPE {
 	RESTP_50 = 0x50,
 	RESTP_51 = 0x51,
 	RESTP_52 = 0x52,
+	RESTP_60 = 0x60,
+	RESTP_61 = 0x61,
 	RESTP_XORSEQ0 = 0x7c,
 	RESTP_XORSEQ1 = 0x7d,
 	RESTP_XORSEQ2 = 0x7e,
@@ -190,6 +192,12 @@ struct Object {
 	Common::Array<byte> storage;
 };
 
+struct Dat61 {
+	int16 x = 0;
+	int16 y = 0;
+	uint16 v = 0;
+};
+
 
 class GamosEngine : public Engine {
 friend class MoviePlayer;
@@ -249,6 +257,9 @@ private:
 
 	Common::Array< Common::Array<byte> > _soundSamples;
 
+	Common::Array< Common::Array<byte> > _dat60;
+	Common::Array< Common::Array<Dat61> > _dat61;
+
 	uint32 _delayTime = 0;
 	uint32 _lastTimeStamp = 0;
 
@@ -461,11 +472,17 @@ protected:
 	void FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1);
 	bool FUN_00409600(Object *obj, Common::Point pos);
 
+	uint32 FUN_004070f8(const byte *data, size_t dataSize);
+
 	void setNeedReload() {
 		_needReload = true;
 		VM::_interrupt = true;
 	};
 
+	Object *FUN_00407588(int32 seq, int32 spr, int32 *pX, int32 y);
+
+	void FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, int32 x, int32 y);
+
 	void vmCallDispatcher(VM *vm, uint32 funcID);
 
 


Commit: 51a705480f658815b747d226ecdc657fb27a640b
    https://github.com/scummvm/scummvm/commit/51a705480f658815b747d226ecdc657fb27a640b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:25+01:00

Commit Message:
GAMOS: Change keycodes conversion

Changed paths:
  A engines/gamos/keycodes.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/keycodes.cpp
    engines/gamos/proc.cpp
    engines/gamos/proc.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 81de1a92ebc..827e0167037 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -897,7 +897,7 @@ void GamosEngine::readData2(const RawData &data) {
 	_mouseCursorImgId = dataStream.readUint32LE(); //0x3c
 	//0x40
 	for (int i = 0; i < 12; i++) {
-		_messageProc._keyCodes[i] = _winkeyMap[dataStream.readByte()];
+		_messageProc._keyCodes[i] = dataStream.readByte();
 	}
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 85de574a1e8..d97f35d744e 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -43,6 +43,8 @@
 
 #include "gamos/pool.h"
 
+#include "gamos/keycodes.h"
+
 #include "gamos/proc.h"
 #include "gamos/music.h"
 #include "gamos/movie.h"
@@ -346,15 +348,12 @@ private:
 
 	uint8 DAT_00417805 = 0;
 
-	uint16 RawKeyCode = 0;
+	uint8 RawKeyCode = 0;
 
 	Common::Array<Common::Rect> _dirtyRects;
 
 	bool _needReload = false;
 
-private:
-	static const uint16 _winkeyMap[256];
-
 protected:
 	// Engine APIs
 	Common::Error run() override;
diff --git a/engines/gamos/keycodes.cpp b/engines/gamos/keycodes.cpp
index 491b56923d7..58e65b92114 100644
--- a/engines/gamos/keycodes.cpp
+++ b/engines/gamos/keycodes.cpp
@@ -22,263 +22,275 @@
 #include "gamos/gamos.h"
 namespace Gamos {
 
-const uint16 GamosEngine::_winkeyMap[256] = {
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_CANCEL,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_BACKSPACE,
-    Common::KEYCODE_TAB,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_RETURN,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_MENU,
-    Common::KEYCODE_PAUSE,
-    Common::KEYCODE_CAPSLOCK,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_ESCAPE,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_SPACE,
-    Common::KEYCODE_PAGEUP,
-    Common::KEYCODE_PAGEDOWN,
-    Common::KEYCODE_END,
-    Common::KEYCODE_HOME,
-    Common::KEYCODE_LEFT,
-    Common::KEYCODE_UP,
-    Common::KEYCODE_RIGHT,
-    Common::KEYCODE_DOWN,
-    Common::KEYCODE_SELECT,
-    Common::KEYCODE_PRINT,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INSERT,
-    Common::KEYCODE_DELETE,
-    Common::KEYCODE_HELP,
-    Common::KEYCODE_0,
-    Common::KEYCODE_1,
-    Common::KEYCODE_2,
-    Common::KEYCODE_3,
-    Common::KEYCODE_4,
-    Common::KEYCODE_5,
-    Common::KEYCODE_6,
-    Common::KEYCODE_7,
-    Common::KEYCODE_8,
-    Common::KEYCODE_9,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_a,
-    Common::KEYCODE_b,
-    Common::KEYCODE_c,
-    Common::KEYCODE_d,
-    Common::KEYCODE_e,
-    Common::KEYCODE_f,
-    Common::KEYCODE_g,
-    Common::KEYCODE_h,
-    Common::KEYCODE_i,
-    Common::KEYCODE_j,
-    Common::KEYCODE_k,
-    Common::KEYCODE_l,
-    Common::KEYCODE_m,
-    Common::KEYCODE_n,
-    Common::KEYCODE_o,
-    Common::KEYCODE_p,
-    Common::KEYCODE_q,
-    Common::KEYCODE_r,
-    Common::KEYCODE_s,
-    Common::KEYCODE_t,
-    Common::KEYCODE_u,
-    Common::KEYCODE_v,
-    Common::KEYCODE_w,
-    Common::KEYCODE_x,
-    Common::KEYCODE_y,
-    Common::KEYCODE_z,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_SLEEP,
-    Common::KEYCODE_KP0,
-    Common::KEYCODE_KP1,
-    Common::KEYCODE_KP2,
-    Common::KEYCODE_KP3,
-    Common::KEYCODE_KP4,
-    Common::KEYCODE_KP5,
-    Common::KEYCODE_KP6,
-    Common::KEYCODE_KP7,
-    Common::KEYCODE_KP8,
-    Common::KEYCODE_KP9,
-    Common::KEYCODE_KP_MULTIPLY,
-    Common::KEYCODE_KP_PLUS,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_KP_MINUS,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_KP_DIVIDE,
-    Common::KEYCODE_F1,
-    Common::KEYCODE_F2,
-    Common::KEYCODE_F3,
-    Common::KEYCODE_F4,
-    Common::KEYCODE_F5,
-    Common::KEYCODE_F6,
-    Common::KEYCODE_F7,
-    Common::KEYCODE_F8,
-    Common::KEYCODE_F9,
-    Common::KEYCODE_F10,
-    Common::KEYCODE_F11,
-    Common::KEYCODE_F12,
-    Common::KEYCODE_F13,
-    Common::KEYCODE_F14,
-    Common::KEYCODE_F15,
-    Common::KEYCODE_F16,
-    Common::KEYCODE_F17,
-    Common::KEYCODE_F18,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_NUMLOCK,
-    Common::KEYCODE_SCROLLOCK,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID,
-    Common::KEYCODE_INVALID
-};
+KeyCodes KeyCodes::_instance;
+
+KeyCodes::KeyCodes() {
+    for (int16 i = 0; i < Common::KEYCODE_LAST; i++) {
+        _winCodes[i] = WIN_INVALID;
+    }
+
+    for (int i = 0; i < 256; i++) {
+        _scummCodes[i] = Common::KEYCODE_INVALID;
+    }
+
+    _winCodes[Common::KEYCODE_BACKSPACE] = WIN_BACK;
+    _winCodes[Common::KEYCODE_TAB] = WIN_TAB;
+    _winCodes[Common::KEYCODE_CLEAR] = WIN_CLEAR;
+    _winCodes[Common::KEYCODE_RETURN] = WIN_RETURN;
+    _winCodes[Common::KEYCODE_PAUSE] = WIN_PAUSE;
+    _winCodes[Common::KEYCODE_ESCAPE] = WIN_ESCAPE;
+    _winCodes[Common::KEYCODE_SPACE] = WIN_SPACE;
+    _winCodes[Common::KEYCODE_QUOTE] = WIN_OEM_7;
+    _winCodes[Common::KEYCODE_COMMA] = WIN_OEM_COMMA;
+    _winCodes[Common::KEYCODE_MINUS] = WIN_OEM_MINUS;
+    _winCodes[Common::KEYCODE_PERIOD] = WIN_OEM_PERIOD;
+    _winCodes[Common::KEYCODE_SLASH] = WIN_OEM_2;
+    _winCodes[Common::KEYCODE_0] = WIN_0;
+    _winCodes[Common::KEYCODE_1] = WIN_1;
+    _winCodes[Common::KEYCODE_2] = WIN_2;
+    _winCodes[Common::KEYCODE_3] = WIN_3;
+    _winCodes[Common::KEYCODE_4] = WIN_4;
+    _winCodes[Common::KEYCODE_5] = WIN_5;
+    _winCodes[Common::KEYCODE_6] = WIN_6;
+    _winCodes[Common::KEYCODE_7] = WIN_7;
+    _winCodes[Common::KEYCODE_8] = WIN_8;
+    _winCodes[Common::KEYCODE_9] = WIN_9;
+    _winCodes[Common::KEYCODE_SEMICOLON] = WIN_OEM_1;
+    _winCodes[Common::KEYCODE_EQUALS] = WIN_OEM_PLUS;
+    _winCodes[Common::KEYCODE_LEFTBRACKET] = WIN_OEM_4;
+    _winCodes[Common::KEYCODE_BACKSLASH] = WIN_OEM_5;
+    _winCodes[Common::KEYCODE_RIGHTBRACKET] = WIN_OEM_6;
+    _winCodes[Common::KEYCODE_BACKQUOTE] = WIN_OEM_3;
+    _winCodes[Common::KEYCODE_a] = WIN_A;
+    _winCodes[Common::KEYCODE_b] = WIN_B;
+    _winCodes[Common::KEYCODE_c] = WIN_C;
+    _winCodes[Common::KEYCODE_d] = WIN_D;
+    _winCodes[Common::KEYCODE_e] = WIN_E;
+    _winCodes[Common::KEYCODE_f] = WIN_F;
+    _winCodes[Common::KEYCODE_g] = WIN_G;
+    _winCodes[Common::KEYCODE_h] = WIN_H;
+    _winCodes[Common::KEYCODE_i] = WIN_I;
+    _winCodes[Common::KEYCODE_j] = WIN_J;
+    _winCodes[Common::KEYCODE_k] = WIN_K;
+    _winCodes[Common::KEYCODE_l] = WIN_L;
+    _winCodes[Common::KEYCODE_m] = WIN_M;
+    _winCodes[Common::KEYCODE_n] = WIN_N;
+    _winCodes[Common::KEYCODE_o] = WIN_O;
+    _winCodes[Common::KEYCODE_p] = WIN_P;
+    _winCodes[Common::KEYCODE_q] = WIN_Q;
+    _winCodes[Common::KEYCODE_r] = WIN_R;
+    _winCodes[Common::KEYCODE_s] = WIN_S;
+    _winCodes[Common::KEYCODE_t] = WIN_T;
+    _winCodes[Common::KEYCODE_u] = WIN_U;
+    _winCodes[Common::KEYCODE_v] = WIN_V;
+    _winCodes[Common::KEYCODE_w] = WIN_W;
+    _winCodes[Common::KEYCODE_x] = WIN_X;
+    _winCodes[Common::KEYCODE_y] = WIN_Y;
+    _winCodes[Common::KEYCODE_z] = WIN_Z;
+    _winCodes[Common::KEYCODE_DELETE] = WIN_DELETE;
+    _winCodes[Common::KEYCODE_KP_PERIOD] = WIN_DECIMAL;
+    _winCodes[Common::KEYCODE_KP_DIVIDE] = WIN_DIVIDE;
+    _winCodes[Common::KEYCODE_KP_MULTIPLY] = WIN_MULTIPLY;
+    _winCodes[Common::KEYCODE_KP_MINUS] = WIN_SUBTRACT;
+    _winCodes[Common::KEYCODE_KP_PLUS] = WIN_ADD;
+    _winCodes[Common::KEYCODE_KP_ENTER] = WIN_RETURN;
+    _winCodes[Common::KEYCODE_KP_EQUALS] = WIN_CLEAR;
+    _winCodes[Common::KEYCODE_UP] = WIN_UP;
+    _winCodes[Common::KEYCODE_DOWN] = WIN_DOWN;
+    _winCodes[Common::KEYCODE_RIGHT] = WIN_RIGHT;
+    _winCodes[Common::KEYCODE_LEFT] = WIN_LEFT;
+    _winCodes[Common::KEYCODE_INSERT] = WIN_INSERT;
+    _winCodes[Common::KEYCODE_HOME] = WIN_HOME;
+    _winCodes[Common::KEYCODE_END] = WIN_END;
+    _winCodes[Common::KEYCODE_PAGEUP] = WIN_PRIOR;
+    _winCodes[Common::KEYCODE_PAGEDOWN] = WIN_NEXT;
+    _winCodes[Common::KEYCODE_F1] = WIN_F1;
+    _winCodes[Common::KEYCODE_F2] = WIN_F2;
+    _winCodes[Common::KEYCODE_F3] = WIN_F3;
+    _winCodes[Common::KEYCODE_F4] = WIN_F4;
+    _winCodes[Common::KEYCODE_F5] = WIN_F5;
+    _winCodes[Common::KEYCODE_F6] = WIN_F6;
+    _winCodes[Common::KEYCODE_F7] = WIN_F7;
+    _winCodes[Common::KEYCODE_F8] = WIN_F8;
+    _winCodes[Common::KEYCODE_F9] = WIN_F9;
+    _winCodes[Common::KEYCODE_F10] = WIN_F10;
+    _winCodes[Common::KEYCODE_F11] = WIN_F11;
+    _winCodes[Common::KEYCODE_F12] = WIN_F12;
+    _winCodes[Common::KEYCODE_F13] = WIN_F13;
+    _winCodes[Common::KEYCODE_F14] = WIN_F14;
+    _winCodes[Common::KEYCODE_F15] = WIN_F15;
+    _winCodes[Common::KEYCODE_CAPSLOCK] = WIN_CAPITAL;
+    _winCodes[Common::KEYCODE_RSHIFT] = WIN_RSHIFT;
+    _winCodes[Common::KEYCODE_LSHIFT] = WIN_LSHIFT;
+    _winCodes[Common::KEYCODE_RCTRL] = WIN_RCONTROL;
+    _winCodes[Common::KEYCODE_LCTRL] = WIN_LCONTROL;
+    _winCodes[Common::KEYCODE_RALT] = WIN_RMENU;
+    _winCodes[Common::KEYCODE_LALT] = WIN_LMENU;
+    _winCodes[Common::KEYCODE_SCROLLOCK] = WIN_SCROLL;
+    _winCodes[Common::KEYCODE_NUMLOCK] = WIN_NUMLOCK;
+    _winCodes[Common::KEYCODE_LSUPER] = WIN_LWIN;
+    _winCodes[Common::KEYCODE_RSUPER] = WIN_RWIN;
+    _winCodes[Common::KEYCODE_PRINT] = WIN_SNAPSHOT;
+    _winCodes[Common::KEYCODE_COMPOSE] = WIN_APPS;
+    _winCodes[Common::KEYCODE_KP0] = WIN_NUMPAD0;
+    _winCodes[Common::KEYCODE_KP1] = WIN_NUMPAD1;
+    _winCodes[Common::KEYCODE_KP2] = WIN_NUMPAD2;
+    _winCodes[Common::KEYCODE_KP3] = WIN_NUMPAD3;
+    _winCodes[Common::KEYCODE_KP4] = WIN_NUMPAD4;
+    _winCodes[Common::KEYCODE_KP5] = WIN_NUMPAD5;
+    _winCodes[Common::KEYCODE_KP6] = WIN_NUMPAD6;
+    _winCodes[Common::KEYCODE_KP7] = WIN_NUMPAD7;
+    _winCodes[Common::KEYCODE_KP8] = WIN_NUMPAD8;
+    _winCodes[Common::KEYCODE_KP9] = WIN_NUMPAD9;
+    _winCodes[Common::KEYCODE_TILDE] = WIN_OEM_3;
+    _winCodes[Common::KEYCODE_F16] = WIN_F16;
+    _winCodes[Common::KEYCODE_F17] = WIN_F17;
+    _winCodes[Common::KEYCODE_F18] = WIN_F18;
+    _winCodes[Common::KEYCODE_SLEEP] = WIN_SLEEP;
+    _winCodes[Common::KEYCODE_VOLUMEUP] = WIN_VOLUME_UP;
+    _winCodes[Common::KEYCODE_VOLUMEDOWN] = WIN_VOLUME_DOWN;
+    _winCodes[Common::KEYCODE_AUDIONEXT] = WIN_MEDIA_NEXT_TRACK;
+    _winCodes[Common::KEYCODE_AUDIOPREV] = WIN_MEDIA_PREV_TRACK;
+    _winCodes[Common::KEYCODE_AUDIOSTOP] = WIN_MEDIA_STOP;
+    _winCodes[Common::KEYCODE_AUDIOPLAYPAUSE] = WIN_MEDIA_PLAY_PAUSE;
+    _winCodes[Common::KEYCODE_AUDIOMUTE] = WIN_VOLUME_MUTE;
+    _winCodes[Common::KEYCODE_AC_SEARCH] = WIN_BROWSER_SEARCH;
+    _winCodes[Common::KEYCODE_AC_HOME] = WIN_BROWSER_HOME;
+    _winCodes[Common::KEYCODE_AC_BACK] = WIN_BROWSER_BACK;
+    _winCodes[Common::KEYCODE_AC_FORWARD] = WIN_BROWSER_FORWARD;
+    _winCodes[Common::KEYCODE_AC_STOP] = WIN_BROWSER_STOP;
+    _winCodes[Common::KEYCODE_AC_REFRESH] = WIN_BROWSER_REFRESH;
+    _winCodes[Common::KEYCODE_AC_BOOKMARKS] = WIN_BROWSER_FAVORITES;
+
+
+    _scummCodes[WIN_BACK] = Common::KEYCODE_BACKSPACE;
+    _scummCodes[WIN_TAB] = Common::KEYCODE_TAB;
+    _scummCodes[WIN_CLEAR] = Common::KEYCODE_CLEAR;
+    _scummCodes[WIN_RETURN] = Common::KEYCODE_RETURN;
+    _scummCodes[WIN_PAUSE] = Common::KEYCODE_PAUSE;
+    _scummCodes[WIN_ESCAPE] = Common::KEYCODE_ESCAPE;
+    _scummCodes[WIN_SPACE] = Common::KEYCODE_SPACE;
+    _scummCodes[WIN_OEM_7] = Common::KEYCODE_QUOTE;
+    _scummCodes[WIN_OEM_COMMA] = Common::KEYCODE_COMMA;
+    _scummCodes[WIN_OEM_MINUS] = Common::KEYCODE_MINUS;
+    _scummCodes[WIN_OEM_PERIOD] = Common::KEYCODE_PERIOD;
+    _scummCodes[WIN_OEM_2] = Common::KEYCODE_SLASH;
+    _scummCodes[WIN_0] = Common::KEYCODE_0;
+    _scummCodes[WIN_1] = Common::KEYCODE_1;
+    _scummCodes[WIN_2] = Common::KEYCODE_2;
+    _scummCodes[WIN_3] = Common::KEYCODE_3;
+    _scummCodes[WIN_4] = Common::KEYCODE_4;
+    _scummCodes[WIN_5] = Common::KEYCODE_5;
+    _scummCodes[WIN_6] = Common::KEYCODE_6;
+    _scummCodes[WIN_7] = Common::KEYCODE_7;
+    _scummCodes[WIN_8] = Common::KEYCODE_8;
+    _scummCodes[WIN_9] = Common::KEYCODE_9;
+    _scummCodes[WIN_OEM_1] = Common::KEYCODE_SEMICOLON;
+    _scummCodes[WIN_OEM_PLUS] = Common::KEYCODE_EQUALS;
+    _scummCodes[WIN_OEM_4] = Common::KEYCODE_LEFTBRACKET;
+    _scummCodes[WIN_OEM_5] = Common::KEYCODE_BACKSLASH;
+    _scummCodes[WIN_OEM_6] = Common::KEYCODE_RIGHTBRACKET;
+    _scummCodes[WIN_OEM_3] = Common::KEYCODE_BACKQUOTE;
+    _scummCodes[WIN_A] = Common::KEYCODE_a;
+    _scummCodes[WIN_B] = Common::KEYCODE_b;
+    _scummCodes[WIN_C] = Common::KEYCODE_c;
+    _scummCodes[WIN_D] = Common::KEYCODE_d;
+    _scummCodes[WIN_E] = Common::KEYCODE_e;
+    _scummCodes[WIN_F] = Common::KEYCODE_f;
+    _scummCodes[WIN_G] = Common::KEYCODE_g;
+    _scummCodes[WIN_H] = Common::KEYCODE_h;
+    _scummCodes[WIN_I] = Common::KEYCODE_i;
+    _scummCodes[WIN_J] = Common::KEYCODE_j;
+    _scummCodes[WIN_K] = Common::KEYCODE_k;
+    _scummCodes[WIN_L] = Common::KEYCODE_l;
+    _scummCodes[WIN_M] = Common::KEYCODE_m;
+    _scummCodes[WIN_N] = Common::KEYCODE_n;
+    _scummCodes[WIN_O] = Common::KEYCODE_o;
+    _scummCodes[WIN_P] = Common::KEYCODE_p;
+    _scummCodes[WIN_Q] = Common::KEYCODE_q;
+    _scummCodes[WIN_R] = Common::KEYCODE_r;
+    _scummCodes[WIN_S] = Common::KEYCODE_s;
+    _scummCodes[WIN_T] = Common::KEYCODE_t;
+    _scummCodes[WIN_U] = Common::KEYCODE_u;
+    _scummCodes[WIN_V] = Common::KEYCODE_v;
+    _scummCodes[WIN_W] = Common::KEYCODE_w;
+    _scummCodes[WIN_X] = Common::KEYCODE_x;
+    _scummCodes[WIN_Y] = Common::KEYCODE_y;
+    _scummCodes[WIN_Z] = Common::KEYCODE_z;
+    _scummCodes[WIN_DELETE] = Common::KEYCODE_DELETE;
+    _scummCodes[WIN_DECIMAL] = Common::KEYCODE_KP_PERIOD;
+    _scummCodes[WIN_DIVIDE] = Common::KEYCODE_KP_DIVIDE;
+    _scummCodes[WIN_MULTIPLY] = Common::KEYCODE_KP_MULTIPLY;
+    _scummCodes[WIN_SUBTRACT] = Common::KEYCODE_KP_MINUS;
+    _scummCodes[WIN_ADD] = Common::KEYCODE_KP_PLUS;
+    _scummCodes[WIN_RETURN] = Common::KEYCODE_KP_ENTER;
+    _scummCodes[WIN_CLEAR] = Common::KEYCODE_KP_EQUALS;
+    _scummCodes[WIN_UP] = Common::KEYCODE_UP;
+    _scummCodes[WIN_DOWN] = Common::KEYCODE_DOWN;
+    _scummCodes[WIN_RIGHT] = Common::KEYCODE_RIGHT;
+    _scummCodes[WIN_LEFT] = Common::KEYCODE_LEFT;
+    _scummCodes[WIN_INSERT] = Common::KEYCODE_INSERT;
+    _scummCodes[WIN_HOME] = Common::KEYCODE_HOME;
+    _scummCodes[WIN_END] = Common::KEYCODE_END;
+    _scummCodes[WIN_PRIOR] = Common::KEYCODE_PAGEUP;
+    _scummCodes[WIN_NEXT] = Common::KEYCODE_PAGEDOWN;
+    _scummCodes[WIN_F1] = Common::KEYCODE_F1;
+    _scummCodes[WIN_F2] = Common::KEYCODE_F2;
+    _scummCodes[WIN_F3] = Common::KEYCODE_F3;
+    _scummCodes[WIN_F4] = Common::KEYCODE_F4;
+    _scummCodes[WIN_F5] = Common::KEYCODE_F5;
+    _scummCodes[WIN_F6] = Common::KEYCODE_F6;
+    _scummCodes[WIN_F7] = Common::KEYCODE_F7;
+    _scummCodes[WIN_F8] = Common::KEYCODE_F8;
+    _scummCodes[WIN_F9] = Common::KEYCODE_F9;
+    _scummCodes[WIN_F10] = Common::KEYCODE_F10;
+    _scummCodes[WIN_F11] = Common::KEYCODE_F11;
+    _scummCodes[WIN_F12] = Common::KEYCODE_F12;
+    _scummCodes[WIN_F13] = Common::KEYCODE_F13;
+    _scummCodes[WIN_F14] = Common::KEYCODE_F14;
+    _scummCodes[WIN_F15] = Common::KEYCODE_F15;
+    _scummCodes[WIN_CAPITAL] = Common::KEYCODE_CAPSLOCK;
+    _scummCodes[WIN_RSHIFT] = Common::KEYCODE_RSHIFT;
+    _scummCodes[WIN_LSHIFT] = Common::KEYCODE_LSHIFT;
+    _scummCodes[WIN_RCONTROL] = Common::KEYCODE_RCTRL;
+    _scummCodes[WIN_LCONTROL] = Common::KEYCODE_LCTRL;
+    _scummCodes[WIN_RMENU] = Common::KEYCODE_RALT;
+    _scummCodes[WIN_LMENU] = Common::KEYCODE_LALT;
+    _scummCodes[WIN_SCROLL] = Common::KEYCODE_SCROLLOCK;
+    _scummCodes[WIN_NUMLOCK] = Common::KEYCODE_NUMLOCK;
+    _scummCodes[WIN_LWIN] = Common::KEYCODE_LSUPER;
+    _scummCodes[WIN_RWIN] = Common::KEYCODE_RSUPER;
+    _scummCodes[WIN_SNAPSHOT] = Common::KEYCODE_PRINT;
+    _scummCodes[WIN_APPS] = Common::KEYCODE_COMPOSE;
+    _scummCodes[WIN_NUMPAD0] = Common::KEYCODE_KP0;
+    _scummCodes[WIN_NUMPAD1] = Common::KEYCODE_KP1;
+    _scummCodes[WIN_NUMPAD2] = Common::KEYCODE_KP2;
+    _scummCodes[WIN_NUMPAD3] = Common::KEYCODE_KP3;
+    _scummCodes[WIN_NUMPAD4] = Common::KEYCODE_KP4;
+    _scummCodes[WIN_NUMPAD5] = Common::KEYCODE_KP5;
+    _scummCodes[WIN_NUMPAD6] = Common::KEYCODE_KP6;
+    _scummCodes[WIN_NUMPAD7] = Common::KEYCODE_KP7;
+    _scummCodes[WIN_NUMPAD8] = Common::KEYCODE_KP8;
+    _scummCodes[WIN_NUMPAD9] = Common::KEYCODE_KP9;
+    _scummCodes[WIN_OEM_3] = Common::KEYCODE_TILDE;
+    _scummCodes[WIN_F16] = Common::KEYCODE_F16;
+    _scummCodes[WIN_F17] = Common::KEYCODE_F17;
+    _scummCodes[WIN_F18] = Common::KEYCODE_F18;
+    _scummCodes[WIN_SLEEP] = Common::KEYCODE_SLEEP;
+    _scummCodes[WIN_VOLUME_UP] = Common::KEYCODE_VOLUMEUP;
+    _scummCodes[WIN_VOLUME_DOWN] = Common::KEYCODE_VOLUMEDOWN;
+    _scummCodes[WIN_MEDIA_NEXT_TRACK] = Common::KEYCODE_AUDIONEXT;
+    _scummCodes[WIN_MEDIA_PREV_TRACK] = Common::KEYCODE_AUDIOPREV;
+    _scummCodes[WIN_MEDIA_STOP] = Common::KEYCODE_AUDIOSTOP;
+    _scummCodes[WIN_MEDIA_PLAY_PAUSE] = Common::KEYCODE_AUDIOPLAYPAUSE;
+    _scummCodes[WIN_VOLUME_MUTE] = Common::KEYCODE_AUDIOMUTE;
+    _scummCodes[WIN_BROWSER_SEARCH] = Common::KEYCODE_AC_SEARCH;
+    _scummCodes[WIN_BROWSER_HOME] = Common::KEYCODE_AC_HOME;
+    _scummCodes[WIN_BROWSER_BACK] = Common::KEYCODE_AC_BACK;
+    _scummCodes[WIN_BROWSER_FORWARD] = Common::KEYCODE_AC_FORWARD;
+    _scummCodes[WIN_BROWSER_STOP] = Common::KEYCODE_AC_STOP;
+    _scummCodes[WIN_BROWSER_REFRESH] = Common::KEYCODE_AC_REFRESH;
+    _scummCodes[WIN_BROWSER_FAVORITES] = Common::KEYCODE_AC_BOOKMARKS;
+}
 
 }
diff --git a/engines/gamos/keycodes.h b/engines/gamos/keycodes.h
new file mode 100644
index 00000000000..a4ad1a73936
--- /dev/null
+++ b/engines/gamos/keycodes.h
@@ -0,0 +1,280 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_KEYCODES_H
+#define GAMOS_KEYCODES_H
+
+#include "common/keyboard.h"
+
+namespace Gamos {
+
+class KeyCodes {
+
+public:
+    enum {
+        WIN_INVALID = 0,
+
+        WIN_LBUTTON = 0x01,
+        WIN_RBUTTON = 0x02,
+        WIN_CANCEL = 0x03,
+        WIN_MBUTTON = 0x04,
+        WIN_XBUTTON1 = 0x05,
+        WIN_XBUTTON2 = 0x06,
+        WIN_BACK = 0x08,
+        WIN_TAB = 0x09,
+        WIN_CLEAR = 0x0C,
+        WIN_RETURN = 0x0D,
+        WIN_SHIFT = 0x10,
+        WIN_CONTROL = 0x11,
+        WIN_MENU = 0x12,
+        WIN_PAUSE = 0x13,
+        WIN_CAPITAL = 0x14,
+        WIN_KANA = 0x15,
+        WIN_JUNJA = 0x17,
+        WIN_FINAL = 0x18,
+        WIN_KANJI = 0x19,
+        WIN_ESCAPE = 0x1B,
+        WIN_CONVERT = 0x1C,
+        WIN_NONCONVERT = 0x1D,
+        WIN_ACCEPT = 0x1E,
+        WIN_MODECHANGE = 0x1F,
+        WIN_SPACE = 0x20,
+        WIN_PRIOR = 0x21,
+        WIN_NEXT = 0x22,
+        WIN_END = 0x23,
+        WIN_HOME = 0x24,
+        WIN_LEFT = 0x25,
+        WIN_UP = 0x26,
+        WIN_RIGHT = 0x27,
+        WIN_DOWN = 0x28,
+        WIN_SELECT = 0x29,
+        WIN_PRINT = 0x2A,
+        WIN_EXECUTE = 0x2B,
+        WIN_SNAPSHOT = 0x2C,
+        WIN_INSERT = 0x2D,
+        WIN_DELETE = 0x2E,
+        WIN_HELP = 0x2F,
+        WIN_0 = 0x30,
+        WIN_1 = 0x31,
+        WIN_2 = 0x32,
+        WIN_3 = 0x33,
+        WIN_4 = 0x34,
+        WIN_5 = 0x35,
+        WIN_6 = 0x36,
+        WIN_7 = 0x37,
+        WIN_8 = 0x38,
+        WIN_9 = 0x39,
+        WIN_A = 0x41,
+        WIN_B = 0x42,
+        WIN_C = 0x43,
+        WIN_D = 0x44,
+        WIN_E = 0x45,
+        WIN_F = 0x46,
+        WIN_G = 0x47,
+        WIN_H = 0x48,
+        WIN_I = 0x49,
+        WIN_J = 0x4A,
+        WIN_K = 0x4B,
+        WIN_L = 0x4C,
+        WIN_M = 0x4D,
+        WIN_N = 0x4E,
+        WIN_O = 0x4F,
+        WIN_P = 0x50,
+        WIN_Q = 0x51,
+        WIN_R = 0x52,
+        WIN_S = 0x53,
+        WIN_T = 0x54,
+        WIN_U = 0x55,
+        WIN_V = 0x56,
+        WIN_W = 0x57,
+        WIN_X = 0x58,
+        WIN_Y = 0x59,
+        WIN_Z = 0x5A,
+        WIN_LWIN = 0x5B,
+        WIN_RWIN = 0x5C,
+        WIN_APPS = 0x5D,
+        WIN_SLEEP = 0x5F,
+        WIN_NUMPAD0 = 0x60,
+        WIN_NUMPAD1 = 0x61,
+        WIN_NUMPAD2 = 0x62,
+        WIN_NUMPAD3 = 0x63,
+        WIN_NUMPAD4 = 0x64,
+        WIN_NUMPAD5 = 0x65,
+        WIN_NUMPAD6 = 0x66,
+        WIN_NUMPAD7 = 0x67,
+        WIN_NUMPAD8 = 0x68,
+        WIN_NUMPAD9 = 0x69,
+        WIN_MULTIPLY = 0x6A,
+        WIN_ADD = 0x6B,
+        WIN_SEPARATOR = 0x6C,
+        WIN_SUBTRACT = 0x6D,
+        WIN_DECIMAL = 0x6E,
+        WIN_DIVIDE = 0x6F,
+        WIN_F1 = 0x70,
+        WIN_F2 = 0x71,
+        WIN_F3 = 0x72,
+        WIN_F4 = 0x73,
+        WIN_F5 = 0x74,
+        WIN_F6 = 0x75,
+        WIN_F7 = 0x76,
+        WIN_F8 = 0x77,
+        WIN_F9 = 0x78,
+        WIN_F10 = 0x79,
+        WIN_F11 = 0x7A,
+        WIN_F12 = 0x7B,
+        WIN_F13 = 0x7C,
+        WIN_F14 = 0x7D,
+        WIN_F15 = 0x7E,
+        WIN_F16 = 0x7F,
+        WIN_F17 = 0x80,
+        WIN_F18 = 0x81,
+        WIN_F19 = 0x82,
+        WIN_F20 = 0x83,
+        WIN_F21 = 0x84,
+        WIN_F22 = 0x85,
+        WIN_F23 = 0x86,
+        WIN_F24 = 0x87,
+        WIN_NAVIGATION_VIEW = 0x88,
+        WIN_NAVIGATION_MENU = 0x89,
+        WIN_NAVIGATION_UP = 0x8A,
+        WIN_NAVIGATION_DOWN = 0x8B,
+        WIN_NAVIGATION_LEFT = 0x8C,
+        WIN_NAVIGATION_RIGHT = 0x8D,
+        WIN_NAVIGATION_ACCEPT = 0x8E,
+        WIN_NAVIGATION_CANCEL = 0x8F,
+        WIN_NUMLOCK = 0x90,
+        WIN_SCROLL = 0x91,
+        WIN_OEM_NEC_EQUAL = 0x92,
+        WIN_OEM_FJ_JISHO = 0x92,
+        WIN_OEM_FJ_MASSHOU = 0x93,
+        WIN_OEM_FJ_TOUROKU = 0x94,
+        WIN_OEM_FJ_LOYA = 0x95,
+        WIN_OEM_FJ_ROYA = 0x96,
+        WIN_LSHIFT = 0xA0,
+        WIN_RSHIFT = 0xA1,
+        WIN_LCONTROL = 0xA2,
+        WIN_RCONTROL = 0xA3,
+        WIN_LMENU = 0xA4,
+        WIN_RMENU = 0xA5,
+        WIN_BROWSER_BACK = 0xA6,
+        WIN_BROWSER_FORWARD = 0xA7,
+        WIN_BROWSER_REFRESH = 0xA8,
+        WIN_BROWSER_STOP = 0xA9,
+        WIN_BROWSER_SEARCH = 0xAA,
+        WIN_BROWSER_FAVORITES = 0xAB,
+        WIN_BROWSER_HOME = 0xAC,
+        WIN_VOLUME_MUTE = 0xAD,
+        WIN_VOLUME_DOWN = 0xAE,
+        WIN_VOLUME_UP = 0xAF,
+        WIN_MEDIA_NEXT_TRACK = 0xB0,
+        WIN_MEDIA_PREV_TRACK = 0xB1,
+        WIN_MEDIA_STOP = 0xB2,
+        WIN_MEDIA_PLAY_PAUSE = 0xB3,
+        WIN_LAUNCH_MAIL = 0xB4,
+        WIN_LAUNCH_MEDIA_SELECT = 0xB5,
+        WIN_LAUNCH_APP1 = 0xB6,
+        WIN_LAUNCH_APP2 = 0xB7,
+        WIN_OEM_1 = 0xBA,
+        WIN_OEM_PLUS = 0xBB,
+        WIN_OEM_COMMA = 0xBC,
+        WIN_OEM_MINUS = 0xBD,
+        WIN_OEM_PERIOD = 0xBE,
+        WIN_OEM_2 = 0xBF,
+        WIN_OEM_3 = 0xC0,
+        WIN_GAMEPAD_A = 0xC3,
+        WIN_GAMEPAD_B = 0xC4,
+        WIN_GAMEPAD_X = 0xC5,
+        WIN_GAMEPAD_Y = 0xC6,
+        WIN_GAMEPAD_RIGHT_SHOULDER = 0xC7,
+        WIN_GAMEPAD_LEFT_SHOULDER = 0xC8,
+        WIN_GAMEPAD_LEFT_TRIGGER = 0xC9,
+        WIN_GAMEPAD_RIGHT_TRIGGER = 0xCA,
+        WIN_GAMEPAD_DPAD_UP = 0xCB,
+        WIN_GAMEPAD_DPAD_DOWN = 0xCC,
+        WIN_GAMEPAD_DPAD_LEFT = 0xCD,
+        WIN_GAMEPAD_DPAD_RIGHT = 0xCE,
+        WIN_GAMEPAD_MENU = 0xCF,
+        WIN_GAMEPAD_VIEW = 0xD0,
+        WIN_GAMEPAD_LEFT_THUMBSTICK_BUTTON = 0xD1,
+        WIN_GAMEPAD_RIGHT_THUMBSTICK_BUTTON = 0xD2,
+        WIN_GAMEPAD_LEFT_THUMBSTICK_UP = 0xD3,
+        WIN_GAMEPAD_LEFT_THUMBSTICK_DOWN = 0xD4,
+        WIN_GAMEPAD_LEFT_THUMBSTICK_RIGHT = 0xD5,
+        WIN_GAMEPAD_LEFT_THUMBSTICK_LEFT = 0xD6,
+        WIN_GAMEPAD_RIGHT_THUMBSTICK_UP = 0xD7,
+        WIN_GAMEPAD_RIGHT_THUMBSTICK_DOWN = 0xD8,
+        WIN_GAMEPAD_RIGHT_THUMBSTICK_RIGHT = 0xD9,
+        WIN_GAMEPAD_RIGHT_THUMBSTICK_LEFT = 0xDA,
+        WIN_OEM_4 = 0xDB,
+        WIN_OEM_5 = 0xDC,
+        WIN_OEM_6 = 0xDD,
+        WIN_OEM_7 = 0xDE,
+        WIN_OEM_8 = 0xDF,
+        WIN_OEM_AX = 0xE1,
+        WIN_OEM_102 = 0xE2,
+        WIN_ICO_HELP = 0xE3,
+        WIN_ICO_00 = 0xE4,
+        WIN_PROCESSKEY = 0xE5,
+        WIN_ICO_CLEAR = 0xE6,
+        WIN_PACKET = 0xE7,
+        WIN_OEM_RESET = 0xE9,
+        WIN_OEM_JUMP = 0xEA,
+        WIN_OEM_PA1 = 0xEB,
+        WIN_OEM_PA2 = 0xEC,
+        WIN_OEM_PA3 = 0xED,
+        WIN_OEM_WSCTRL = 0xEE,
+        WIN_OEM_CUSEL = 0xEF,
+        WIN_OEM_ATTN = 0xF0,
+        WIN_OEM_FINISH = 0xF1,
+        WIN_OEM_COPY = 0xF2,
+        WIN_OEM_AUTO = 0xF3,
+        WIN_OEM_ENLW = 0xF4,
+        WIN_OEM_BACKTAB = 0xF5,
+        WIN_ATTN = 0xF6,
+        WIN_CRSEL = 0xF7,
+        WIN_EXSEL = 0xF8,
+        WIN_EREOF = 0xF9,
+        WIN_PLAY = 0xFA,
+        WIN_ZOOM = 0xFB,
+        WIN_NONAME = 0xFC,
+        WIN_PA1 = 0xFD,
+        WIN_OEM_CLEAR = 0xFE
+    };
+
+private:
+    static KeyCodes _instance;
+
+    uint8 _winCodes[Common::KEYCODE_LAST];
+    uint16 _scummCodes[256];
+
+private:
+    KeyCodes();
+
+public:
+    static uint8 GetWinCode(uint16 code) { return _instance._winCodes[code]; };
+    static uint16 GetScummCode(uint8 code) {return _instance._scummCodes[code]; };
+};
+
+
+};
+
+
+ #endif
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index 1af3bf28043..f1ba65038fa 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -24,6 +24,8 @@
 namespace Gamos {
 
 void SystemProc::processMessage(const Common::Event &ev) {
+	uint8 winKey;
+
 	switch(ev.type) {
 	case Common::EVENT_KEYDOWN:
 		if ((_gd2flags & 1) == 0)
@@ -31,35 +33,37 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 		_ascii = ev.kbd.ascii;
 
-		if (ev.kbd.keycode == _keyCodes[0])
+		winKey = KeyCodes::GetWinCode(ev.kbd.keycode);
+
+		if (winKey == _keyCodes[0])
 			_act1 = 0;
-		else if (ev.kbd.keycode == _keyCodes[1])
+		else if (winKey == _keyCodes[1])
 			_act1 = 1;
-		else if (ev.kbd.keycode == _keyCodes[2])
+		else if (winKey == _keyCodes[2])
 			_act1 = 2;
-		else if (ev.kbd.keycode == _keyCodes[3])
+		else if (winKey == _keyCodes[3])
 			_act1 = 3;
-		else if (ev.kbd.keycode == _keyCodes[4])
+		else if (winKey == _keyCodes[4])
 			_act1 = 4;
-		else if (ev.kbd.keycode == _keyCodes[5])
+		else if (winKey == _keyCodes[5])
 			_act1 = 5;
-		else if (ev.kbd.keycode == _keyCodes[6])
+		else if (winKey == _keyCodes[6])
 			_act1 = 6;
-		else if (ev.kbd.keycode == _keyCodes[7])
+		else if (winKey == _keyCodes[7])
 			_act1 = 7;
 		else {
-			if (ev.kbd.keycode == _keyCodes[8])
+			if (winKey == _keyCodes[8])
 				_act2 = ACT2_82;
-			else if (ev.kbd.keycode == _keyCodes[9])
+			else if (winKey == _keyCodes[9])
 				_act2 = ACT2_83;
-			else if (ev.kbd.keycode == _keyCodes[10])
+			else if (winKey == _keyCodes[10])
 				_act2 = ACT2_8f;
-			else if (ev.kbd.keycode == _keyCodes[11])
+			else if (winKey == _keyCodes[11])
 				_act2 = ACT2_84;
 			else
 				return;
 
-			_rawKeyCode = ev.kbd.keycode;
+			_rawKeyCode = winKey;
 			return;
 		}
 
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index 41f0e8dafa9..9035ffcd361 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -45,7 +45,7 @@ public:
     uint8 _act1 = 0;
     uint8 _act2 = 0;
 
-    uint16 _rawKeyCode = 0;
+    uint8 _rawKeyCode = 0;
     uint16 _ascii = 0;
 
 
@@ -53,7 +53,7 @@ public:
     Common::Point _mouseActPos;
 
     uint8 _gd2flags = 0; /* 0x4 */
-    uint16 _keyCodes[12]; /* 0x40 */
+    uint8 _keyCodes[12]; /* 0x40 */
 
 };
 


Commit: c49eda376b1486045cede5ca8d8b73bdea1655f5
    https://github.com/scummvm/scummvm/commit/c49eda376b1486045cede5ca8d8b73bdea1655f5
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:26+01:00

Commit Message:
GAMOS: Implement loading of missing resource data into VM memory

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 827e0167037..727568b0e42 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -393,6 +393,21 @@ bool GamosEngine::loadModule(uint id) {
 
 bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize) {
 	if (tp == RESTP_12) {
+		Common::MemoryReadStream dataStream(data, dataSize, DisposeAfterUse::NO);
+
+		_addrBlk12 = _loadedDataSize;
+		_addrFPS = _loadedDataSize + 1;
+		_addrKeyDown = _loadedDataSize + 2;
+		_addrKeyCode = _loadedDataSize + 3;
+		_addrCurrentFrame = _loadedDataSize + 4;
+
+		VM::memory().setU8( _addrBlk12, dataStream.readByte() );
+		dataStream.skip(1);
+		VM::memory().setU8( _addrFPS, _fps );
+		VM::memory().setU8( _addrKeyDown, dataStream.readByte() );
+		VM::memory().setU8( _addrKeyCode, dataStream.readByte() );
+		VM::memory().setU32( _addrCurrentFrame, dataStream.readUint32LE() );
+
 		setFPS(_fps);
 	} else if (tp == RESTP_13) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
@@ -920,7 +935,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
 
-	/*if ()*/{
+	if ( FUN_00402bc4() ) {
 		bool loop = false;
 		if (!DAT_00417802)
 			loop = FUN_00402fb4();
@@ -2595,6 +2610,37 @@ Object *GamosEngine::FUN_00407588(int32 seq, int32 spr, int32 *pX, int32 y) {
 	return obj;
 }
 
+bool GamosEngine::FUN_00402bc4() {
+	if (RawKeyCode == ACT_NONE) {
+		VM::memory().setU8(_addrKeyCode, 0);
+		VM::memory().setU8(_addrKeyDown, 0);
+	} else {
+		VM::memory().setU8(_addrKeyCode, RawKeyCode);
+		VM::memory().setU8(_addrKeyDown, 1);
+	}
+
+	if (VM::memory().getU8(_addrBlk12) != 0)
+		return false;
+
+	uint32 frameval = VM::memory().getU32(_addrCurrentFrame);
+	VM::memory().setU32(_addrCurrentFrame, frameval + 1);
+
+	uint8 fpsval = VM::memory().getU8(_addrFPS);
+
+	if (fpsval == 0) {
+		fpsval = 1;
+		VM::memory().setU8(_addrFPS, 1);
+	} else if (fpsval > 50) {
+		fpsval = 50;
+		VM::memory().setU8(_addrFPS, 50);
+	}
+
+	if (fpsval != _fps) {
+		_fps = fpsval;
+		setFPS(_fps);
+	}
+
+	return true;
 }
 
 
@@ -2614,21 +2660,6 @@ bool GamosEngine::FUN_004038b8() {
 	return true;
 }
 
-bool GamosEngine::FUN_00402bc4() {
-	warning("Not implemented FUN_00402bc4");
-	return true;
-}
-
-bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
-	if (obj->y == -1)
-		return false;
-
-	Object &robj = _drawElements[obj->y];
-	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
-		return true;
-	return false;
-}
-
 void GamosEngine::dumpActions() {
 	Common::String t = Common::String::format("actions_%d.txt", _currentModuleID);
 	FILE *f = fopen(t.c_str(), "wb");
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index d97f35d744e..7def752e4a5 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -294,7 +294,11 @@ private:
 	int32 _readingBkgMainId = -1;
 	int32 _loadedDataSize = -1;
 
-
+	uint32 _addrBlk12 = 0;
+	uint32 _addrFPS = 1;
+	uint32 _addrKeyDown = 2;
+	uint32 _addrKeyCode = 3;
+	uint32 _addrCurrentFrame = 4;
 
 	MidiMusic _musicPlayer;
 	SystemProc _messageProc;


Commit: e11e7cc513df1928d3bd571b35919380b7d3903c
    https://github.com/scummvm/scummvm/commit/e11e7cc513df1928d3bd571b35919380b7d3903c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:26+01:00

Commit Message:
GAMOS: Implement few callbacks and placholders

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 727568b0e42..b522d3185c6 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -903,10 +903,15 @@ void GamosEngine::readData2(const RawData &data) {
 	dataStream.seek(4); // FIX ME
 	_messageProc._gd2flags = dataStream.readByte(); //4
 	//5
-	//x15
-	dataStream.seek(0x15);
+	//x14
+	dataStream.seek(0x14);
+	_d2_fld14 = dataStream.readByte(); // x14
 	_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
-	//x16
+	_d2_fld16 = dataStream.readByte(); // x16
+	_d2_fld17 = dataStream.readByte(); // x17
+	_d2_fld18 = dataStream.readByte(); // x18
+	//x19
+
 	dataStream.seek(0x38);
 	_midiTrack = dataStream.readUint32LE(); //0x38
 	_mouseCursorImgId = dataStream.readUint32LE(); //0x3c
@@ -2117,6 +2122,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 	} break;
 
+	case 26:
+		FUN_004023d8(PTR_00417218);
+		vm->EAX.val = 1;
+		break;
+
 	case 30: {
 		if (PTR_00417218->y != -1) {
 			Object *obj = &_drawElements[PTR_00417218->y];
@@ -2142,11 +2152,54 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 		break;
 
+	case 47: {
+		arg1 = vm->pop32();
+
+		switch (arg1) {
+		case 0:
+			vm->EAX.val = _d2_fld16 != 0 ? 1 : 0;
+			break;
+
+		case 1:
+			vm->EAX.val = _d2_fld14 != 0 ? 1 : 0;
+			break;
+
+		case 2:
+			vm->EAX.val = 1; //BYTE_004177fb != 0 ? 1 : 0;
+			break;
+
+		case 3:
+			vm->EAX.val = _d2_fld17 != 0 ? 1 : 0;
+			break;
+
+		case 4:
+			vm->EAX.val = _d2_fld18 != 0 ? 1 : 0;
+			break;
+
+		default:
+			break;
+		}
+	} break;
+
+	case 49: {
+		arg1 = vm->pop32();
+		arg2 = vm->pop32();
+
+		warning("Do save-load %d %d", arg1, arg2);
+	} break;
+
 	case 54:
 		arg1 = vm->pop32();
 		vm->EAX.val = rndRange16(arg1);
 		break;
 
+	case 55: {
+		VM::Reg regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef.ref, regRef.val);
+		warning("PlayMovie 55: %s", str.c_str());
+		vm->EAX.val = 1;
+	} break;
+
 	case 57: {
 		VM::Reg regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef.ref, regRef.val);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 7def752e4a5..0cd3e9263d5 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -287,6 +287,11 @@ private:
 
 	/* Data2 */
 
+	uint8 _d2_fld14 = 0;
+	uint8 _d2_fld16 = 0;
+	uint8 _d2_fld17 = 0;
+	uint8 _d2_fld18 = 0;
+
 	bool _enableMidi = false;
 	int32 _midiTrack = 0;
 


Commit: 4a8f382029e08c3b200be959fe292b526318b5cc
    https://github.com/scummvm/scummvm/commit/4a8f382029e08c3b200be959fe292b526318b5cc
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:26+01:00

Commit Message:
GAMOS: Fix skipping

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index b522d3185c6..f1d20fce826 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1084,14 +1084,14 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 
 				if ((c[1] & 2) == cval) {
 					if ((c[1] & 0xc) == 0) {
-						rstream.skip((sz - read) * 4);
+						rstream.skip((sz - (read + 1)) * 4);
 						break;
 					}
 					if ((c[1] & 0xc) == 4)
 						return 0;
 					if ((c[1] & 0xc) == 8) {
 						fastSkipAll = true;
-						rstream.skip((sz - read) * 4);
+						rstream.skip((sz - (read + 1)) * 4);
 						break;
 					}
 					ARR_00412208[ sbuf[ps] ] = (c[3] << 8) | c[2];


Commit: 218e0fc5c4dff81609faf60e488ab14687f13382
    https://github.com/scummvm/scummvm/commit/218e0fc5c4dff81609faf60e488ab14687f13382
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:27+01:00

Commit Message:
GAMOS: rename thing1 to states and use array2D template

Changed paths:
  A engines/gamos/array2d.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/array2d.h b/engines/gamos/array2d.h
new file mode 100644
index 00000000000..2546825f9d4
--- /dev/null
+++ b/engines/gamos/array2d.h
@@ -0,0 +1,159 @@
+
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_ARRAY2D_H
+#define GAMOS_ARRAY2D_H
+
+#include "common/array.h"
+#include "common/rect.h"
+
+template <class T>
+class Array2D : protected Common::Array<T>
+{
+private:
+    typedef Common::Array<T> __base;
+public:
+    typedef uint size_type; /*!< Size type of the array. */
+
+    using Common::Array<T>::data;
+    using Common::Array<T>::operator[];
+    using Common::Array<T>::size;
+    using Common::Array<T>::begin;
+    using Common::Array<T>::end;
+    using Common::Array<T>::empty;
+
+public:
+
+
+    Array2D() = default;
+    Array2D( Array2D && ) = default;
+    Array2D( const Array2D & ) = default;
+
+    Array2D& operator=( const Array2D & ) = default;
+    Array2D& operator=( Array2D && ) = default;
+
+    Array2D(size_type w, size_type h) {
+        resize(w, h);
+    }
+
+    Array2D(const Common::Point &sz) {
+        resize(sz);
+    }
+
+    Array2D<T>* copy() {
+        Array2D<T> *tmp = new Array2D<T>;
+        *tmp = *this;
+        return tmp;
+    }
+
+    void resize(const Common::Point &sz) {
+        _w = sz.x;
+        _h = sz.y;
+
+        __base::resize(_w * _h);
+    }
+
+    void resize(size_type w, size_type h) {
+        _w = w;
+        _h = h;
+
+        __base::resize(_w * _h);
+    }
+
+    T& at(size_type x, size_type y) {
+        return __base::operator[](x + y * _w);
+    }
+
+    T& at(const Common::Point &p) {
+        return __base::operator[](p.x + p.y * _w);
+    }
+
+    T& at(size_type n) {
+        return __base::operator[](n);
+    }
+
+    T& operator()(size_type x, size_type y) {
+        return at(x + y * _w);
+    }
+
+    T& operator()(const Common::Point &p) {
+        return at(p.x + p.y * _w);
+    }
+
+    T* getLinePtr(size_type y) {
+        return &(at(y * _w));
+    }
+
+    const T* getLinePtr(size_type y) const {
+        return &(at(y * _w));
+    }
+
+    Common::Point sizes() const {
+        return Common::Point(_w, _h);
+    }
+
+    size_type getIndex(size_type x, size_type y) const {
+        size_t n = x + y * _w;
+        if (n < size())
+            return n;
+        return -1;
+    }
+
+    Common::Point indexToCoords(size_type id) const {
+        if (id >= 0 && id < size())
+            return Common::Point(id % _w, id / _w);
+        return Common::Point(-1, -1);
+    }
+
+    size_type width() const {
+        return _w;
+    }
+
+    size_type height() const {
+        return _h;
+    }
+
+    void clear() {
+        _w = 0;
+        _h = 0;
+        Common::Array<T>::clear();
+    }
+
+    bool isNotNull() const {
+        return _w > 0 && _h > 0;
+    }
+
+    bool isNull() const {
+        return _w == 0 || _h == 0;
+    }
+
+    bool isOk() const {
+        return _w > 0 && _h > 0 && (size() == _w * _h);
+    }
+
+protected:
+    size_type _w = 0;
+    size_type _h = 0;
+};
+
+
+#endif
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index f1d20fce826..4fea4d9a8a0 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -415,8 +415,8 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		loadRes18(pid, data, dataSize);
 	} else if (tp == RESTP_19) {
 		if (BYTE_004177f7 == 0) {
-			for (int i = 0; i < _thing1.size(); i++)
-				_thing1[i] = 0xf0fe;
+			for (int i = 0; i < _states.size(); i++)
+				_states.at(i) = 0xf0fe;
 
 			DAT_004177f8 = 1;
 			ProcessScript(true, data, dataSize);
@@ -620,8 +620,8 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 
 	uint32 bkgnum1 = dataStream.readUint32LE(); // 0
 	uint32 bkgnum2 = dataStream.readUint32LE(); // 4
-	_thing1Size = dataStream.readUint32LE(); // 8
-	_thing1Count = dataStream.readUint32LE(); // c
+	_statesWidth = dataStream.readUint32LE(); // 8
+	_statesHeight = dataStream.readUint32LE(); // c
 	_bkgUpdateSizes.x = dataStream.readUint32LE(); // 10
 	_bkgUpdateSizes.y = dataStream.readUint32LE(); // 14
 	/* bkgbufferSize */ dataStream.readUint32LE(); // 18
@@ -632,16 +632,16 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	uint32 midiCount = dataStream.readUint32LE(); // 2c
 	uint32 dat6xCount = dataStream.readUint32LE(); // 30
 
-	_thing1Shift = 2;
+	_statesShift = 2;
 	for(int i = 2; i < 9; i++) {
-		if (_thing1Size <= (1 << i)) {
-			_thing1Shift = i;
+		if (_statesWidth <= (1 << i)) {
+			_statesShift = i;
 			break;
 		}
 	}
 
-	_thing1.clear();
-	_thing1.resize(_thing1Count << _thing1Shift);
+	_states.clear();
+	_states.resize(_statesWidth, _statesHeight);
 
 	_bkgImages.clear();
 	_bkgImages.resize(bkgnum1 * bkgnum2);
@@ -1054,10 +1054,12 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 
 				uint16 fb = 0;
 				if (!p1) {
-					fb = _thing1[ ((int8)c[2] + DAT_00417220 + _thing1Size) % _thing1Size  +
-				                  ((((int8)c[3] + DAT_00417224 + _thing1Count) % _thing1Count) << _thing1Shift) ];
+					Common::Point xy;
+					xy.x = ((int8)c[2] + DAT_00417220 + _statesWidth) % _statesWidth;
+					xy.y = ((int8)c[3] + DAT_00417224 + _statesHeight) % _statesHeight;
+					fb = _states.at( xy );
 				} else {
-					fb = _thing1[(c[3] << _thing1Shift) + c[2]];
+					fb = _states.at(c[2], c[3]);
 				}
 
 				uint8 lb = fb & 0xff;
@@ -1401,8 +1403,8 @@ void GamosEngine::preprocessDataB1(int id, byte *data) {
 int GamosEngine::processData(int id, byte *data) {
 	preprocessData(_preprocDataId, data);
 	if (id == 0) {
-		FUN_0040283c( ((int8)data[3] + DAT_00417224 + _thing1Count) % _thing1Count,
-		              ((int8)data[2] + DAT_00417220 + _thing1Size) % _thing1Size,
+		FUN_0040283c( ((int8)data[3] + DAT_00417224 + _statesHeight) % _statesHeight,
+		              ((int8)data[2] + DAT_00417220 + _statesWidth) % _statesWidth,
 					  data );
 		if (_needReload)
 			return 0;
@@ -1415,24 +1417,24 @@ int GamosEngine::processData(int id, byte *data) {
 
 void GamosEngine::FUN_00402a68(const byte *d) {
 	if (d[2] != 0 || d[3] != 0) {
-		DAT_00417220 = ((int8)d[2] + DAT_00417220 + _thing1Size) % _thing1Size;
-        DAT_00417224 = ((int8)d[3] + DAT_00417224 + _thing1Count) % _thing1Count;
+		DAT_00417220 = ((int8)d[2] + DAT_00417220 + _statesWidth) % _statesWidth;
+		DAT_00417224 = ((int8)d[3] + DAT_00417224 + _statesHeight) % _statesHeight;
 
 		uint8 t = PTR_00417218->fld_3;
 
-        _thing1[(DAT_0041722c << _thing1Shift) + DAT_00417228] = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
+        _states.at(DAT_00417228, DAT_0041722c) = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
 
         FUN_00402654(0, DAT_00417224, DAT_00417220);
 
         PTR_00417218->pos = DAT_00417220;
         PTR_00417218->blk = DAT_00417224;
 
-        uint16 thing = _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ];
+        uint16 &rthing = _states.at(DAT_00417220, DAT_00417224);
 
-        PTR_00417218->fld_2 = thing & 0xff;
-        PTR_00417218->fld_3 = (t & 0xf) | ((thing >> 8) & 0xf0);
+        PTR_00417218->fld_2 = rthing & 0xff;
+        PTR_00417218->fld_3 = (t & 0xf) | ((rthing >> 8) & 0xf0);
 
-        _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ] = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
+        rthing = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
 
         BYTE_00412200 = 1;
 	}
@@ -1442,7 +1444,7 @@ void GamosEngine::FUN_00402a68(const byte *d) {
         PTR_00417218->flags = PTR_00417218->flags & 0xf;
         PTR_00417218->flags = PTR_00417218->flags | BYTE_004177f6;
 
-		uint16 &tref = _thing1[ (DAT_00417224 << _thing1Shift) + DAT_00417220 ];
+		uint16 &tref = _states.at(DAT_00417220, DAT_00417224);
 		tref = (tref & 0xff) | (BYTE_004177f6 << 8);
 
         BYTE_00412200 = 1;
@@ -1453,7 +1455,7 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 	byte td[4];
 	memcpy(td, data, 4);
 
-	uint16 *pv1 = _thing1.data() + (id << _thing1Shift) + pos;
+	uint16 &rthing = _states.at(pos, id);
 
 	uint8 oid = td[0];
 
@@ -1463,7 +1465,7 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 			if (_needReload)
 				return;
 
-			*pv1 = (td[1] << 8) | td[0];
+			rthing = (td[1] << 8) | td[0];
 			return;
 		}
 	} else {
@@ -1506,8 +1508,8 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 		obj->blk = id;
 		obj->x = -1;
 		obj->y = -1;
-		obj->fld_2 = (*pv1) & 0xff;
-		obj->fld_3 = ((*pv1) >> 8 ) & 0xff;
+		obj->fld_2 = rthing & 0xff;
+		obj->fld_3 = (rthing >> 8 ) & 0xff;
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
 			obj->fld_3 |= 1;
 
@@ -1528,7 +1530,7 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 			PTR_004121b4 = obj;
 	}
 
-	*pv1 = (td[1] << 8) | td[0];
+	rthing = (td[1] << 8) | td[0];
 	executeScript(td[1], id, pos, odat, index, obj, &act, act.script1);
 }
 
@@ -1539,9 +1541,9 @@ void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
 
 
 void GamosEngine::FUN_00402654(int mode, int id, int pos) {
-	uint16 *pth1 = &_thing1[pos + (id << _thing1Shift)];
+	uint16 &rthing = _states.at(pos, id);
 
-	uint8 actid = (*pth1 & 0xff);
+	uint8 actid = rthing & 0xff;
 
 	if (actid == 0xfe)
 		return;
@@ -1584,9 +1586,9 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	}
 
 	if (povar4)
-		*pth1 = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
+		rthing = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
 
-	executeScript((*pth1) >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
+	executeScript(rthing >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
 }
 
 Object *GamosEngine::getFreeObject() {
@@ -2148,7 +2150,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		break;
 
 	case 33:
-		PTR_00417218->fld_5 = _thing1Count - PTR_00417218->blk;
+		PTR_00417218->fld_5 = _statesHeight - PTR_00417218->blk;
 		vm->EAX.val = 1;
 		break;
 
@@ -2508,7 +2510,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	if (!pobj) {
 		DAT_004173f4 = actPos.x / _unk2;
 		DAT_004173f0 = actPos.y / _unk3;
-		DAT_00417803 = _thing1[DAT_004173f4 + (DAT_004173f0 << _thing1Shift)] & 0xff;
+		DAT_00417803 = _states.at(DAT_004173f4, DAT_004173f0) & 0xff;
 	} else {
 		DAT_00417803 = actT;
 		if (actT == 2) {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 0cd3e9263d5..85b3a70d8d9 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -53,6 +53,8 @@
 #include "gamos/detection.h"
 #include "gamos/file.h"
 
+#include "gamos/array2d.h"
+
 namespace Gamos {
 
 struct GamosGameDescription;
@@ -309,10 +311,10 @@ private:
 	SystemProc _messageProc;
 	MoviePlayer _moviePlayer;
 
-	uint32 _thing1Size = 0;
-	uint32 _thing1Count = 0;
-	uint32 _thing1Shift = 0;
-	Common::Array<uint16> _thing1;
+	uint32 _statesWidth = 0;
+	uint32 _statesHeight = 0;
+	uint32 _statesShift = 0;
+	Array2D<uint16> _states;
 
 
 	uint8 _preprocDataId = 0;


Commit: 128dd6da3763fb08dc51a6bb8fc175d277f0d2ee
    https://github.com/scummvm/scummvm/commit/128dd6da3763fb08dc51a6bb8fc175d277f0d2ee
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:27+01:00

Commit Message:
GAMOS: rename grid size variables

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 4fea4d9a8a0..fab8e9bb8b5 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -534,8 +534,8 @@ bool GamosEngine::initMainDatas() {
 	_readBufSize = dataStream.readUint32LE();
 	_width = dataStream.readUint32LE();
 	_height = dataStream.readUint32LE();
-	_unk2 = dataStream.readUint32LE();
-	_unk3 = dataStream.readUint32LE();
+	_gridCellW = dataStream.readSint32LE();
+	_gridCellH = dataStream.readSint32LE();
 	_movieCount = dataStream.readUint32LE();
 	_unk5 = dataStream.readByte();
 	_unk6 = dataStream.readByte();
@@ -1834,25 +1834,25 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 	ImagePos *imgPos = obj->pImg;
 	Image *img = imgPos->image;
 
-	int32 x = obj->fld_4 * _unk2;
-	int32 y = obj->fld_5 * _unk3;
+	int32 x = obj->fld_4 * _gridCellW;
+	int32 y = obj->fld_5 * _gridCellH;
 
 	if (obj->pos != 255 && obj->blk != 255) {
 		Object *o = &_drawElements[(obj->blk * 0x100) + obj->pos];
 		if (o->flags & 4) {
 			int t = obj->actID + 1;
-			x += (o->pos - obj->fld_4) * _unk2 * t / obj->fld_2;
-			y += (o->blk - obj->fld_5) * _unk3 * t / obj->fld_2;
+			x += (o->pos - obj->fld_4) * _gridCellW * t / obj->fld_2;
+			y += (o->blk - obj->fld_5) * _gridCellH * t / obj->fld_2;
 		}
 	}
 
 	if (obj->flags & 8)
-		obj->x = x - (img->surface.w - _unk2 - imgPos->xoffset);
+		obj->x = x - (img->surface.w - _gridCellW - imgPos->xoffset);
 	else
 		obj->x = x - imgPos->xoffset;
 
 	if (obj->flags & 0x10)
-		obj->y = y - (img->surface.h - _unk3 - imgPos->yoffset);
+		obj->y = y - (img->surface.h - _gridCellH - imgPos->yoffset);
 	else
 		obj->y = y - imgPos->yoffset;
 }
@@ -2223,7 +2223,7 @@ void GamosEngine::callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID)
 
 uint32 GamosEngine::scriptFunc19(uint32 id) {
 	BYTE_004177fc = 1;
-	FUN_0040738c(id, DAT_00417220 * _unk2, DAT_00417224 * _unk3, false);
+	FUN_0040738c(id, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH, false);
 
 	return 1;
 }
@@ -2508,8 +2508,8 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	}
 
 	if (!pobj) {
-		DAT_004173f4 = actPos.x / _unk2;
-		DAT_004173f0 = actPos.y / _unk3;
+		DAT_004173f4 = actPos.x / _gridCellW;
+		DAT_004173f0 = actPos.y / _gridCellH;
 		DAT_00417803 = _states.at(DAT_004173f4, DAT_004173f0) & 0xff;
 	} else {
 		DAT_00417803 = actT;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 85b3a70d8d9..d1f2def584c 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -227,8 +227,8 @@ private:
 	uint32 _readBufSize;
 	uint32 _width;
 	uint32 _height;
-	uint32 _unk2;
-	uint32 _unk3;
+	int32 _gridCellW;
+	int32 _gridCellH;
 	uint32 _movieCount;
 	byte _unk5;
 	byte _unk6;


Commit: 665a53fcdfc330e24e8e9496efd314b59c30e7a6
    https://github.com/scummvm/scummvm/commit/665a53fcdfc330e24e8e9496efd314b59c30e7a6
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:27+01:00

Commit Message:
GAMOS: Path finding functions

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index fab8e9bb8b5..c3ba5692ec2 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -643,6 +643,12 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_states.clear();
 	_states.resize(_statesWidth, _statesHeight);
 
+	_statesCount = _statesHeight * _statesWidth;
+	_pathRight = _statesWidth - 1;
+	_pathBottom = _statesHeight - 1;
+	_pathMap.clear();
+	_pathMap.resize(_statesWidth, _statesHeight);
+
 	_bkgImages.clear();
 	_bkgImages.resize(bkgnum1 * bkgnum2);
 
@@ -1719,7 +1725,7 @@ bool GamosEngine::FUN_00402fb4()
 					PTR_00417214 = &_someActsArr[pobj->actID];
 					PTR_004173e8 = pobj->storage.data();
 
-					//DAT_00417804 = 0;
+					DAT_00417804 = 0;
 					for ( ScriptS &scr: PTR_00417214->scriptS ) {
 						BYTE_004177f6 = PTR_00417218->flags & 0xf0;
 
@@ -2154,6 +2160,117 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 		break;
 
+	case 35:
+		arg1 = vm->pop32();
+
+		switch (arg1)
+		{
+		case 3:
+			FUN_00408648(0xe, 0xff, 0xff);
+			break;
+
+		case 4:
+			FUN_00408648(0xe, 0xfe, 0xff);
+			break;
+
+		case 5:
+			FUN_00408648(0xe, 0xfe, 0xfe);
+			break;
+
+		case 6:
+			FUN_00408648(0x82, 0xff, 0xff);
+			break;
+
+		case 7:
+			FUN_00408648(0x82, 0xfe, 0xff);
+			break;
+
+		case 8:
+			FUN_00408648(0x82, 0xfe, 0xfe);
+			break;
+
+		case 9:
+			FUN_00408648(0x83, 0xff, 0xff);
+			break;
+
+		case 10:
+			FUN_00408648(0x83, 0xfe, 0xff);
+			break;
+
+		case 11:
+			FUN_00408648(0x83, 0xfe, 0xfe);
+			break;
+
+		default:
+			break;
+		}
+
+		break;
+
+	case 36:
+		arg1 = vm->pop32();
+		arg2 = vm->pop32();
+
+		switch (arg1)
+		{
+		case 1:
+			FUN_00408648(0, arg2, 0xff);
+			break;
+
+		case 2:
+			FUN_00408648(0, arg2, 0xfe);
+			break;
+
+		case 3:
+			FUN_00408648(0xe, arg2, 0xff);
+			break;
+
+		case 4:
+			FUN_00408648(0xe, arg2, 0xfe);
+			break;
+
+		case 5:
+			FUN_00408648(0xe, arg2, arg2);
+			break;
+
+		case 6:
+			FUN_00408648(0x82, arg2, 0xff);
+			break;
+
+		case 7:
+			FUN_00408648(0x82, arg2, 0xfe);
+			break;
+
+		case 8:
+			FUN_00408648(0x82, arg2, arg2);
+			break;
+
+		case 9:
+			FUN_00408648(0x83, arg2, 0xff);
+			break;
+
+		case 10:
+			FUN_00408648(0x83, arg2, 0xfe);
+			break;
+
+		case 11:
+			FUN_00408648(0x83, arg2, arg2);
+			break;
+
+		default:
+			break;
+		}
+
+		break;
+
+	case 38:
+		arg1 = vm->pop32();
+		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412ca0)
+			vm->EAX.val = 0;
+		else
+			vm->EAX.val = 1;
+		break;
+
 	case 47: {
 		arg1 = vm->pop32();
 
@@ -2698,6 +2815,339 @@ bool GamosEngine::FUN_00402bc4() {
 	return true;
 }
 
+void GamosEngine::FUN_00407db8(uint8 p)
+{
+	if ((p == 0x82) || (p == 0x83)) {
+		DAT_00412c94 = DAT_004173fc;
+		DAT_00412c98 = DAT_004173f8;
+	} else {
+		DAT_00412c94 = DAT_004173f4;
+		DAT_00412c98 = DAT_004173f0;
+	}
+	DAT_00412c8c = (uint)PTR_00417218->pos;
+	DAT_00412c90 = (uint)PTR_00417218->blk;
+	INT_00412ca0 = -1;
+	INT_00412c9c = -1;
+	DAT_00417804 = 0;
+}
+
+void GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
+	FUN_00407db8(p1);
+
+	if (p1 == 0x82 || p1 == 0x83) {
+		if (p1 != DAT_004177fe)
+			return;
+		if (p2 != 0xff && p2 != DAT_004177fd)
+			return;
+	} else {
+		if (p1 != 0xe) {
+			if (p3 == 0xff)
+				FUN_004084bc(p2);
+			else
+				FUN_00408510(p2);
+			return;
+		}
+		if (p2 != 0xff && p2 != DAT_00417803)
+			return;
+	}
+
+	if (p3 == 0xff)
+		FUN_00407e2c();
+	else if (p3 == 0xfe)
+		FUN_0040856c();
+	else
+		FUN_004085d8(p2);
+}
+
+void GamosEngine::FUN_004084bc(uint8 p) {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+			if ((th1 & 0xff) != p)
+				_pathMap.at(i, j) = 0;
+			else
+				_pathMap.at(i, j) = 2;
+		}
+	}
+	FUN_0040841c(true);
+}
+
+void GamosEngine::FUN_00408510(uint8 p) {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+
+			if ((th1 & 0xff) == 0xfe)
+				_pathMap.at(i, j) = 0;
+			else if ((th1 & 0xff) == p)
+				_pathMap.at(i, j) = 2;
+			else
+				_pathMap.at(i, j) = 3;
+		}
+	}
+	FUN_0040841c(false);
+}
+
+void GamosEngine::FUN_0040856c() {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+
+			if ((th1 & 0xff) == 0xfe)
+				_pathMap.at(i, j) = 0;
+			else
+				_pathMap.at(i, j) = 3;
+		}
+	}
+	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
+	FUN_0040841c(false);
+}
+
+void GamosEngine::FUN_004085d8(uint8 p) {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+
+			if ((th1 & 0xff) == p)
+				_pathMap.at(i, j) = 0;
+			else
+				_pathMap.at(i, j) = 3;
+		}
+	}
+	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
+	FUN_0040841c(false);
+}
+
+void GamosEngine::FUN_0040841c(bool p) {
+	_pathMap.at(DAT_00412c8c, DAT_00412c90) = 6;
+
+	while(true) {
+		byte res = FUN_004081b8(6, 4);
+		if (res == 0)
+			break;
+		else if (res == 1) {
+			if (p)
+				FUN_00407e2c();
+			else
+				FUN_00407f70(6);
+			break;
+		}
+
+		res = FUN_004081b8(4, 5);
+		if (res == 0)
+			break;
+		else if (res == 1) {
+			if (p)
+				FUN_00407e2c();
+			else
+				FUN_00407f70(4);
+			break;
+		}
+
+		res = FUN_004081b8(5, 6);
+		if (res == 0)
+			break;
+		else if (res == 1) {
+			if (p)
+				FUN_00407e2c();
+			else
+				FUN_00407f70(5);
+			break;
+		}
+	}
+}
+
+byte GamosEngine::FUN_00407e2c()
+{
+	int32 iVar2 = DAT_00412c8c - DAT_00412c94;
+	if (iVar2 < 1)
+		iVar2 = -iVar2;
+
+	int32 iVar1 = DAT_00412c90 - DAT_00412c98;
+	if (iVar1 < 1)
+		iVar1 = -iVar1;
+
+	if ((iVar2 == 0) && (iVar1 == 0))
+		return 0;
+
+	if ((iVar2 == 0) || (iVar1 / iVar2) > 3) {
+		if (iVar1 > 1) {
+			INT_00412c9c = 4;
+			if (DAT_00412c98 <= DAT_00412c90)
+				INT_00412c9c = 0;
+		}
+		INT_00412ca0 = 4;
+		if (DAT_00412c98 <= DAT_00412c90)
+			INT_00412ca0 = 0;
+	} else if ((iVar1 == 0) || (iVar2 / iVar1) > 3) {
+		if (iVar2 > 1) {
+			INT_00412c9c = 2;
+			if (DAT_00412c94 <= DAT_00412c8c)
+				INT_00412c9c = 6;
+		}
+		INT_00412ca0 = 2;
+		if (DAT_00412c94 <= DAT_00412c8c)
+			INT_00412ca0 = 6;
+	} else {
+		if (DAT_00412c8c < DAT_00412c94) {
+			INT_00412c9c = 3;
+			if (DAT_00412c98 <= DAT_00412c90)
+				INT_00412c9c = 1;
+		} else {
+			INT_00412c9c = 5;
+			if (DAT_00412c98 <= DAT_00412c90)
+				INT_00412c9c = 7;
+		}
+
+		if (iVar1 < iVar2) {
+			INT_00412ca0 = 2;
+			if (DAT_00412c94 <= DAT_00412c8c)
+				INT_00412ca0 = 6;
+		} else {
+			INT_00412ca0 = 4;
+			if (DAT_00412c98 <= DAT_00412c90)
+				INT_00412ca0 = 0;
+		}
+	}
+
+	DAT_00417804 = 1;
+	return 1;
+}
+
+byte GamosEngine::FUN_00407f70(uint8 p) {
+	int32 x = DAT_00412c94;
+	int32 y = DAT_00412c98;
+	int32 px = -1;
+	int32 py = -1;
+
+	while (true) {
+		int32 xdist = DAT_00412c8c - x;
+		if (xdist < 1)
+			xdist = -xdist;
+		int32 ydist = DAT_00412c90 - y;
+		if (ydist < 1)
+			ydist = -ydist;
+
+		int32 xx = x;
+		int32 yy = y;
+
+		if (ydist < xdist) {
+			if (x == 0 || _pathMap.at(x - 1, y) != p) {
+				if ((x >= _pathRight) || _pathMap.at(x + 1, y) != p) {
+					if ((y == 0) || _pathMap.at(x, y - 1) != p) {
+						if ((y >= _pathBottom) || _pathMap.at(x, y + 1) != p) {
+							return ydist;
+						} else {
+							yy = y + 1;
+						}
+					} else {
+						yy = y - 1;
+					}
+				} else {
+					xx = x + 1;
+				}
+			} else {
+				xx = x - 1;
+			}
+		} else {
+			if ((y == 0) || _pathMap.at(x, y - 1) != p) {
+				if ((y >= _pathBottom) || _pathMap.at(x, y + 1) != p) {
+					if ((x == 0) || _pathMap.at(x - 1, y) != p) {
+						if (x >= _pathRight || _pathMap.at(x + 1, y) != p) {
+							return ydist;
+						} else {
+							xx = x + 1;
+						}
+					} else {
+						xx = x - 1;
+					}
+				} else {
+					yy = y + 1;
+				}
+			} else {
+				yy = y - 1;
+			}
+		}
+
+		if (xx == DAT_00412c8c && yy == DAT_00412c90) {
+			INT_00412ca0 = 2;
+			if (x <= xx) {
+				INT_00412ca0 = 6;
+				if (x >= xx) {
+					INT_00412ca0 = 4;
+					if (y <= yy)
+						INT_00412ca0 = 0;
+				}
+			}
+			if (px != -1) {
+				if (py > yy) {
+					INT_00412c9c = 3;
+					if (px <= xx) {
+						INT_00412c9c = 5;
+						if (px >= xx)
+							INT_00412c9c = 4;
+					}
+				} else if (py < yy) {
+					INT_00412c9c = 1;
+					if (px <= xx) {
+						INT_00412c9c = 7;
+						if (px >= xx)
+							INT_00412c9c = 0;
+					}
+				} else {
+					INT_00412c9c = 2;
+					if (px <= xx)
+						INT_00412c9c = 6;
+				}
+			}
+			DAT_00417804 = 1;
+			return 1;
+		}
+
+		py = y;
+		px = x;
+
+		y = yy;
+		x = xx;
+
+		if (p == 4)
+			p = 6;
+		else if (p == 5)
+			p = 4;
+		else if (p == 6)
+			p = 5;
+	}
+}
+
+byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
+	uint8 ret = 0;
+
+	for (int32 y = 0; y < _pathBottom; y++) {
+		for (int32 x = 0; x < _pathRight; x++) {
+			uint8 &rval = _pathMap.at(x, y);
+			if ( rval == 0) {
+				if ( (x > 0 && _pathMap.at(x - 1, y) == cv) ||
+					(x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
+					(y > 0 && _pathMap.at(x, y - 1) == cv) ||
+					(y < _pathBottom && _pathMap.at(x, y + 1) == cv) ) {
+					ret = sv;
+					rval = sv;
+				}
+			} else if (rval == 2) {
+				if ( (x > 0 && _pathMap.at(x - 1, y) == cv) ||
+					(x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
+					(y > 0 && _pathMap.at(x, y - 1) == cv) ||
+					(y < _pathBottom && _pathMap.at(x, y + 1) == cv) ) {
+					DAT_00412c94 = x;
+					DAT_00412c98 = y;
+					return 1;
+				}
+			}
+		}
+	}
+	return ret;
+}
+
 
 void GamosEngine::FUN_00404fcc(int32 id) {
 	warning("Not implemented FUN_00404fcc");
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index d1f2def584c..aca1d0b1d8a 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -356,11 +356,25 @@ private:
 	int32 DAT_004173f8 = 0;
 	int32 DAT_004173fc = 0;
 	uint8 DAT_00417803 = 0;
-
+	uint8 DAT_00417804 = 0;
 	uint8 DAT_00417805 = 0;
 
 	uint8 RawKeyCode = 0;
 
+
+	/* path find ? */
+	int32 DAT_00412c8c = 0;
+	int32 DAT_00412c90 = 0;
+	int32 DAT_00412c94 = 0;
+	int32 DAT_00412c98 = 0;
+	int32 INT_00412c9c = 0;
+	int32 INT_00412ca0 = 0;
+
+	Array2D<uint8> _pathMap;
+	uint32 _statesCount = 0;
+	int32 _pathRight = 0;
+	int32 _pathBottom = 0;
+
 	Common::Array<Common::Rect> _dirtyRects;
 
 	bool _needReload = false;
@@ -493,6 +507,18 @@ protected:
 
 	void FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, int32 x, int32 y);
 
+	void FUN_00407db8(uint8 p);
+	void FUN_00408648(uint8 p1, uint8 p2, uint8 p3);
+	void FUN_004084bc(uint8 p);
+	void FUN_00408510(uint8 p);
+	void FUN_0040856c();
+	void FUN_004085d8(uint8 p);
+	void FUN_0040841c(bool p);
+	byte FUN_00407e2c();
+	byte FUN_00407f70(uint8 p);
+	byte FUN_004081b8(uint8 cv, uint8 sv);
+
+
 	void vmCallDispatcher(VM *vm, uint32 funcID);
 
 


Commit: 779eb34a58d3109ce0c62ac3d4ab92782b576445
    https://github.com/scummvm/scummvm/commit/779eb34a58d3109ce0c62ac3d4ab92782b576445
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:28+01:00

Commit Message:
GAMOS: vm callback func 1

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index c3ba5692ec2..98371d174b6 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2036,6 +2036,10 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		DAT_004177ff = true;
 		vm->EAX.val = 1;
 		break;
+	case 1:
+		vm->EAX.val = PTR_00417218->y == -1 ? 1 : 0;
+		break;
+
 	case 2:
 		arg1 = vm->pop32();
 		if (PTR_00417218->x == -1)


Commit: 86b51afe05dca3a1585abfc745404f8441a159e0
    https://github.com/scummvm/scummvm/commit/86b51afe05dca3a1585abfc745404f8441a159e0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:28+01:00

Commit Message:
GAMOS: Correctly load samples

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 98371d174b6..3e1cae1f905 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -470,7 +470,8 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_50) {
 		/* just ignore it? */
 	} else if (tp == RESTP_51) {
-		_soundSamples[pid].assign(data, data + dataSize);
+		uint32 datSz = getU32(data) & (~3);
+		_soundSamples[pid].assign(data + 4, data + 4 + datSz);
 		//printf("sound  size %d\n", dataSize);
 	} else if (tp == RESTP_52) {
 		return loadRes52(pid, data, dataSize);


Commit: e138582fc4d3e9996259e8c353ff1fbaf7800de8
    https://github.com/scummvm/scummvm/commit/e138582fc4d3e9996259e8c353ff1fbaf7800de8
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:29+01:00

Commit Message:
GAMOS: Implement blitter

Changed paths:
  A engines/gamos/blit.cpp
  A engines/gamos/blit.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/module.mk


diff --git a/engines/gamos/blit.cpp b/engines/gamos/blit.cpp
new file mode 100644
index 00000000000..ac642018d4d
--- /dev/null
+++ b/engines/gamos/blit.cpp
@@ -0,0 +1,167 @@
+/* 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 "gamos/blit.h"
+
+namespace Gamos {
+
+void Blitter::blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
+    if (dst->format != src->format)
+        return;
+
+    Common::Rect drect = dstRect;
+    if (drect.right <= drect.left)
+        drect.right = dst->w;
+    if (drect.bottom <= drect.top)
+        drect.bottom = dst->h;
+
+    drect.clip(dst->w, dst->h);
+
+    Common::Rect srect = srcRect;
+    srect.translate(dstRect.left, dstRect.top);
+    srect.clip(drect);
+
+    drect = srect;
+    srect.translate(-dstRect.left, -dstRect.top);
+
+    if (srect.isEmpty())
+        return;
+
+    for(int y = srect.top; y < srect.bottom; y++) {
+        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+        byte *psrc = (byte *)src->getBasePtr(srect.left, y);
+        for(int x = srect.left; x < srect.right; x++) {
+            if (*psrc != 0)
+                *pdst = *psrc;
+
+            psrc++;
+            pdst++;
+        }
+    }
+
+}
+
+void Blitter::blitFlipH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
+    if (dst->format != src->format)
+        return;
+
+    Common::Rect drect = dstRect;
+    if (drect.right <= drect.left)
+        drect.right = dst->w;
+    if (drect.bottom <= drect.top)
+        drect.bottom = dst->h;
+
+    drect.clip(dst->w, dst->h);
+
+    Common::Rect srect = srcRect;
+    srect.translate(dstRect.left, dstRect.top);
+    srect.clip(drect);
+
+    drect = srect;
+    srect.translate(-dstRect.left, -dstRect.top);
+
+    if (srect.isEmpty())
+        return;
+
+    for(int y = srect.top; y < srect.bottom; y++) {
+        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+        byte *psrc = (byte *)src->getBasePtr(srect.right - 1, y);
+        for(int x = srect.left; x < srect.right; x++) {
+            if (*psrc != 0)
+                *pdst = *psrc;
+
+            psrc--;
+            pdst++;
+        }
+    }
+}
+
+void Blitter::blitFlipV(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
+    if (dst->format != src->format)
+        return;
+
+    Common::Rect drect = dstRect;
+    if (drect.right <= drect.left)
+        drect.right = dst->w;
+    if (drect.bottom <= drect.top)
+        drect.bottom = dst->h;
+
+    drect.clip(dst->w, dst->h);
+
+    Common::Rect srect = srcRect;
+    srect.translate(dstRect.left, dstRect.top);
+    srect.clip(drect);
+
+    drect = srect;
+    srect.translate(-dstRect.left, -dstRect.top);
+
+    if (srect.isEmpty())
+        return;
+
+    for(int y = srect.top; y < srect.bottom; y++) {
+        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+        byte *psrc = (byte *)src->getBasePtr(srect.left, srect.bottom - 1 - y);
+        for(int x = srect.left; x < srect.right; x++) {
+            if (*psrc != 0)
+                *pdst = *psrc;
+
+            psrc++;
+            pdst++;
+        }
+    }
+}
+
+void Blitter::blitFlipVH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
+    if (dst->format != src->format)
+        return;
+
+    Common::Rect drect = dstRect;
+    if (drect.right <= drect.left)
+        drect.right = dst->w;
+    if (drect.bottom <= drect.top)
+        drect.bottom = dst->h;
+
+    drect.clip(dst->w, dst->h);
+
+    Common::Rect srect = srcRect;
+    srect.translate(dstRect.left, dstRect.top);
+    srect.clip(drect);
+
+    drect = srect;
+    srect.translate(-dstRect.left, -dstRect.top);
+
+    if (srect.isEmpty())
+        return;
+
+    for(int y = srect.top; y < srect.bottom; y++) {
+        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+        byte *psrc = (byte *)src->getBasePtr(srect.right - 1, srect.bottom - 1 - y);
+        for(int x = srect.left; x < srect.right; x++) {
+            if (*psrc != 0)
+                *pdst = *psrc;
+
+            psrc--;
+            pdst++;
+        }
+    }
+}
+
+}
diff --git a/engines/gamos/blit.h b/engines/gamos/blit.h
new file mode 100644
index 00000000000..14896c44a7e
--- /dev/null
+++ b/engines/gamos/blit.h
@@ -0,0 +1,61 @@
+/* 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/>.
+ *
+ */
+
+#ifndef GAMOS_BLIT_H
+#define GAMOS_BLIT_H
+
+#include "graphics/surface.h"
+#include "common/rect.h"
+
+namespace Gamos {
+
+class Blitter {
+protected:
+    static void blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+    static void blitFlipH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+    static void blitFlipV(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+    static void blitFlipVH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+
+public:
+    static void blit(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect, uint flip = 0) {
+        switch(flip) {
+            default:
+                blitNormal(src, srcRect, dst, dstRect);
+                break;
+
+            case Graphics::FLIP_H:
+                blitFlipH(src, srcRect, dst, dstRect);
+                break;
+
+            case Graphics::FLIP_V:
+                blitFlipV(src, srcRect, dst, dstRect);
+                break;
+
+            case Graphics::FLIP_VH:
+                blitFlipVH(src, srcRect, dst, dstRect);
+                break;
+        }
+    };
+};
+
+}
+
+#endif
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 3e1cae1f905..094a8be182d 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1987,8 +1987,23 @@ void GamosEngine::doDraw() {
 	}
 
 	for(Object *o: drawList) {
-		if (o->pImg && loadImage(o->pImg->image))
-			_screen->blitFrom(o->pImg->image->surface, Common::Point(o->x, o->y));
+		/*if (o->pImg && loadImage(o->pImg->image)) {
+			Common::Rect out(Common::Point(o->x, o->y), o->pImg->image->surface.w, o->pImg->image->surface.h);
+			out.clip(_screen->getBounds());
+			out.translate(-o->x, -o->y);
+			_screen->copyRectToSurfaceWithKey(o->pImg->image->surface, o->x+out.left, o->y+out.top, out, 0);
+		}*/
+		if (o->pImg && loadImage(o->pImg->image)) {
+			uint flip = 0;
+			if (o->flags & 8)
+				flip |= Graphics::FLIP_H;
+			if (o->flags & 0x10)
+				flip |= Graphics::FLIP_V;
+			Blitter::blit(&o->pImg->image->surface,
+						   Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
+		                   _screen->surfacePtr(),
+						   Common::Rect(o->x, o->y, _screen->w, _screen->h), flip);
+		}
 	}
 
 	_screen->update();
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index aca1d0b1d8a..9cca3f638de 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -55,6 +55,8 @@
 
 #include "gamos/array2d.h"
 
+#include "gamos/blit.h"
+
 namespace Gamos {
 
 struct GamosGameDescription;
diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
index 66c4a6919e9..d763707cab8 100644
--- a/engines/gamos/module.mk
+++ b/engines/gamos/module.mk
@@ -1,6 +1,7 @@
 MODULE := engines/gamos
 
 MODULE_OBJS = \
+	blit.o \
 	gamos.o \
 	file.o \
 	console.o \


Commit: d138814d4704e296f990c70a7a71b51054d86cce
    https://github.com/scummvm/scummvm/commit/d138814d4704e296f990c70a7a71b51054d86cce
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:29+01:00

Commit Message:
GAMOS: fix blit

Changed paths:
    engines/gamos/blit.cpp


diff --git a/engines/gamos/blit.cpp b/engines/gamos/blit.cpp
index ac642018d4d..859d709794e 100644
--- a/engines/gamos/blit.cpp
+++ b/engines/gamos/blit.cpp
@@ -45,9 +45,9 @@ void Blitter::blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Gr
     if (srect.isEmpty())
         return;
 
-    for(int y = srect.top; y < srect.bottom; y++) {
+    for(int y = 0; y < srect.height(); y++) {
         byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-        byte *psrc = (byte *)src->getBasePtr(srect.left, y);
+        byte *psrc = (byte *)src->getBasePtr(srect.left, srect.top + y);
         for(int x = srect.left; x < srect.right; x++) {
             if (*psrc != 0)
                 *pdst = *psrc;


Commit: f6219afdaa836b2c42a6dd751f1fcbe32a0d8966
    https://github.com/scummvm/scummvm/commit/f6219afdaa836b2c42a6dd751f1fcbe32a0d8966
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:29+01:00

Commit Message:
GAMOS: little refactor

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 094a8be182d..befb019c8f2 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -419,38 +419,43 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 				_states.at(i) = 0xf0fe;
 
 			DAT_004177f8 = 1;
-			ProcessScript(true, data, dataSize);
+
+			Actions acts;
+			acts.parse(data, dataSize);
+			doActions(acts, true);
+
 			if (_needReload)
 				warning("needs reload from loadResHandler, CANT HAPPEN!");
+
 			DAT_004177f8 = 0;
 			FUN_00404fcc(pid);
 		}
 	} else if (tp == RESTP_20) {
 		if (dataSize != 4)
 			return false;
-		_someActsArr[pid].unk1 = getU32(data);
+		_objectActions[pid].unk1 = getU32(data);
 	} else if (tp == RESTP_21) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
-		_someActsArr[pid].script1 = _loadedDataSize + p3;
+		_objectActions[pid].onCreateAddress = _loadedDataSize + p3;
 		//printf("RESTP_21 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_22) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
-		_someActsArr[pid].script2 = _loadedDataSize + p3;
+		_objectActions[pid].onDeleteAddress = _loadedDataSize + p3;
 		//printf("RESTP_22 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_23) {
 		if (dataSize % 4 != 0 || dataSize < 4)
 			return false;
-		_someActsArr[pid].scriptS.resize(dataSize / 4);
+		_objectActions[pid].actions.resize(dataSize / 4);
 	} else if (tp == RESTP_2A) {
-		ScriptS &scr = _someActsArr[pid].scriptS[p1];
-		scr.data.assign(data, data + dataSize);
+		Actions &scr = _objectActions[pid].actions[p1];
+		scr.parse(data, dataSize);
 	} else if (tp == RESTP_2B) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
-		_someActsArr[pid].scriptS[p1].codes1 = _loadedDataSize + p3;
+		_objectActions[pid].actions[p1].conditionAddress = _loadedDataSize + p3;
 		//printf("RESTP_2B %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_2C) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
-		_someActsArr[pid].scriptS[p1].codes2 = _loadedDataSize + p3;
+		_objectActions[pid].actions[p1].functionAddress = _loadedDataSize + p3;
 		//printf("RESTP_2C %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
 		warning("Data 38 size %zu", dataSize);
@@ -477,18 +482,18 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		return loadRes52(pid, data, dataSize);
 		//printf("midi  size %d\n", dataSize);
 	} else if (tp == RESTP_60) {
-		_dat60[pid].assign(data, data + dataSize);
+		_subtitleActions[pid].parse(data, dataSize);
 	} else if (tp == RESTP_61) {
 		Common::MemoryReadStream dataStream(data, dataSize, DisposeAfterUse::NO);
 		const int count = dataSize / 8;
-		_dat61[pid].resize(count);
+		_subtitlePoints[pid].resize(count);
 
 		for (int i = 0; i < count; i++) {
-			Dat61 &d = _dat61[pid][i];
+			SubtitlePoint &d = _subtitlePoints[pid][i];
 
 			d.x = dataStream.readSint16LE();
 			d.y = dataStream.readSint16LE();
-			d.v = dataStream.readUint16LE();
+			d.sprId = dataStream.readUint16LE();
 
 			dataStream.skip(2);
 		}
@@ -566,7 +571,7 @@ bool GamosEngine::initMainDatas() {
 	_movieOffsets.clear();
 	_movieOffsets.resize(_movieCount, 0);
 
-	_drawElements.clear();
+	_objects.clear();
 
 	return true;
 }
@@ -669,14 +674,14 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_thing2.clear();
 	_thing2.resize(unk1Count);
 
-	_someActsArr.clear();
-	_someActsArr.resize(actsCount);
+	_objectActions.clear();
+	_objectActions.resize(actsCount);
 
-	_dat60.clear();
-	_dat61.clear();
+	_subtitleActions.clear();
+	_subtitlePoints.clear();
 
-	_dat60.resize(dat6xCount);
-	_dat61.resize(dat6xCount);
+	_subtitleActions.resize(dat6xCount);
+	_subtitlePoints.resize(dat6xCount);
 
 	_loadedDataSize = 0;
 	VM::clearMemory();
@@ -982,14 +987,10 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	return 1;
 }
 
+int32 GamosEngine::doActions(const Actions &a, bool absolute) {
+	Common::Array<Common::Point> ARR_00412208(512);
 
-int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int32 code1, int32 code2) {
-
-	Common::Array<uint16> ARR_00412208(512);
-
-	Common::MemoryReadStream rstream(data, dataSize);
-
-	if (!p1) {
+	if (!absolute) {
 		DAT_00417228 = PTR_00417218->pos;
 		DAT_0041722c = PTR_00417218->blk;
 	} else {
@@ -1000,7 +1001,7 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 		//DAT_0041723c = -1;
 		DAT_0041722c = 0;
 		DAT_00417228 = 0;
-		BYTE_004177f6 = 0x10;
+		BYTE_004177f6 = 1;
 		_preprocDataId = 0;
 		PTR_004173e8 = nullptr;
 	}
@@ -1011,36 +1012,21 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 	int32 spos = -1;
 	int32 sbuf[6];
 
-	uint8 b[4];
-	rstream.read(b, 4);
 
-	//printf("FLAGS %x\n", b[0]);
-
-	if (b[0] & 1) {
-		if (code1 != -1) {
-			if (!doScript(code1))
+	if (a.flags & Actions::HAS_CONDITION) {
+		if (a.conditionAddress != -1) {
+			if (!doScript(a.conditionAddress))
 				return 0;
 			if (_needReload)
 				return 0;
 		}
-		rstream.skip(4);
 	}
 
-	if (b[0] & 2) {
+	if (a.flags & Actions::HAS_ACT2) {
 		bool fastSkipAll = false;
-		while (true) {
-			uint16 sz = rstream.readUint16LE();
-			uint8 f = rstream.readByte();
-			uint8 t = rstream.readByte();
+		for(const ActTypeEntry &ate : a.act_2) {
 
-			if (fastSkipAll) {
-				rstream.skip(sz * 4);
-				if (f & 1)
-					break;
-				continue;
-			}
-
-			if (t == 4) {
+			if (ate.t == 4) {
 				spos++;
 				if (spos == 0) {
 					sbuf[0] = 0;
@@ -1053,93 +1039,90 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 			} else {
 				spos = -1;
 			}
+
 			int32 ps = spos * 2 + 1;
-			for (int read = 0; read < sz; read++) {
-				byte c[4];
-				rstream.read(c, 4);
-				preprocessData(_preprocDataId, c);
+
+			for (int i = 0; i < ate.entries.size(); i++) {
+				/* use copy of entrie because it will be modified */
+				ActEntry e = ate.entries[i];
+
+				preprocessData(_preprocDataId, &e);
 
 				uint16 fb = 0;
-				if (!p1) {
+				if (!absolute) {
 					Common::Point xy;
-					xy.x = ((int8)c[2] + DAT_00417220 + _statesWidth) % _statesWidth;
-					xy.y = ((int8)c[3] + DAT_00417224 + _statesHeight) % _statesHeight;
+					xy.x = (e.x + DAT_00417220 + _statesWidth) % _statesWidth;
+					xy.y = (e.y + DAT_00417224 + _statesHeight) % _statesHeight;
 					fb = _states.at( xy );
 				} else {
-					fb = _states.at(c[2], c[3]);
+					fb = _states.at(e.x, e.y);
 				}
 
 				uint8 lb = fb & 0xff;
 				uint8 hb = (fb >> 8) & 0xff;
 
 				int cval = 0;
-				int fnc = c[1] >> 4;
-				if ((c[1] & 1) == 0) {
-					if (c[0] == lb && (c[1] & hb & 0xf0)) {
+				int fnc = e.t;
+				if ((e.flags & 1) == 0) {
+					if (e.value == lb && ((hb >> 4) & e.t)) {
 						cval = 2;
 					}
 				} else if (lb != 0xfe &&
-					       (_thing2[c[0]].field_0[(fb & 0xff) >> 3] & (1 << (fb & 7))) != 0) {
+					       (_thing2[e.value].field_0[(fb & 0xff) >> 3] & (1 << (fb & 7))) != 0) {
 
-					if (!_thing2[c[0]].field_2.empty()) {
-						c[1] = (c[1] & 0xf) | _thing2[c[0]].field_2[lb];
-						preprocessData(fnc + 8, c);
+					if (!_thing2[e.value].field_2.empty()) {
+						e.t = _thing2[e.value].field_2[lb] >> 4;
+						preprocessData(fnc + 8, &e);
 					}
 
-					if (hb & c[1] & 0xf0) {
+					if ((hb >> 4) & e.t) {
 						cval = 2;
 					}
 				}
 
-				if ((c[1] & 2) == cval) {
-					if ((c[1] & 0xc) == 0) {
-						rstream.skip((sz - (read + 1)) * 4);
+				if ((e.flags & 2) == cval) {
+					if ((e.flags & 0xc) == 0) {
 						break;
 					}
-					if ((c[1] & 0xc) == 4)
+					if ((e.flags & 0xc) == 4)
 						return 0;
-					if ((c[1] & 0xc) == 8) {
+					if ((e.flags & 0xc) == 8) {
 						fastSkipAll = true;
-						rstream.skip((sz - (read + 1)) * 4);
 						break;
 					}
-					ARR_00412208[ sbuf[ps] ] = (c[3] << 8) | c[2];
+					ARR_00412208[ sbuf[ps] ] = Common::Point(e.x, e.y);
 					sbuf[ps]++;
-				} else if ((sz - read) == 1 && spos > -1 && sbuf[spos * 2] == sbuf[ps]) {
+				} else if ( (ate.entries.size() - i) == 1 && spos > -1 && sbuf[spos * 2] == sbuf[ps]) {
 					return 0;
 				}
 			}
-
-			if (f & 1)
-				break;
 		}
 	}
 
 	BYTE_00412200 = 0;
 
-	if (b[0] & 4) {
-		byte s = b[1];
-		preprocessData(_preprocDataId, b);
-		preprocessDataB1(b[1] >> 4, b);
+	if (a.flags & Actions::HAS_ACT4) {
+		ActEntry e = a.act_4;
+		preprocessData(_preprocDataId, &e);
+		preprocessDataB1(e.t, &e);
 		rnd();
-		b[1] = (b[1] & 0xf0) | (s & 0xf);
-		FUN_00402a68(b);
+		e.flags = a.act_4.flags;
+		FUN_00402a68(e);
 		if (_needReload)
 			return 0;
 	}
 
 	BYTE_004177fc = 0;
-	if (b[0] & 8) {
+	if (a.flags & Actions::HAS_FUNCTION) {
 		uint32 fldsv;
 		if (PTR_00417218)
 			fldsv = PTR_00417218->fld_5;
-		if (code2 != -1)
-			doScript(code2);
+		if (a.functionAddress != -1)
+			doScript(a.functionAddress);
 		if (_needReload)
 			return 0;
-		rstream.skip(4);
 		if (BYTE_004177fc == 0 && BYTE_00412200 == 0 && PTR_00417218 && PTR_00417218->fld_5 != fldsv && PTR_00417218->y != -1)
-			addDirtRectOnObject( &_drawElements[PTR_00417218->y] );
+			addDirtRectOnObject( &_objects[PTR_00417218->y] );
 	}
 
 	if (BYTE_004177fc == 0 && BYTE_00412200 != 0)
@@ -1147,85 +1130,50 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 
 	int32 retval = 0;
 
-	if (b[0] & 0x10) {
+	if (a.flags & Actions::HAS_ACT10) {
 		int ivar5 = -1;
-		while (true) {
-			uint16 dcount = rstream.readUint16LE();
-			uint8 dbits = rstream.readByte();
-			uint8 dtype = rstream.readByte();
-
-			/* set next pos before next iteration */
-			uint32 nextpos = rstream.pos() + (dcount * 4);
-
-			switch (dtype) {
+		for(const ActTypeEntry &ate : a.act_10) {
+			switch (ate.t)
+			{
 			case 0: {
-				uint16 rndval = rndRange16(b[1] & 3);
-
-				if (rndval == 2) {
-					rstream.skip(dcount * 4);
-					dcount = rstream.readUint16LE();
-					rstream.skip(2 + dcount * 4);
-					dcount = rstream.readUint16LE();
-					rstream.skip(2);
-				} else if (rndval == 1) {
-					rstream.skip(dcount * 4);
-					dcount = rstream.readUint16LE();
-					rstream.skip(2);
-				}
-
+				uint16 rndval = rndRange16(a.num_act_10e);
 				rnd();
-
-				for (int i = 0; i < dcount; i++) {
-					byte d[4];
-					rstream.read(d, 4);
-					retval += processData(p1, d);
-
+				for (ActEntry e : a.act_10end[rndval]) {
+					retval += processData(e, absolute);
 					if (_needReload)
 						return 0;
 				}
-
-				return retval + 1;
 			} break;
 
 			case 1: {
-				int32 num = rndRange16(dcount);
-
-				for (int i = 0; i < dcount; i++) {
-					byte d[4];
-					rstream.read(d, 4);
-
+				int32 num = rndRange16(ate.entries.size());
+				for (int i = 0; i < ate.entries.size(); i++) {
 					if (num != 0) {
-						retval += processData(p1, d);
+						ActEntry e = ate.entries[i];
+						retval += processData(e, absolute);
 						if (_needReload)
 							return 0;
 					}
-
 					num--;
 				}
 
 			} break;
 
 			case 2: {
-				rstream.skip(4 * rndRange16(dcount));
-
-				byte d[4];
-				rstream.read(d, 4);
-
-				retval += processData(p1, d);
+				int32 num = rndRange16(ate.entries.size());
+				ActEntry e = ate.entries[num];
+				retval += processData(e, absolute);
 				if (_needReload)
 						return 0;
 			} break;
 
 			case 3: {
-				for (int i = 0; i < dcount; i++) {
+				for (int i = 0; i < ate.entries.size(); i++) {
 					uint16 doproc = rndRange16(2);
 
-					byte d[4];
-					rstream.read(d, 4);
-
 					if (doproc != 0) {
-						retval += processData(p1, d);
-
+						ActEntry e = ate.entries[i];
+						retval += processData(e, absolute);
 						if (_needReload)
 							return 0;
 					}
@@ -1240,14 +1188,11 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 
 				uint32 lb = rnd() >> 0x10;
 				uint32 idx = ((sbuf[ivar5 * 2 + 1] - sbuf[ivar5 * 2]) * lb + sbuf[ivar5 * 2]) >> 0x10;
-				uint16 tval = ARR_00412208[ idx ];
+				Common::Point point = ARR_00412208[ idx ];
 
-				for (int i = 0; i < dcount; i++) {
-					byte d[4];
-					rstream.read(d, 4);
-
-					if ( ((d[3] << 8) | d[2]) == tval ) {
-						retval += processData(p1, d);
+				for (ActEntry e : ate.entries) {
+					if ( Common::Point(e.x, e.y) == point ) {
+						retval += processData(e, absolute);
 						if (_needReload)
 							return 0;
 						break;
@@ -1256,14 +1201,9 @@ int32 GamosEngine::ProcessScript(bool p1, const byte *data, size_t dataSize, int
 			} break;
 
 			}
-
-			rstream.seek(nextpos);
-
-			if (dbits & 1)
-				break;
 		}
-
 	}
+
 	return retval + 1;
 }
 
@@ -1273,7 +1213,7 @@ uint32 GamosEngine::getU32(const void *ptr) {
 }
 
 
-void GamosEngine::preprocessData(int id, byte *data) {
+void GamosEngine::preprocessData(int id, ActEntry *e) {
 	switch (id) {
 
 	default:
@@ -1282,61 +1222,61 @@ void GamosEngine::preprocessData(int id, byte *data) {
 
 	case 1:
 	case 10: {
-		static const uint8 lookup[16] = {0, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0x10, 0x30, 0x50, 0x70, 0x90, 0xB0, 0xD0, 0xF0};
-		int8 tmp = (int8)data[3];
-		data[3] = data[2];
-		data[2] = -tmp;
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15};
+		int8 tmp = e->y;
+		e->y = e->x;
+		e->x = -tmp;
+		e->t = lookup[ e->t ];
 	} break;
 
 	case 2:
 	case 12: {
-		static const uint8 lookup[16] = {0, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0};
-		data[3] = -((int8)data[3]);
-		data[2] = -((int8)data[2]);
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15};
+		e->y = -e->y;
+		e->x = -e->x;
+		e->t = lookup[ e->t ];
 	} break;
 
 	case 3:
 	case 16: {
-		static const uint8 lookup[16] = {0, 0x80, 0x10, 0x90, 0x20, 0xA0, 0x30, 0xB0, 0x40, 0xC0, 0x50, 0xD0, 0x60, 0xE0, 0x70, 0xF0};
-		int8 tmp = (int8)data[2];
-		data[2] = data[3];
-		data[3] = -tmp;
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15};
+		int8 tmp = e->x;
+		e->x = e->y;
+		e->y = -tmp;
+		e->t = lookup[ e->t ];
 	} break;
 
 	case 4: {
-		static const uint8 lookup[16] = {0, 0x10, 0x80, 0x90, 0x40, 0x50, 0xC0, 0xD0, 0x20, 0x30, 0xA0, 0xB0, 0x60, 0x70, 0xE0, 0xF0};
-		data[2] = -((int8)data[2]);
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 1, 8, 9, 4, 5, 12, 13, 2, 3, 10, 11, 6, 7, 14, 15};
+		e->x = -e->x;
+		e->t = lookup[ e->t ];
 	} break;
 
 	case 5: {
-		static const uint8 lookup[16] = {0, 0x20, 0x10, 0x30, 0x80, 0xA0, 0x90, 0xB0, 0x40, 0x60, 0x50, 0x70, 0xC0, 0xE0, 0xD0, 0xF0};
-		int8 tmp = (int8)data[2];
-		data[2] = -((int8)data[3]);
-		data[3] = -tmp;
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15};
+		int8 tmp = e->x;
+		e->x = -e->y;
+		e->y = -tmp;
+		e->t = lookup[ e->t ];
 	} break;
 
 	case 6: {
-		static const uint8 lookup[16] = {0, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70, 0x80, 0xC0, 0xA0, 0xE0, 0x90, 0xD0, 0xB0, 0xF0};
-		data[3] = -((int8)data[3]);
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
+		e->y = -e->y;
+		e->t = lookup[ e->t ];
 	} break;
 
 	case 7: {
-		static const uint8 lookup[16] = {0, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0};
-		uint8 tmp = data[2];
-		data[2] = data[3];
-		data[3] = tmp;
-		data[1] = (data[1] & 0xf) | lookup[ (data[1] >> 4) & 0xf ];
+		static const uint8 lookup[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
+		uint8 tmp = e->x;
+		e->x = e->y;
+		e->y = tmp;
+		e->t = lookup[ e->t ];
 	} break;
 	}
 }
 
-void GamosEngine::preprocessDataB1(int id, byte *data) {
+void GamosEngine::preprocessDataB1(int id, ActEntry *e) {
 	switch (id) {
 
 		default:
@@ -1347,85 +1287,85 @@ void GamosEngine::preprocessDataB1(int id, byte *data) {
 		case 2:
 		case 4:
 		case 8:
-			data[1] &= 0xf0;
+			//e->t = e->t;
 			break;
 
 		case 3: {
-			static const uint8 lookup[2] = {0x10, 0x20};
-			data[1] = lookup[rndRange16(2)];
+			static const uint8 lookup[2] = {1, 2};
+			e->t = lookup[rndRange16(2)];
 		} break;
 
 		case 5: {
-			static const uint8 lookup[2] = {0x10, 0x40};
-			data[1] = lookup[rndRange16(2)];
+			static const uint8 lookup[2] = {1, 4};
+			e->t = lookup[rndRange16(2)];
 		} break;
 
 		case 6: {
-			static const uint8 lookup[2] = {0x20, 0x40};
-			data[1] = lookup[rndRange16(2)];
+			static const uint8 lookup[2] = {2, 4};
+			e->t = lookup[rndRange16(2)];
 		} break;
 
 		case 7: {
-			static const uint8 lookup[3] = {0x10, 0x20, 0x40};
-			data[1] = lookup[rndRange16(3)];
+			static const uint8 lookup[3] = {1, 2, 4};
+			e->t = lookup[rndRange16(3)];
 		} break;
 
 		case 9: {
-			static const uint8 lookup[2] = {0x10, 0x80};
-			data[1] = lookup[rndRange16(2)];
+			static const uint8 lookup[2] = {1, 8};
+			e->t = lookup[rndRange16(2)];
 		} break;
 
 		case 0xa: {
-			static const uint8 lookup[2] = {0x20, 0x80};
-			data[1] = lookup[rndRange16(2)];
+			static const uint8 lookup[2] = {2, 8};
+			e->t = lookup[rndRange16(2)];
 		} break;
 
 		case 0xb: {
-			static const uint8 lookup[3] = {0x10, 0x20, 0x80};
-			data[1] = lookup[rndRange16(3)];
+			static const uint8 lookup[3] = {1, 2, 8};
+			e->t = lookup[rndRange16(3)];
 		} break;
 
 		case 0xc: {
-			static const uint8 lookup[2] = {0x40, 0x80};
-			data[1] = lookup[rndRange16(2)];
+			static const uint8 lookup[2] = {4, 8};
+			e->t = lookup[rndRange16(2)];
 		} break;
 
 		case 0xd: {
-			static const uint8 lookup[3] = {0x10, 0x40, 0x80};
-			data[1] = lookup[rndRange16(3)];
+			static const uint8 lookup[3] = {1, 4, 8};
+			e->t = lookup[rndRange16(3)];
 		} break;
 
 		case 0xe: {
-			static const uint8 lookup[3] = {0x20, 0x40, 0x80};
-			data[1] = lookup[rndRange16(3)];
+			static const uint8 lookup[3] = {2, 4, 8};
+			e->t = lookup[rndRange16(3)];
 		} break;
 
 		case 0xf: {
-			static const uint8 lookup[4] = {0x10, 0x20, 0x40, 0x80};
-			data[1] = lookup[rndRange16(4)];
+			static const uint8 lookup[4] = {1, 2, 4, 8};
+			e->t = lookup[rndRange16(4)];
 		} break;
 	}
 }
 
-int GamosEngine::processData(int id, byte *data) {
-	preprocessData(_preprocDataId, data);
-	if (id == 0) {
-		FUN_0040283c( ((int8)data[3] + DAT_00417224 + _statesHeight) % _statesHeight,
-		              ((int8)data[2] + DAT_00417220 + _statesWidth) % _statesWidth,
-					  data );
+int GamosEngine::processData(ActEntry e, bool absolute) {
+	preprocessData(_preprocDataId, &e);
+	if (!absolute) {
+		FUN_0040283c(e,
+					 (e.x + DAT_00417220 + _statesWidth) % _statesWidth,
+					 (e.y + DAT_00417224 + _statesHeight) % _statesHeight );
 		if (_needReload)
 			return 0;
-		return data[2] == 0 && data[3] == 0;
+		return e.x == 0 && e.y == 0;
 	} else {
-		FUN_0040283c( (int8)data[3], (int8)data[2],	data);
+		FUN_0040283c(e, e.x, e.y);
 		return 0;
 	}
 }
 
-void GamosEngine::FUN_00402a68(const byte *d) {
-	if (d[2] != 0 || d[3] != 0) {
-		DAT_00417220 = ((int8)d[2] + DAT_00417220 + _statesWidth) % _statesWidth;
-		DAT_00417224 = ((int8)d[3] + DAT_00417224 + _statesHeight) % _statesHeight;
+void GamosEngine::FUN_00402a68(ActEntry e) {
+	if (e.x != 0 || e.y != 0) {
+		DAT_00417220 = (e.x + DAT_00417220 + _statesWidth) % _statesWidth;
+		DAT_00417224 = (e.y + DAT_00417224 + _statesHeight) % _statesHeight;
 
 		uint8 t = PTR_00417218->fld_3;
 
@@ -1446,10 +1386,9 @@ void GamosEngine::FUN_00402a68(const byte *d) {
         BYTE_00412200 = 1;
 	}
 
-	if ((d[1] & 0xf0) != BYTE_004177f6) {
-        BYTE_004177f6 = d[1] & 0xf0;
-        PTR_00417218->flags = PTR_00417218->flags & 0xf;
-        PTR_00417218->flags = PTR_00417218->flags | BYTE_004177f6;
+	if (e.t != BYTE_004177f6) {
+        BYTE_004177f6 = e.t;
+        PTR_00417218->flags = (PTR_00417218->flags & 0xf) | (e.t << 4);
 
 		uint16 &tref = _states.at(DAT_00417220, DAT_00417224);
 		tref = (tref & 0xff) | (BYTE_004177f6 << 8);
@@ -1458,61 +1397,59 @@ void GamosEngine::FUN_00402a68(const byte *d) {
     }
 }
 
-void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
-	byte td[4];
-	memcpy(td, data, 4);
+void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
+	uint16 &rthing = _states.at(x, y);
 
-	uint16 &rthing = _states.at(pos, id);
-
-	uint8 oid = td[0];
+	uint8 oid = e.value;
 
-	if ((td[1] & 1) == 0) {
+	if ((e.flags & 1) == 0) {
 		if (oid == 0xfe) {
-			FUN_00402654(1, id, pos);
+			FUN_00402654(1, y, x);
 			if (_needReload)
 				return;
 
-			rthing = (td[1] << 8) | td[0];
+			rthing = (e.t << 12) | (e.flags << 8) | e.value;
 			return;
 		}
 	} else {
 		Unknown1 &unk1 = _thing2[ oid ];
 		uint8 index = rndRange16( unk1.field_1[0] );
 		if (!unk1.field_2.empty()) {
-			byte id1 = td[1];
-			td[1] = unk1.field_2[ unk1.field_1[ index + 1 ] ];
-			preprocessData(8 + (id1 >> 4), td);
+			byte id1 = e.t;
+			e.t = unk1.field_2[ unk1.field_1[ index + 1 ] ] >> 4;
+			preprocessData(8 + e.t, &e);
 		}
 	}
 
-	preprocessDataB1(td[1] >> 4, td);
-	rnd(); // needed?
+	preprocessDataB1(e.t, &e);
 
-	td[0] = oid;
+	e.flags = 0;
+
+	rnd(); // needed?
 
 	Object *obj = nullptr;
 	int index = 0;
 	byte *odat = nullptr;
 
-	SomeAction &act = _someActsArr[oid];
+	ObjectAction &act = _objectActions[oid];
 	if ((act.unk1 & 0xff) == 0) {
-		FUN_00402654(1, id, pos);
+		FUN_00402654(1, y, x);
 		if (_needReload)
 			return;
 		obj = nullptr;
 		index = -1;
 		odat = nullptr;
 	} else {
-		FUN_00402654(0, id, pos);
+		FUN_00402654(0, y, x);
 		if (_needReload)
 			return;
 		obj = getFreeObject();
-		obj->flags = (td[1] & 0xf0) | 3;
+		obj->flags = (e.t << 4) | 3;
 		obj->actID = oid;
 		obj->fld_4 = 0;
 		obj->fld_5 = (act.unk1 >> 16) & 0xff;
-		obj->pos = pos;
-		obj->blk = id;
+		obj->pos = x;
+		obj->blk = y;
 		obj->x = -1;
 		obj->y = -1;
 		obj->fld_2 = rthing & 0xff;
@@ -1537,13 +1474,13 @@ void GamosEngine::FUN_0040283c(int id, int pos, const byte *data) {
 			PTR_004121b4 = obj;
 	}
 
-	rthing = (td[1] << 8) | td[0];
-	executeScript(td[1], id, pos, odat, index, obj, &act, act.script1);
+	rthing = (e.t << 12) | (e.flags << 8) | e.value;
+	executeScript(e.t << 4, y, x, odat, index, obj, &act, act.onCreateAddress);
 }
 
 void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
 	if (id != -1)
-		removeObjectMarkDirty(&_drawElements[id]);
+		removeObjectMarkDirty(&_objects[id]);
 }
 
 
@@ -1555,12 +1492,12 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	if (actid == 0xfe)
 		return;
 
-	SomeAction &act = _someActsArr[actid];
+	ObjectAction &act = _objectActions[actid];
 	Object *povar4 = nullptr;
 	bool multidel = false;
 
-	for(uint i = 0; i < _drawElements.size(); i++) {
-		Object &obj = _drawElements[i];
+	for(uint i = 0; i < _objects.size(); i++) {
+		Object &obj = _objects[i];
 		if (obj.flags & 1) {
 			if (obj.flags & 2) {
 				if (obj.pos == pos && obj.blk == id) {
@@ -1569,7 +1506,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 						removeObjectByIDMarkDirty(obj.x);
 					/* if (obj.flags & 8)
 						obj.storage.clear(); */
-					FUN_004023d8(&obj);
+					removeSubtitles(&obj);
 					removeObject(&obj);
 					FUN_0040255c(&obj);
 					povar4 = &obj;
@@ -1595,36 +1532,54 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	if (povar4)
 		rthing = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
 
-	executeScript(rthing >> 8, id, pos, nullptr, -1, nullptr, &act, act.script2);
+	executeScript(rthing >> 8, id, pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
 }
 
 Object *GamosEngine::getFreeObject() {
-	for (uint i = 0; i < _drawElements.size(); i++) {
-		Object &rObj = _drawElements[i];
+	Object *obj = nullptr;
+	for (uint i = 0; i < _objects.size(); i++) {
+		Object &rObj = _objects[i];
 		if ( (rObj.flags & 1) == 0 ) {
-			rObj.flags = 1;
-			return &rObj;
+			obj = &rObj;
+			break;
 		}
 	}
 
-	_drawElements.emplace_back();
-	Object &rObj = _drawElements.back();
-	rObj.flags = 1;
-	rObj.index = _drawElements.size() - 1;
-	return &rObj;
+	if (!obj) {
+		_objects.emplace_back();
+		obj = &_objects.back();
+		obj->index = _objects.size() - 1;
+	}
+
+	obj->flags = 1;
+	obj->sprId = -1;
+	obj->seqId = -1;
+	obj->frame = -1;
+
+	obj->actID = 0;
+	obj->fld_2 = 0;
+	obj->fld_3 = 0;
+	obj->fld_4 = 0;
+	obj->fld_5 = 0;
+	obj->pos = 0xff;
+	obj->blk = 0xff;
+	obj->x = 0;
+	obj->y = 0;
+	obj->pImg = nullptr;
+	return obj;
 }
 
 void GamosEngine::removeObject(Object *obj) {
 	obj->flags = 0;
-	/*if (&(_drawElements.back()) == obj) {
-		int32 lastindex = _drawElements.size() - 1;
+	/*if (&(_objects.back()) == obj) {
+		int32 lastindex = _objects.size() - 1;
 		for (int32 i = lastindex - 1; i >= 0; i--) {
-			if ( _drawElements[i].flags & 1 ) {
+			if ( _objects[i].flags & 1 ) {
 				lastindex = i;
 				break;
 			}
 		}
-		_drawElements.resize(lastindex);
+		_objects.resize(lastindex);
 	}*/
 }
 
@@ -1635,7 +1590,7 @@ void GamosEngine::removeObjectMarkDirty(Object *obj) {
 }
 
 
-void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, SomeAction *act, int32 scriptAddr) {
+void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, ObjectAction *act, int32 scriptAddr) {
 	if (scriptAddr == -1)
 		return;
 
@@ -1647,7 +1602,7 @@ void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage,
 	int32 sv6 = DAT_00417220;
 	int32 sv7 = _curObjIndex;
 	Object *sv8 = PTR_00417218;
-	SomeAction *sv9 = PTR_00417214;
+	ObjectAction *sv9 = PTR_00417214;
 
 	BYTE_004177f6 = p1;
 	PTR_004173e8 = storage;
@@ -1674,15 +1629,15 @@ void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage,
 
 bool GamosEngine::FUN_00402fb4()
 {
-	if (_drawElements.empty())
+	if (_objects.empty())
 		return true;
 
 	Object *pobj = DAT_00412204;
 	if (!pobj)
-		pobj = &(_drawElements.front());
+		pobj = &(_objects.front());
 
-	for (int32 objIdx = pobj->index; objIdx < _drawElements.size(); objIdx++) {
-		pobj = &_drawElements[objIdx];
+	for (int32 objIdx = pobj->index; objIdx < _objects.size(); objIdx++) {
+		pobj = &_objects[objIdx];
 
 		if ((pobj->flags & 3) == 3) {
 			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7))) ) {
@@ -1690,10 +1645,10 @@ bool GamosEngine::FUN_00402fb4()
 					pobj->fld_3 &= ~1;
 				} else {
 					if ((pobj->flags & 4) == 0) {
-						if (pobj->y != -1 && FUN_00402f34(true, false, &_drawElements[pobj->y])) {
+						if (pobj->y != -1 && FUN_00402f34(true, false, &_objects[pobj->y])) {
 							pobj->y = pobj->x;
 							if (pobj->x != -1) {
-								Object &o = _drawElements[pobj->x];
+								Object &o = _objects[pobj->x];
 								o.flags |= 0x80;
 								o.fld_4 = pobj->pos;
 								o.fld_5 = pobj->blk;
@@ -1702,10 +1657,10 @@ bool GamosEngine::FUN_00402fb4()
 							}
 						}
 					} else {
-						if (FUN_00402f34(pobj->y != pobj->x, true, &_drawElements[pobj->y])) {
+						if (FUN_00402f34(pobj->y != pobj->x, true, &_objects[pobj->y])) {
 							pobj->y = pobj->x;
 							if (pobj->x != -1) {
-								Object &o = _drawElements[pobj->x];
+								Object &o = _objects[pobj->x];
 								o.flags |= 0x80;
 								o.fld_4 = pobj->pos;
 								o.fld_5 = pobj->blk;
@@ -1723,19 +1678,19 @@ bool GamosEngine::FUN_00402fb4()
 
 					PTR_00417218 = pobj;
 					_curObjIndex = pobj->index;
-					PTR_00417214 = &_someActsArr[pobj->actID];
+					PTR_00417214 = &_objectActions[pobj->actID];
 					PTR_004173e8 = pobj->storage.data();
 
 					DAT_00417804 = 0;
-					for ( ScriptS &scr: PTR_00417214->scriptS ) {
-						BYTE_004177f6 = PTR_00417218->flags & 0xf0;
+					for ( Actions &scr: PTR_00417214->actions ) {
+						BYTE_004177f6 = PTR_00417218->flags >> 4;
 
 						int ivr8 = 0;
-						if (BYTE_004177f6 == 0x20)
+						if (BYTE_004177f6 == 2)
 							ivr8 = 1;
-						else if (BYTE_004177f6 == 0x40)
+						else if (BYTE_004177f6 == 4)
 							ivr8 = 2;
-						else if (BYTE_004177f6 == 0x80)
+						else if (BYTE_004177f6 == 8)
 							ivr8 = 3;
 
 						bool tmp = false;
@@ -1748,7 +1703,7 @@ bool GamosEngine::FUN_00402fb4()
 
 								DAT_004177ff = false;
 								_preprocDataId = fncid;
-								int32 res = ProcessScript(false, scr.data.data(), scr.data.size(), scr.codes1, scr.codes2);
+								int32 res = doActions(scr, false);
 
 								if (_needReload)
 									return false;
@@ -1775,7 +1730,7 @@ bool GamosEngine::FUN_00402fb4()
 							}
 						}
 
-						if (scr.data[0] & 0x80) {
+						if (scr.flags & 0x80) {
 							if (tmp) {
 								DAT_00412204 = pobj;
 								goto exit;
@@ -1845,7 +1800,7 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 	int32 y = obj->fld_5 * _gridCellH;
 
 	if (obj->pos != 255 && obj->blk != 255) {
-		Object *o = &_drawElements[(obj->blk * 0x100) + obj->pos];
+		Object *o = &_objects[(obj->blk * 0x100) + obj->pos];
 		if (o->flags & 4) {
 			int t = obj->actID + 1;
 			x += (o->pos - obj->fld_4) * _gridCellW * t / obj->fld_2;
@@ -1947,8 +1902,8 @@ void GamosEngine::doDraw() {
 	Common::Array<Object *> drawList( 1024 );//_drawElements.size(), 1024) );
 
 	int cnt = 0;
-	for (int i = 0; i < _drawElements.size(); i++) {
-		Object &obj = _drawElements[i];
+	for (int i = 0; i < _objects.size(); i++) {
+		Object &obj = _objects[i];
 		if ((obj.flags & 0x83) == 0x81) {
 			drawList[cnt] = &obj;
 			cnt++;
@@ -2061,7 +2016,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		if (PTR_00417218->x == -1)
 			vm->EAX.val = 0;
 		else
-			vm->EAX.val = _drawElements[ PTR_00417218->x ].spr->index == arg1 ? 1 : 0;
+			vm->EAX.val = _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0;
 		break;
 	case 3:
 		//warning("func 3 %x check 0x10", PTR_00417218->fld_4 & 0x90);
@@ -2083,7 +2038,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		break;
 	case 9:
 		arg1 = vm->pop32();
-		vm->EAX.val = FUN_004070f8(_dat60[arg1].data(), _dat60[arg1].size());
+		vm->EAX.val = savedDoActions(_subtitleActions[arg1]);
 		break;
 	case 13: {
 		VM::Reg regRef = vm->popReg(); //implement
@@ -2118,17 +2073,17 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 
 	case 20: {
 		arg1 = vm->pop32();
-		for (const Dat61 &d : _dat61[arg1]) {
-			FUN_0040738c(d.v, d.x, d.y, true);
+		for (const SubtitlePoint &d : _subtitlePoints[arg1]) {
+			FUN_0040738c(d.sprId, d.x, d.y, true);
 		}
-		vm->EAX.val = FUN_004070f8(_dat60[arg1].data(), _dat60[arg1].size());
+		vm->EAX.val = savedDoActions(_subtitleActions[arg1]);
 	} break;
 
 	case 24: {
 		VM::Reg regRef = vm->popReg();
 		arg2 = vm->pop32();
-		const Dat61 &d = _dat61[arg2][0];
-		FUN_00407a68(vm, regRef.ref, regRef.val, d.v, d.x, d.y);
+		const SubtitlePoint &d = _subtitlePoints[arg2][0];
+		addSubtitles(vm, regRef.ref, regRef.val, d.sprId, d.x, d.y);
 
 		vm->EAX.val = 1;
 	} break;
@@ -2138,11 +2093,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		if (PTR_00417218->fld_5 != arg1) {
 			PTR_00417218->fld_5 = arg1;
 			if (PTR_00417218->x != -1) {
-				Object &obj = _drawElements[PTR_00417218->x];
+				Object &obj = _objects[PTR_00417218->x];
 				obj.fld_3 = arg1;
 			}
 			if (PTR_00417218->y != -1) {
-				Object &obj = _drawElements[PTR_00417218->y];
+				Object &obj = _objects[PTR_00417218->y];
 				obj.fld_3 = arg1;
 				addDirtRectOnObject(&obj);
 			}
@@ -2151,13 +2106,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	} break;
 
 	case 26:
-		FUN_004023d8(PTR_00417218);
+		removeSubtitles(PTR_00417218);
 		vm->EAX.val = 1;
 		break;
 
 	case 30: {
 		if (PTR_00417218->y != -1) {
-			Object *obj = &_drawElements[PTR_00417218->y];
+			Object *obj = &_objects[PTR_00417218->y];
 			PTR_00417218->x = -1;
 			PTR_00417218->y = -1;
 			removeObjectMarkDirty(obj);
@@ -2405,7 +2360,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 		} else {
 			int32 index = pobj->index;
 			if (PTR_00417218->y != -1) {
-				Object *oobj = &_drawElements[PTR_00417218->y];
+				Object *oobj = &_objects[PTR_00417218->y];
 				addDirtRectOnObject(oobj);
 				oobj->flags &= 0x7f;
 				if (PTR_00417218->x != PTR_00417218->y)
@@ -2415,7 +2370,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 			PTR_00417218->y = index;
 			if (!(pobj->flags & 4)) {
 				if (PTR_00417218->x != -1)
-					removeObject(&_drawElements[PTR_00417218->x]);
+					removeObject(&_objects[PTR_00417218->x]);
 				PTR_00417218->x = index;
 			}
 
@@ -2430,76 +2385,78 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 		pobj->fld_5 = 0xff;
 	}
 
-	FUN_00409378(&spr, pobj, p);
+	FUN_00409378(id, pobj, p);
 	return true;
 }
 
-void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
+void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 	obj->flags &= ~0x18;
 	obj->actID = 0;
-	obj->spr = spr;
+	obj->sprId = sprId;
 
-	if (spr->field_2 == 1) {
-		obj->pImg = &spr->sequences[0][0];
-		if (BYTE_004177f6 == 0x80) {
-			if (spr->field_1 & 2)
+	Sprite &spr = _sprites[sprId];
+
+	if (spr.field_2 == 1) {
+		obj->pImg = &spr.sequences[0][0];
+		if (BYTE_004177f6 == 8) {
+			if (spr.field_1 & 2)
 				obj->flags |= 8;
-		} else if (BYTE_004177f6 == 0x40 && (spr->field_1 & 4)) {
+		} else if (BYTE_004177f6 == 4 && (spr.field_1 & 4)) {
 			obj->flags |= 0x10;
 		}
 	} else {
 		int frm = 0;
-		if (BYTE_004177f6 == 0x10) {
+		if (BYTE_004177f6 == 1) {
 			frm = 1;
-			if (DAT_00417224 == DAT_0041722c && (spr->field_1 & 8))
+			if (DAT_00417224 == DAT_0041722c && (spr.field_1 & 8))
 				frm = 0;
-		} else if (BYTE_004177f6 == 0x20) {
+		} else if (BYTE_004177f6 == 2) {
 			frm = 3;
 			if (DAT_0041722c < DAT_00417224)
 				frm = 2;
 			else if (DAT_0041722c > DAT_00417224) {
 				frm = 4;
-				if (spr->field_1 & 4) {
+				if (spr.field_1 & 4) {
 					frm = 2;
 					obj->flags |= 0x10;
 				}
-			} else if (DAT_00417220 == DAT_00417228 && (spr->field_1 & 8))
+			} else if (DAT_00417220 == DAT_00417228 && (spr.field_1 & 8))
 				frm = 0;
-		} else if (BYTE_004177f6 == 0x40) {
+		} else if (BYTE_004177f6 == 4) {
 			frm = 5;
-			if (DAT_00417224 == DAT_0041722c && (spr->field_1 & 8))
+			if (DAT_00417224 == DAT_0041722c && (spr.field_1 & 8))
 				frm = 0;
-			else if (spr->field_1 & 4) {
+			else if (spr.field_1 & 4) {
 				frm = 1;
 				obj->flags |= 0x10;
 			}
 		} else {
 			frm = 7;
 			if (DAT_00417224 == DAT_0041722c) {
-				if ((spr->field_1 & 8) && DAT_00417220 == DAT_00417228)
+				if ((spr.field_1 & 8) && DAT_00417220 == DAT_00417228)
 					frm = 0;
-				else if (spr->field_1 & 2) {
+				else if (spr.field_1 & 2) {
 					frm = 3;
 					obj->flags |= 8;
 				}
 			} else {
 				if (DAT_0041722c < DAT_00417224) {
 					frm = 8;
-					if (spr->field_1 & 2) {
+					if (spr.field_1 & 2) {
 						frm = 2;
 						obj->flags |= 8;
 					}
 				} else {
 					frm = 6;
-					if (spr->field_1 & 4) {
+					if (spr.field_1 & 4) {
 						frm = 8;
 						obj->flags |= 0x10;
 
-						if (spr->field_1 & 2) {
+						if (spr.field_1 & 2) {
 							frm = 2;
 							obj->flags |= 8;
 						}
-					} else if (spr->field_1 & 2) {
+					} else if (spr.field_1 & 2) {
 						frm = 4;
 						obj->flags |= 8;
 					}
@@ -2507,7 +2464,7 @@ void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
 			}
 		}
 
-		obj->pImg = &spr->sequences[frm][0];
+		obj->pImg = &spr.sequences[frm][0];
 	}
 	if (!p) {
 		obj->fld_4 = DAT_00417228;
@@ -2522,21 +2479,20 @@ void GamosEngine::FUN_00409378(Sprite *spr, Object *obj, bool p) {
 
 void GamosEngine::FUN_004095a0(Object *obj) {
 	if (obj->y != -1) {
-		Object &yobj = _drawElements[obj->y];
-		Sprite *spr = yobj.spr; //getSprite
+		Object &yobj = _objects[obj->y];
 		addDirtRectOnObject(&yobj);
 		if (DAT_00417228 != DAT_00417220 || DAT_0041722c != DAT_00417224)
 			obj->flags |= 4;
-		FUN_00409378(spr, &yobj, false);
+		FUN_00409378(yobj.sprId, &yobj, false);
 	}
 }
 
-void GamosEngine::FUN_004023d8(Object *obj) {
+void GamosEngine::removeSubtitles(Object *obj) {
 	if (obj->fld_3 & 2) {
 		obj->fld_3 &= ~2;
-		int32 index = obj->index;
-		for (int index = obj->index; index < _drawElements.size(); index++) {
-			Object *pobj = &_drawElements[index];
+		//for (int index = obj->index; index < _objects.size(); index++) {
+		for (int index = 0; index < _objects.size(); index++) {
+			Object *pobj = &_objects[index];
 			if ((pobj->flags & 0xe3) == 0xe1 && ((pobj->blk << 8) | pobj->pos) == obj->index)
 				removeObjectMarkDirty(pobj);
 		}
@@ -2547,13 +2503,13 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 	if (obj == PTR_004121b4) {
 		PTR_004121b4 = nullptr;
 		int32 n = 0;
-		for (int32 i = 0; i < _drawElements.size(); i++) {
-			Object &robj = _drawElements[i];
+		for (int32 i = 0; i < _objects.size(); i++) {
+			Object &robj = _objects[i];
 
 			if (robj.index > obj->index)
 				n++;
 
-			if ( (robj.flags & 3) == 3 && (_someActsArr[robj.actID].unk1 & 0xff) == 3 ) {
+			if ( (robj.flags & 3) == 3 && (_objectActions[robj.actID].unk1 & 0xff) == 3 ) {
 				if (n) {
 					PTR_004121b4 = &robj;
 					break;
@@ -2567,12 +2523,12 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 
 void GamosEngine::setCursor(int id, bool dirtRect) {
 	if (_unk9 == 0) {
-		if (dirtRect && _cursorObject.spr)
+		if (dirtRect && _cursorObject.sprId != -1)
 			addDirtRectOnObject(&_cursorObject);
 
 		_mouseCursorImgId = id;
 
-		_cursorObject.spr = &_sprites[id];
+		_cursorObject.sprId = id;
 		_cursorObject.flags = 0xc1;
 		_cursorObject.fld_2 = _sprites[id].field_3; // max frames
 		_cursorObject.actID = 0; //frame
@@ -2593,7 +2549,7 @@ bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
 	if (obj->y == -1)
 		return false;
 
-	Object &robj = _drawElements[obj->y];
+	Object &robj = _objects[obj->y];
 	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
 		return true;
 	return false;
@@ -2620,10 +2576,10 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	uint8 actT = 0;
 	uint8 pobjF5 = 0xff;
 
-	for(int i = 0; i < _drawElements.size(); i++) {
-		Object &obj = _drawElements[i];
+	for(int i = 0; i < _objects.size(); i++) {
+		Object &obj = _objects[i];
 		if ((obj.flags & 3) == 3) {
-			SomeAction &action = _someActsArr[obj.actID];
+			ObjectAction &action = _objectActions[obj.actID];
 			uint8 tp = action.unk1 & 0xff;
 			if (tp == 1)
 				obj.fld_4 = tmpb;
@@ -2680,7 +2636,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 
 }
 
-uint32 GamosEngine::FUN_004070f8(const byte *data, size_t dataSize) {
+uint32 GamosEngine::savedDoActions(const Actions &a) {
 	uint8 sv1 = BYTE_004177fc;
 	uint8 sv2 = BYTE_004177f6;
 	byte *sv3 = PTR_004173e8;
@@ -2693,9 +2649,9 @@ uint32 GamosEngine::FUN_004070f8(const byte *data, size_t dataSize) {
 	int32 sv10 = DAT_00417220;
 	int sv11 = _curObjIndex;
 	Object *sv12 = PTR_00417218;
-	SomeAction *sv13 = PTR_00417214;
+	ObjectAction *sv13 = PTR_00417214;
 
-	uint32 res = ProcessScript(true, data, dataSize);
+	uint32 res = doActions(a, true);
 
 	BYTE_004177fc = sv1;
 	BYTE_004177f6 = sv2;
@@ -2714,8 +2670,8 @@ uint32 GamosEngine::FUN_004070f8(const byte *data, size_t dataSize) {
 	return res;
 }
 
-void GamosEngine::FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, int32 x, int32 y) {
-	FUN_004023d8(PTR_00417218);
+void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
+	removeSubtitles(PTR_00417218);
 	PTR_00417218->fld_3 |= 2;
 
 	while (true) {
@@ -2751,7 +2707,7 @@ void GamosEngine::FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, in
 						offset += 4;
 					}
 
-					warning("FUN_00407a68 unimplemented part");
+					warning("addSubtitles unimplemented part");
 
 					switch( flg & 7 ) {
 					case 0:
@@ -2775,13 +2731,13 @@ void GamosEngine::FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, in
 				}
 			}
 		} else {
-			FUN_00407588(ib, val, &x, y);
+			addSubtitleImage(ib, sprId, &x, y);
 		}
 	}
 
 }
 
-Object *GamosEngine::FUN_00407588(int32 seq, int32 spr, int32 *pX, int32 y) {
+Object *GamosEngine::addSubtitleImage(int32 frame, int32 spr, int32 *pX, int32 y) {
 	Object *obj = getFreeObject();
 	obj->flags |= 0xe0;
 	obj->actID = 0;
@@ -2793,8 +2749,10 @@ Object *GamosEngine::FUN_00407588(int32 seq, int32 spr, int32 *pX, int32 y) {
 	obj->blk = (_curObjIndex >> 8) & 0xff;
 	obj->x = *pX;
 	obj->y = y;
-	obj->spr = &_sprites[spr];
-	obj->pImg = &_sprites[spr].sequences[0][seq - _sprites[spr].field_1];
+	obj->sprId = spr;
+	obj->seqId = 0;
+	obj->frame = frame - _sprites[spr].field_1;
+	obj->pImg = &_sprites[spr].sequences[obj->seqId][obj->frame];
 
 	*pX += obj->pImg->image->surface.w - obj->pImg->xoffset;
 
@@ -3168,6 +3126,114 @@ byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
 	return ret;
 }
 
+void Actions::parse(const byte *data, size_t dataSize) {
+	Common::MemoryReadStream rstream(data, dataSize);
+
+	/* clean first */
+	act_2.clear();
+	act_10.clear();
+	act_10end[0].clear();
+	act_10end[1].clear();
+	act_10end[2].clear();
+
+	/* start parsing */
+	flags = rstream.readByte();
+
+	uint8 tmp = rstream.readByte();
+	act_4.value = 0;
+	act_4.flags = 0;
+	act_4.t = tmp >> 4;
+	act_4.x = rstream.readSByte();
+	act_4.y = rstream.readSByte();
+
+	num_act_10e = tmp & 0x3;
+
+	if (flags & HAS_CONDITION)
+		rstream.skip(4);
+
+	if (flags & HAS_ACT2) {
+		act_2.reserve(4);
+
+		while (true) {
+			act_2.emplace_back();
+			ActTypeEntry &entrie = act_2.back();
+
+			uint16 num = rstream.readUint16LE();
+			uint8 bits = rstream.readByte();
+
+			entrie.t = rstream.readByte();
+			entrie.entries.resize(num);
+
+			for (uint16 i = 0; i < num; i++) {
+				ActEntry &a = entrie.entries[i];
+				a.value = rstream.readByte();
+				tmp = rstream.readByte();
+				a.flags = tmp & 0xf;
+				a.t = tmp >> 4;
+				a.x = rstream.readSByte();
+				a.y = rstream.readSByte();
+			}
+
+			if (bits & 1)
+				break;
+		}
+	}
+
+	if (flags & HAS_FUNCTION)
+		rstream.skip(4);
+
+	if (flags & HAS_ACT10) {
+		act_10.reserve(4);
+
+		while (true) {
+			act_10.emplace_back();
+			ActTypeEntry &entrie = act_10.back();
+
+			uint16 num = rstream.readUint16LE();
+			uint8 f = rstream.readByte();
+
+			entrie.t = rstream.readByte();
+
+			if (entrie.t == 0) {
+				for (int j = 0; j < num_act_10e; j++) {
+					act_10end[j].resize(num);
+					for (uint16 i = 0; i < num; i++) {
+						ActEntry &a = act_10end[j][i];
+						a.value = rstream.readByte();
+						tmp = rstream.readByte();
+						a.flags = tmp & 0xf;
+						a.t = tmp >> 4;
+						a.x = rstream.readSByte();
+						a.y = rstream.readSByte();
+					}
+
+					if (num_act_10e - j > 1) {
+						num = rstream.readUint16LE();
+						rstream.skip(2);
+					}
+				}
+				break;
+			}
+
+			entrie.entries.resize(num);
+
+			for (uint16 i = 0; i < num; i++) {
+				ActEntry &a = entrie.entries[i];
+				a.value = rstream.readByte();
+				tmp = rstream.readByte();
+				a.flags = tmp & 0xf;
+				a.t = tmp >> 4;
+				a.x = rstream.readSByte();
+				a.y = rstream.readSByte();
+			}
+
+			if (f & 1)
+				break;
+		}
+	}
+}
+
+
 
 void GamosEngine::FUN_00404fcc(int32 id) {
 	warning("Not implemented FUN_00404fcc");
@@ -3189,35 +3255,35 @@ void GamosEngine::dumpActions() {
 	Common::String t = Common::String::format("actions_%d.txt", _currentModuleID);
 	FILE *f = fopen(t.c_str(), "wb");
 	int i = 0;
-	for (SomeAction &act : _someActsArr) {
+	for (ObjectAction &act : _objectActions) {
 		fprintf(f, "Act %d : %x\n", i, act.unk1);
-		if (act.script1 != -1) {
-			t = VM::disassembly(act.script1);
+		if (act.onCreateAddress != -1) {
+			t = VM::disassembly(act.onCreateAddress);
 			fprintf(f, "Script1 : \n");
 			fwrite(t.c_str(), t.size(), 1, f);
 			fprintf(f, "\n");
 		}
 
-		if (act.script2 != -1) {
-			t = VM::disassembly(act.script2);
+		if (act.onDeleteAddress != -1) {
+			t = VM::disassembly(act.onDeleteAddress);
 			fprintf(f, "Script2 : \n");
 			fwrite(t.c_str(), t.size(), 1, f);
 			fprintf(f, "\n");
 		}
 
 		int j = 0;
-		for (ScriptS &sc : act.scriptS) {
+		for (Actions &sc : act.actions) {
 			fprintf(f, "subscript %d : \n", j);
 
-			if (sc.codes1 != -1) {
-				t = VM::disassembly(sc.codes1);
+			if (sc.conditionAddress != -1) {
+				t = VM::disassembly(sc.conditionAddress);
 				fprintf(f, "condition : \n");
 				fwrite(t.c_str(), t.size(), 1, f);
 				fprintf(f, "\n");
 			}
 
-			if (sc.codes2 != -1) {
-				t = VM::disassembly(sc.codes2);
+			if (sc.functionAddress != -1) {
+				t = VM::disassembly(sc.functionAddress);
 				fprintf(f, "action : \n");
 				fwrite(t.c_str(), t.size(), 1, f);
 				fprintf(f, "\n");
@@ -3231,6 +3297,9 @@ void GamosEngine::dumpActions() {
 
 		i++;
 	}
+	fclose(f);
+
+	warning("Actions saved into actions_%d.txt", _currentModuleID);
 }
 
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 9cca3f638de..a3a449a337b 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -158,23 +158,58 @@ struct Unknown1 {
 	uint32 field_3;
 };
 
-struct ScriptS {
-	Common::Array<byte> data;
-	int32 codes1 = -1;
-	int32 codes2 = -1;
+struct ActEntry {
+	uint8 value = 0;
+	uint8 flags = 0;
+	uint8 t = 0;
+	int8 x = 0;
+	int8 y = 0;
+};
+
+struct ActTypeEntry {
+	uint8 t = 0;
+	Common::Array<ActEntry> entries;
 };
 
-struct SomeAction {
+struct Actions {
+	enum {
+		HAS_CONDITION = 1,
+		HAS_ACT2 = 2,
+		HAS_ACT4 = 4,
+		HAS_FUNCTION = 8,
+		HAS_ACT10 = 0x10
+	};
+
+	byte flags = 0;
+	byte num_act_10e = 0;
+
+	Common::Array<ActTypeEntry> act_2;
+
+	ActEntry act_4;
+
+	Common::Array<ActTypeEntry> act_10;
+
+	Common::Array<ActEntry> act_10end[3];
+
+	int32 conditionAddress = -1;
+	int32 functionAddress = -1;
+
+	void parse(const byte *data, size_t dataSize);
+};
+
+struct ObjectAction {
 	uint32 unk1;
-	int32 script1 = -1;
-	Common::Array< ScriptS > scriptS;
-	int32 script2 = -1;
+	int32 onCreateAddress = -1;
+	Common::Array< Actions > actions;
+	int32 onDeleteAddress = -1;
 };
 
 struct Object {
 	/* additional data */
 	int16 index = 0;
-	Sprite *spr = nullptr;
+	int32 sprId = -1;
+	int32 seqId = -1;
+	int32 frame = -1;
 
 	/* 80 - drawable
 	   40 -
@@ -198,10 +233,10 @@ struct Object {
 	Common::Array<byte> storage;
 };
 
-struct Dat61 {
+struct SubtitlePoint {
 	int16 x = 0;
 	int16 y = 0;
-	uint16 v = 0;
+	uint16 sprId = 0;
 };
 
 
@@ -263,8 +298,8 @@ private:
 
 	Common::Array< Common::Array<byte> > _soundSamples;
 
-	Common::Array< Common::Array<byte> > _dat60;
-	Common::Array< Common::Array<Dat61> > _dat61;
+	Common::Array< Actions > _subtitleActions;
+	Common::Array< Common::Array<SubtitlePoint> > _subtitlePoints;
 
 	uint32 _delayTime = 0;
 	uint32 _lastTimeStamp = 0;
@@ -322,15 +357,15 @@ private:
 	uint8 _preprocDataId = 0;
 
 	Common::Array<Unknown1> _thing2;
-	Common::Array<SomeAction> _someActsArr;
+	Common::Array<ObjectAction> _objectActions;
 
-	Pool<Object> _drawElements;
+	Pool<Object> _objects;
 
 	uint8 BYTE_00412200 = 0;
 
 	Object *DAT_00412204 = nullptr;
 
-	SomeAction *PTR_00417214 = nullptr;
+	ObjectAction *PTR_00417214 = nullptr;
 	Object *PTR_00417218 = nullptr;
 	Object *PTR_004121b4 = nullptr;
 
@@ -442,21 +477,22 @@ protected:
 
 	uint8 update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow);
 
-	int32 ProcessScript(bool p1, const byte *data, size_t dataSize, int32 code1 = -1, int32 code2 = -1);
+	int32 doActions(const Actions &a, bool absolute);
+	uint32 savedDoActions(const Actions &a);
 
 	void FUN_00404fcc(int32 id);
 
 	uint32 getU32(const void *ptr);
 
-	void preprocessData(int id, byte *data);
-	void preprocessDataB1(int id, byte *data);
-	int processData(int id, byte *data);
+	void preprocessData(int id, ActEntry *e);
+	void preprocessDataB1(int id, ActEntry *e);
+	int processData(ActEntry e, bool absolute);
 
-	void executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, SomeAction *act, int32 scriptAddr);
+	void executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, ObjectAction *act, int32 scriptAddr);
 
-	void FUN_00402a68(const byte *d);
+	void FUN_00402a68(ActEntry e);
 
-	void FUN_0040283c(int id, int pos, const byte *data);
+	void FUN_0040283c(ActEntry e, int32 x, int32 y);
 
 	void FUN_00402654(int mode, int id, int pos);
 
@@ -465,7 +501,7 @@ protected:
 	void removeObjectMarkDirty(Object *obj);
 	void removeObjectByIDMarkDirty(int32 id);
 
-	void FUN_004023d8(Object *obj);
+	void removeSubtitles(Object *obj);
 	void FUN_0040255c(Object *obj);
 
 	bool FUN_00402fb4();
@@ -487,7 +523,7 @@ protected:
 
 	bool FUN_0040738c(uint32 id, int32 x, int32 y, bool p);
 
-	void FUN_00409378(Sprite *spr, Object *obj, bool p);
+	void FUN_00409378(int32 sprId, Object *obj, bool p);
 
 	void FUN_004095a0(Object *obj);
 
@@ -498,16 +534,13 @@ protected:
 	void FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1);
 	bool FUN_00409600(Object *obj, Common::Point pos);
 
-	uint32 FUN_004070f8(const byte *data, size_t dataSize);
-
 	void setNeedReload() {
 		_needReload = true;
 		VM::_interrupt = true;
 	};
 
-	Object *FUN_00407588(int32 seq, int32 spr, int32 *pX, int32 y);
-
-	void FUN_00407a68(VM *vm, byte memtype, int32 offset, int32 val, int32 x, int32 y);
+	Object *addSubtitleImage(int32 seq, int32 spr, int32 *pX, int32 y);
+	void addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
 
 	void FUN_00407db8(uint8 p);
 	void FUN_00408648(uint8 p1, uint8 p2, uint8 p3);


Commit: c689017a8929ffdfb41f246232cf2d25b5a9f3ec
    https://github.com/scummvm/scummvm/commit/c689017a8929ffdfb41f246232cf2d25b5a9f3ec
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:30+01:00

Commit Message:
GAMOS: Fixes

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index befb019c8f2..165e63b5db3 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -950,6 +950,8 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	_needReload = false;
 	VM::_interrupt = false;
 
+	RawKeyCode = keyCode;
+
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
 
 	if ( FUN_00402bc4() ) {
@@ -1414,9 +1416,10 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 	} else {
 		Unknown1 &unk1 = _thing2[ oid ];
 		uint8 index = rndRange16( unk1.field_1[0] );
+		oid = unk1.field_1[ index + 1 ];
 		if (!unk1.field_2.empty()) {
 			byte id1 = e.t;
-			e.t = unk1.field_2[ unk1.field_1[ index + 1 ] ] >> 4;
+			e.t = unk1.field_2[ oid ] >> 4;
 			preprocessData(8 + e.t, &e);
 		}
 	}
@@ -3100,8 +3103,8 @@ byte GamosEngine::FUN_00407f70(uint8 p) {
 byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
 	uint8 ret = 0;
 
-	for (int32 y = 0; y < _pathBottom; y++) {
-		for (int32 x = 0; x < _pathRight; x++) {
+	for (int32 y = 0; y < _statesHeight; y++) {
+		for (int32 x = 0; x < _statesWidth; x++) {
 			uint8 &rval = _pathMap.at(x, y);
 			if ( rval == 0) {
 				if ( (x > 0 && _pathMap.at(x - 1, y) == cv) ||


Commit: 6a16720a5ff838171e6075424fc212c805cd2c26
    https://github.com/scummvm/scummvm/commit/6a16720a5ff838171e6075424fc212c805cd2c26
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:30+01:00

Commit Message:
GAMOS: Fix wrong value passed to state array if flags has bit 1

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 165e63b5db3..dcbb242a4db 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1477,8 +1477,8 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 			PTR_004121b4 = obj;
 	}
 
-	rthing = (e.t << 12) | (e.flags << 8) | e.value;
 	executeScript(e.t << 4, y, x, odat, index, obj, &act, act.onCreateAddress);
+	rthing = (e.t << 12) | (e.flags << 8) | oid;
 }
 
 void GamosEngine::removeObjectByIDMarkDirty(int32 id) {


Commit: 20c8864c01695cc5e12911f35c19d4cea2f83caf
    https://github.com/scummvm/scummvm/commit/20c8864c01695cc5e12911f35c19d4cea2f83caf
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:30+01:00

Commit Message:
GAMOS: Add runfile and version fields into detection

Changed paths:
    engines/gamos/detection.cpp
    engines/gamos/detection.h
    engines/gamos/detection_tables.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/metaengine.cpp
    engines/gamos/metaengine.h


diff --git a/engines/gamos/detection.cpp b/engines/gamos/detection.cpp
index 0d980a7b38a..192bc6ea7aa 100644
--- a/engines/gamos/detection.cpp
+++ b/engines/gamos/detection.cpp
@@ -29,17 +29,27 @@
 #include "gamos/detection.h"
 #include "gamos/detection_tables.h"
 
-const DebugChannelDef GamosMetaEngineDetection::debugFlagList[] = {
-	{ Gamos::kDebugGraphics, "Graphics", "Graphics debug level" },
-	{ Gamos::kDebugPath, "Path", "Pathfinding debug level" },
-	{ Gamos::kDebugFilePath, "FilePath", "File path debug level" },
-	{ Gamos::kDebugScan, "Scan", "Scan for unrecognised games" },
-	{ Gamos::kDebugScript, "Script", "Enable debug script dump" },
-	DEBUG_CHANNEL_END
+class GamosMetaEngineDetection : public AdvancedMetaEngineDetection<Gamos::GamosGameDescription> {
+
+public:
+	GamosMetaEngineDetection(): AdvancedMetaEngineDetection(
+		Gamos::gameDescriptions, Gamos::gamosGames) {
+	}
+	~GamosMetaEngineDetection() override {}
+
+	const char *getName() const override {
+		return "gamos";
+	}
+
+	const char *getEngineName() const override {
+		return "Gamos";
+	}
+
+	const char *getOriginalCopyright() const override {
+		return "Gamos (C)";
+	}
+
 };
 
-GamosMetaEngineDetection::GamosMetaEngineDetection() : AdvancedMetaEngineDetection(
-	Gamos::gameDescriptions, Gamos::gamosGames) {
-}
 
 REGISTER_PLUGIN_STATIC(GAMOS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, GamosMetaEngineDetection);
diff --git a/engines/gamos/detection.h b/engines/gamos/detection.h
index a6d47a122ff..667b671e3ce 100644
--- a/engines/gamos/detection.h
+++ b/engines/gamos/detection.h
@@ -26,44 +26,15 @@
 
 namespace Gamos {
 
-enum GamosDebugChannels {
-	kDebugGraphics = 1,
-	kDebugPath,
-	kDebugScan,
-	kDebugFilePath,
-	kDebugScript,
-};
-
-extern const PlainGameDescriptor gamosGames[];
-
-extern const ADGameDescription gameDescriptions[];
+struct GamosGameDescription {
+	AD_GAME_DESCRIPTION_HELPERS(desc);
 
-#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
+	ADGameDescription desc;
+	const char *runFile;
+	uint32 engineVersion;
+};
 
 } // End of namespace Gamos
 
-class GamosMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
-	static const DebugChannelDef debugFlagList[];
-
-public:
-	GamosMetaEngineDetection();
-	~GamosMetaEngineDetection() override {}
-
-	const char *getName() const override {
-		return "gamos";
-	}
-
-	const char *getEngineName() const override {
-		return "Gamos";
-	}
-
-	const char *getOriginalCopyright() const override {
-		return "Gamos (C)";
-	}
-
-	const DebugChannelDef *getDebugChannels() const override {
-		return debugFlagList;
-	}
-};
 
 #endif // GAMOS_DETECTION_H
diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 2b2b07df8c9..4243f2bfbab 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -29,35 +29,51 @@ const PlainGameDescriptor gamosGames[] = {
 	{ 0, 0 }
 };
 
-const ADGameDescription gameDescriptions[] = {
+const GamosGameDescription gameDescriptions[] = {
 	{
-		"solgamer",
-		0,
-		AD_ENTRY1s("solgamer.exe", "6049dd1645071da1b60cdd395e6999ba", 24658521),
-		Common::EN_ANY,
-		Common::kPlatformWindows,
-		ADGF_UNSTABLE,
-		GUIO1(GUIO_NONE)
+		{
+			"solgamer",
+			0,
+			AD_ENTRY1s("solgamer.exe", "6049dd1645071da1b60cdd395e6999ba", 24658521),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"solgamer.exe",
+		0x80000018
 	},
 	{
-		"pilots",
-		0,
-		AD_ENTRY1s("pilots.exe", "152f751d3c1b325e91411dd75de54e95", 48357155),
-		Common::EN_ANY,
-		Common::kPlatformWindows,
-		ADGF_UNSTABLE,
-		GUIO1(GUIO_NONE)
+		{
+			"pilots",
+			0,
+			AD_ENTRY1s("pilots.exe", "152f751d3c1b325e91411dd75de54e95", 48357155),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"pilots.exe",
+		0x80000016
 	},
 	{
-		"pilots2",
-		0,
-		AD_ENTRY1s("pilots2.exe", "a0353dfb46043d1b2d1ef8ab6c204b33", 582283983),
-		Common::EN_ANY,
-		Common::kPlatformWindows,
-		ADGF_UNSTABLE,
-		GUIO1(GUIO_NONE)
+		{
+			"pilots2",
+			0,
+			AD_ENTRY1s("pilots2.exe", "a0353dfb46043d1b2d1ef8ab6c204b33", 582283983),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"pilots2.exe",
+		0x80000018
 	},
-	AD_TABLE_END_MARKER
+	{
+		AD_TABLE_END_MARKER,
+		"",
+		0
+	}
 };
 
 } // End of namespace Gamos
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index dcbb242a4db..74525e78dfe 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -59,7 +59,7 @@ const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x8
 										 0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
 										 0x32, 0x57, 0xdd, 0xb2, 0x38, 0xa7, 0x95, 0x7a};
 
-GamosEngine::GamosEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
+GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
 	_gameDescription(gameDesc), _randomSource("Gamos") {
 	g_engine = this;
 }
@@ -69,11 +69,21 @@ GamosEngine::~GamosEngine() {
 }
 
 uint32 GamosEngine::getFeatures() const {
-	return _gameDescription->flags;
+	return _gameDescription->desc.flags;
 }
 
 Common::String GamosEngine::getGameId() const {
-	return _gameDescription->gameId;
+	return _gameDescription->desc.gameId;
+}
+
+Common::String GamosEngine::getRunFile() const {
+	return _gameDescription->runFile;
+}
+
+uint32 GamosEngine::getEngineVersion() const {
+	return _gameDescription->engineVersion;
+}
+
 }
 
 Common::Error GamosEngine::run() {
@@ -90,15 +100,8 @@ Common::Error GamosEngine::run() {
 
 	g_system->showMouse(true);
 
-	Common::String mname;
-	if (Common::String(_gameDescription->gameId) == Common::String("solgamer"))
-		mname = "solgamer.exe";
-	else if (Common::String(_gameDescription->gameId) == Common::String("pilots"))
-		mname = "pilots.exe";
-	else if (Common::String(_gameDescription->gameId) == Common::String("pilots2"))
-		mname = "pilots2.exe";
 
-	init(mname);
+	init(getRunFile());
 
 	Common::Event e;
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index a3a449a337b..3b7a5707463 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -244,7 +244,7 @@ class GamosEngine : public Engine {
 friend class MoviePlayer;
 
 private:
-	const ADGameDescription *_gameDescription;
+	const GamosGameDescription *_gameDescription;
 	Common::RandomSource _randomSource;
 
 	bool _errSet = false;
@@ -582,7 +582,7 @@ public:
 public:
 	Graphics::Screen *_screen = nullptr;
 public:
-	GamosEngine(OSystem *syst, const ADGameDescription *gameDesc);
+	GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc);
 	~GamosEngine() override;
 
 	uint32 getFeatures() const;
@@ -592,6 +592,10 @@ public:
 	 */
 	Common::String getGameId() const;
 
+	Common::String getRunFile() const;
+
+	uint32 getEngineVersion() const;
+
 	/**
 	 * Gets a random number
 	 */
diff --git a/engines/gamos/metaengine.cpp b/engines/gamos/metaengine.cpp
index 8768bc8e274..2e785232a41 100644
--- a/engines/gamos/metaengine.cpp
+++ b/engines/gamos/metaengine.cpp
@@ -25,34 +25,11 @@
 #include "gamos/detection.h"
 #include "gamos/gamos.h"
 
-namespace Gamos {
-
-static const ADExtraGuiOptionsMap optionsList[] = {
-	{
-		GAMEOPTION_ORIGINAL_SAVELOAD,
-		{
-			_s("Use original save/load screens"),
-			_s("Use the original save/load screens instead of the ScummVM ones"),
-			"original_menus",
-			false,
-			0,
-			0
-		}
-	},
-	AD_EXTRA_GUI_OPTIONS_TERMINATOR
-};
-
-} // End of namespace Gamos
-
 const char *GamosMetaEngine::getName() const {
 	return "gamos";
 }
 
-const ADExtraGuiOptionsMap *GamosMetaEngine::getAdvancedExtraGuiOptions() const {
-	return Gamos::optionsList;
-}
-
-Common::Error GamosMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+Common::Error GamosMetaEngine::createInstance(OSystem *syst, Engine **engine, const Gamos::GamosGameDescription *desc) const {
 	*engine = new Gamos::GamosEngine(syst, desc);
 	return Common::kNoError;
 }
diff --git a/engines/gamos/metaengine.h b/engines/gamos/metaengine.h
index c0ad7ad17a2..bdb19c957fb 100644
--- a/engines/gamos/metaengine.h
+++ b/engines/gamos/metaengine.h
@@ -23,12 +23,13 @@
 #define GAMOS_METAENGINE_H
 
 #include "engines/advancedDetector.h"
+#include "gamos/detection.h"
 
-class GamosMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
+class GamosMetaEngine : public AdvancedMetaEngine<Gamos::GamosGameDescription> {
 public:
 	const char *getName() const override;
 
-	Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+	Common::Error createInstance(OSystem *syst, Engine **engine, const Gamos::GamosGameDescription *desc) const override;
 
 	/**
 	 * Determine whether the engine supports the specified MetaEngine feature.
@@ -36,8 +37,6 @@ public:
 	 * Used by e.g. the launcher to determine whether to enable the Load button.
 	 */
 	bool hasFeature(MetaEngineFeature f) const override;
-
-	const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override;
 };
 
 #endif // GAMOS_METAENGINE_H


Commit: d6a6956f919e51f132eefebc9366bb1ac1af0e69
    https://github.com/scummvm/scummvm/commit/d6a6956f919e51f132eefebc9366bb1ac1af0e69
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:31+01:00

Commit Message:
GAMOS: Replace usage of g_system with _system

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 74525e78dfe..8db3721e853 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -98,19 +98,18 @@ Common::Error GamosEngine::run() {
 	if (saveSlot != -1)
 		(void)loadGameState(saveSlot);
 
-	g_system->showMouse(true);
-
+	_system->showMouse(true);
 
 	init(getRunFile());
 
 	Common::Event e;
 
 	while (!shouldQuit()) {
-		while (g_system->getEventManager()->pollEvent(e)) {
+		while (_system->getEventManager()->pollEvent(e)) {
 			_messageProc.processMessage(e);
 		}
 
-		uint32 curTime = g_system->getMillis();
+		uint32 curTime = _system->getMillis();
 		if (curTime > _lastTimeStamp + _delayTime) {
 			_lastTimeStamp = curTime;
 
@@ -596,7 +595,7 @@ bool GamosEngine::init(const Common::String &moduleName) {
 }
 
 bool GamosEngine::loadInitModule() {
-	rndSeed(g_system->getMillis());
+	rndSeed(_system->getMillis());
 	//DAT_0041723c = -1;
 	_curObjIndex = -1;
 	PTR_00417218 = nullptr;
@@ -897,7 +896,7 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 	const int16 maxDelay = (500 / 10) - 1;
 
 	for (int16 p = 0; p < 16; p++) {
-		uint32 val = g_system->getMillis();
+		uint32 val = _system->getMillis();
 		const Common::Point point = checkerCoords[p];
 		for (uint32 x = point.x; x < _width; x += 64) {
 			for (uint32 y = point.y; y < _height; y += 64) {
@@ -905,10 +904,10 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 			}
 		}
 		_screen->update();
-		val = g_system->getMillis() - val;
+		val = _system->getMillis() - val;
 
 		if (val > maxDelay)
-			g_system->delayMillis(maxDelay - val);
+			_system->delayMillis(maxDelay - val);
 	}
 }
 
@@ -2542,7 +2541,7 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 		_cursorObject.y = 0;
 		_cursorObject.pImg = &_sprites[id].sequences[0][0];
 
-		g_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(),
+		_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(),
 								 _cursorObject.pImg->image->surface.w,
 								 _cursorObject.pImg->image->surface.h,
 								 _cursorObject.pImg->xoffset,


Commit: 06cc8725a448a4e52a55612a30d57853487f4bac
    https://github.com/scummvm/scummvm/commit/06cc8725a448a4e52a55612a30d57853487f4bac
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:31+01:00

Commit Message:
GAMOS: Set _rawKeyCode with ascii because it's set with WM_CHAR in original game

Changed paths:
    engines/gamos/proc.cpp


diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index f1ba65038fa..a570988393b 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -33,6 +33,9 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 		_ascii = ev.kbd.ascii;
 
+		if (ev.kbd.ascii)
+			_rawKeyCode = ev.kbd.ascii;
+
 		winKey = KeyCodes::GetWinCode(ev.kbd.keycode);
 
 		if (winKey == _keyCodes[0])


Commit: 797ebc7edb40d344733e5e10bade4ef9f426f90e
    https://github.com/scummvm/scummvm/commit/797ebc7edb40d344733e5e10bade4ef9f426f90e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:31+01:00

Commit Message:
GAMOS: Change few indentations in file.cpp

Changed paths:
    engines/gamos/file.cpp


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index 1f50e489ae8..80c3d485722 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -138,7 +138,7 @@ bool Archive::readCompressedData(RawData *out) {
 
     if (t & 0x40) {
         /* small uncompressed data */
-    _lastReadSize = t & 0x1F;
+        _lastReadSize = t & 0x1F;
     } else {
         /* read size */
         const byte szsize = (t & 3) + 1;
@@ -150,7 +150,7 @@ bool Archive::readCompressedData(RawData *out) {
         /* is compressed */
         if (t & 0xC) {
             for (uint i = 0; i < szsize; ++i)
-            _lastReadDecompressedSize |= readByte() << (i << 3);
+                _lastReadDecompressedSize |= readByte() << (i << 3);
         }
     }
 


Commit: 5d403fb3cc55a3edafa2cf2fe8c2dbef9c2f1422
    https://github.com/scummvm/scummvm/commit/5d403fb3cc55a3edafa2cf2fe8c2dbef9c2f1422
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:32+01:00

Commit Message:
GAMOS: Implement usePalette method

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 8db3721e853..2c85413bcd7 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -911,6 +911,85 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 	}
 }
 
+bool GamosEngine::usePalette(byte *pal, int num, int fade, bool winColors) {
+
+	static const byte winColorMap[20][3] = {
+	/* r     g     b */
+	{ 0x00, 0x00, 0x00 },
+	{ 0x80, 0x00, 0x00 },
+	{ 0x00, 0x80, 0x00 },
+	{ 0x80, 0x80, 0x00 },
+	{ 0x00, 0x00, 0x80 },
+	{ 0x80, 0x00, 0x80 },
+	{ 0x00, 0x80, 0x80 },
+	{ 0xc0, 0xc0, 0xc0 },
+	{ 0xc0, 0xdc, 0xc0 },
+	{ 0xa6, 0xca, 0xf0 },
+
+	{ 0xff, 0xfb, 0xf0 },
+	{ 0xa0, 0xa0, 0xa4 },
+	{ 0x80, 0x80, 0x80 },
+	{ 0xff, 0x00, 0x00 },
+	{ 0x00, 0xff, 0x00 },
+	{ 0xff, 0xff, 0x00 },
+	{ 0x00, 0x00, 0xff },
+	{ 0xff, 0x00, 0xff },
+	{ 0x00, 0xff, 0xff },
+	{ 0xff, 0xff, 0xff } };
+
+	if (!pal)
+		return false;
+
+	if (_width != 0 && _height !=0) {
+		if (fade == 0) {
+			uint16 color = _screen->getPalette().findBestColor(0, 0, 0);
+			_screen->fillRect(_screen->getBounds(), color);
+			_screen->update();
+		} else {
+			uint16 color = 0;
+			if (fade == 2)
+				color = _screen->getPalette().findBestColor(0x80, 0x80, 0x80);
+			else if (fade == 3)
+				color = _screen->getPalette().findBestColor(0xc0, 0xc0, 0xc0);
+			else if (fade == 4)
+				color = _screen->getPalette().findBestColor(0xff, 0xff, 0xff);
+			else
+				color = _screen->getPalette().findBestColor(0, 0, 0);
+
+			/* 0.4sec */
+			const int16 maxDelay = (400 / 8) - 1;
+
+			for (int j = 0 ; j < 8; j++) {
+				uint32 val = _system->getMillis();
+
+				for (int i = j; i < _screen->w; i += 8)
+					_screen->drawLine(i, 0, i, _screen->h - 1, color);
+				for (int i = j; i < _screen->h; i += 8)
+					_screen->drawLine(0, i, _screen->w - 1, i, color);
+
+				_screen->update();
+				val = _system->getMillis() - val;
+
+				if (val < maxDelay)
+					_system->delayMillis(maxDelay - val);
+			}
+		}
+	}
+
+	Graphics::Palette newPal(256);
+	newPal.set(pal, 0, num);
+
+	if (winColors) {
+		newPal.set(winColorMap[0], 0, 10);
+		newPal.set(winColorMap[10], 246, 10);
+	}
+
+	newPal.resize(num, true);
+
+	_screen->setPalette(newPal);
+	return true;
+}
+
 
 void GamosEngine::readData2(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 3b7a5707463..201603f262f 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -516,6 +516,7 @@ protected:
 	void addDirtyRect(const Common::Rect &rect);
 
 	void doDraw();
+	bool usePalette(byte *pal, int num, int fade, bool winColors);
 
 	bool loadImage(Image *img);
 


Commit: 54ff252d869801571adac9c8fe070ef7cc8eeee8
    https://github.com/scummvm/scummvm/commit/54ff252d869801571adac9c8fe070ef7cc8eeee8
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:32+01:00

Commit Message:
GAMOS: Rename BkgImage structure to GameScreen, improve, update it's functionality for swapping between game screens

Changed paths:
  A engines/gamos/saveload.cpp
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/module.mk


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 2c85413bcd7..884affd63bf 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -229,6 +229,7 @@ bool GamosEngine::loadModule(uint id) {
 	_currentModuleID = id;
 	const byte targetDir = 2 + id;
 
+	_currentGameScreen = -1;
 	_readingBkgMainId = -1;
 
 	/* Complete me */
@@ -372,23 +373,19 @@ bool GamosEngine::loadModule(uint id) {
 	}
 
 	//FUN_00404a28();
-	if (BYTE_004177f7 == 0) {
-		// Reverse Here
+	if (BYTE_004177f7)
+		return true;
 
-		setCursor(0, false);
+	// Reverse Here
+	setCursor(0, false);
 
-		if (_readingBkgMainId == -1)
-			_screen->setPalette(_bkgImages[0].palette);
-			//FUN_00405ebc(0, false);
-		else
-			_screen->setPalette(_bkgImages[_readingBkgMainId].palette);
-			//FUN_00405ebc(0, false);
 
-		addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes ));
-	} else {
+	int bkg = _readingBkgMainId;
+	if (bkg == -1)
+		bkg = 0;
 
-	}
-	_screen->update();
+	if ( !switchToGameScreen(bkg, false) )
+		return false;
 
 	return true;
 }
@@ -430,7 +427,8 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 				warning("needs reload from loadResHandler, CANT HAPPEN!");
 
 			DAT_004177f8 = 0;
-			FUN_00404fcc(pid);
+
+			storeToGameScreen(pid);
 		}
 	} else if (tp == RESTP_20) {
 		if (dataSize != 4)
@@ -657,8 +655,8 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_pathMap.clear();
 	_pathMap.resize(_statesWidth, _statesHeight);
 
-	_bkgImages.clear();
-	_bkgImages.resize(bkgnum1 * bkgnum2);
+	_gameScreens.clear();
+	_gameScreens.resize(bkgnum1 * bkgnum2);
 
 	_sprites.clear();
 	_sprites.resize(imageCount);
@@ -794,14 +792,14 @@ bool GamosEngine::loadRes52(int32 id, const byte *data, size_t dataSize) {
 }
 
 bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
-	BkgImage &bimg = _bkgImages[id];
+	GameScreen &bimg = _gameScreens[id];
 	bimg.loaded = true;
 	bimg.offset = _readingBkgOffset;
-	bimg.field2_0x8 = 0;
-	bimg.field3_0xc = 0;
+	bimg._savedStates.clear();
+	bimg._savedObjects.clear();
 	bimg.palette = nullptr;
 
-	bimg.rawData.assign(data, data + dataSize);
+	bimg._bkgImageData.assign(data, data + dataSize);
 
 	Common::MemoryReadStream strm(data, dataSize);
 
@@ -812,17 +810,17 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 
 	strm.seek(8);
 
-	bimg.surface.pitch = bimg.surface.w = strm.readUint32LE();
-	bimg.surface.h = strm.readUint32LE();
+	bimg._bkgImage.pitch = bimg._bkgImage.w = strm.readUint32LE();
+	bimg._bkgImage.h = strm.readUint32LE();
 
 	uint32 imgsize = strm.readUint32LE();
 
 	//printf("res 18 id %d 14: %x\n", id, strm.readUint32LE());
 
-	bimg.surface.setPixels(bimg.rawData.data() + 0x18);
-	bimg.surface.format = Graphics::PixelFormat::createFormatCLUT8();
+	bimg._bkgImage.setPixels(bimg._bkgImageData.data() + 0x18);
+	bimg._bkgImage.format = Graphics::PixelFormat::createFormatCLUT8();
 
-	bimg.palette = bimg.rawData.data() + 0x18 + imgsize;
+	bimg.palette = bimg._bkgImageData.data() + 0x18 + imgsize;
 
 	return true;
 }
@@ -836,10 +834,6 @@ bool GamosEngine::playIntro() {
 
 bool GamosEngine::playMovie(int id) {
 	bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
-	if (_readingBkgMainId == -1)
-		_screen->setPalette(_bkgImages[0].palette);
-	else
-		_screen->setPalette(_bkgImages[_readingBkgMainId].palette);
 	return res;
 }
 
@@ -990,6 +984,21 @@ bool GamosEngine::usePalette(byte *pal, int num, int fade, bool winColors) {
 	return true;
 }
 
+bool GamosEngine::setPaletteCurrentGS() {
+	_currentFade = _fadeEffectID;
+
+	int curGS = _currentGameScreen;
+	if (curGS == -1)
+		curGS = 0;
+
+	if (!usePalette(_gameScreens[curGS].palette, 256, _currentFade, true) )
+		return false;
+
+	addDirtyRect(Common::Rect(_bkgUpdateSizes.x, _bkgUpdateSizes.y));
+
+	return true;
+}
+
 
 void GamosEngine::readData2(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
@@ -1976,10 +1985,12 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 }
 
 void GamosEngine::doDraw() {
-	if (_dirtyRects.empty())
+	if (_dirtyRects.empty()) {
+		_screen->update();
 		return;
+	}
 
-	int32 bkg = _readingBkgMainId;
+	int32 bkg = _currentGameScreen;
 	if (bkg == -1)
 		bkg = 0;
 
@@ -2019,10 +2030,12 @@ void GamosEngine::doDraw() {
 	for (int i = 0; i < _dirtyRects.size(); i++) {
 		Common::Rect &r = _dirtyRects[i];
 
-		if (_bkgImages[bkg].loaded) {
-			_screen->blitFrom(_bkgImages[bkg].surface, r, r);
+		if (_gameScreens[bkg].loaded) {
+			_screen->blitFrom(_gameScreens[bkg]._bkgImage, r, r);
 		}
-		_screen->addDirtyRect(r);
+
+		if (!_currentFade)
+			_screen->addDirtyRect(r);
 	}
 
 	for(Object *o: drawList) {
@@ -2045,6 +2058,13 @@ void GamosEngine::doDraw() {
 		}
 	}
 
+	if (_currentFade)
+		updateScreen(true, Common::Rect(_bkgUpdateSizes.x, _bkgUpdateSizes.y));
+
+	_currentFade = 0;
+
+	_dirtyRects.clear();
+
 	_screen->update();
 }
 
@@ -3318,11 +3338,6 @@ void Actions::parse(const byte *data, size_t dataSize) {
 }
 
 
-
-void GamosEngine::FUN_00404fcc(int32 id) {
-	warning("Not implemented FUN_00404fcc");
-}
-
 bool GamosEngine::FUN_004033a8(Common::Point mouseMove) {
 	_cursorObject.x = mouseMove.x;
 	_cursorObject.y = mouseMove.y;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 201603f262f..5a60b3a6e9d 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -103,18 +103,6 @@ enum RESTYPE {
 	RESTP_XORSEQ2 = 0x7e,
 };
 
-struct BkgImage {
-	bool loaded = false;
-	uint32 offset = 0;
-	Graphics::Surface surface;
-	byte *palette = nullptr;
-
-	uint32 field2_0x8 = 0;
-	uint32 field3_0xc = 0;
-
-	RawData rawData;
-};
-
 struct Image {
 	bool loaded = false;
 	int32 offset = -1;
@@ -239,6 +227,17 @@ struct SubtitlePoint {
 	uint16 sprId = 0;
 };
 
+struct GameScreen {
+	bool loaded = false;
+	uint32 offset = 0;
+	Graphics::Surface _bkgImage;
+	byte *palette = nullptr;
+
+	Array2D<uint16> _savedStates;
+	Common::Array<Object> _savedObjects;
+
+	RawData _bkgImageData;
+};
 
 class GamosEngine : public Engine {
 friend class MoviePlayer;
@@ -273,9 +272,11 @@ private:
 	byte _fps;
 	byte _unk8;
 	byte _unk9;
-	byte _fadeEffectID;
+	byte _fadeEffectID = 0;
 	byte _unk11;
 
+	byte _currentFade = 0;
+
 	int _isMoviePlay = 0;
 
 	bool _onlyScanImage = false;
@@ -290,7 +291,7 @@ private:
 
 	Common::Point _bkgUpdateSizes;
 
-	Common::Array<BkgImage> _bkgImages;
+	Common::Array<GameScreen> _gameScreens;
 
 	Common::Array<Sprite> _sprites;
 
@@ -336,6 +337,7 @@ private:
 
 	uint32 _readingBkgOffset = 0;
 	int32 _readingBkgMainId = -1;
+	int32 _currentGameScreen = -1;
 	int32 _loadedDataSize = -1;
 
 	uint32 _addrBlk12 = 0;
@@ -480,8 +482,6 @@ protected:
 	int32 doActions(const Actions &a, bool absolute);
 	uint32 savedDoActions(const Actions &a);
 
-	void FUN_00404fcc(int32 id);
-
 	uint32 getU32(const void *ptr);
 
 	void preprocessData(int id, ActEntry *e);
@@ -517,6 +517,7 @@ protected:
 
 	void doDraw();
 	bool usePalette(byte *pal, int num, int fade, bool winColors);
+	bool setPaletteCurrentGS();
 
 	bool loadImage(Image *img);
 
@@ -555,6 +556,11 @@ protected:
 	byte FUN_004081b8(uint8 cv, uint8 sv);
 
 
+	void storeToGameScreen(int id);
+	bool switchToGameScreen(int id, bool doNotStore);
+
+
+
 	void vmCallDispatcher(VM *vm, uint32 funcID);
 
 
diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
index d763707cab8..12d61e3e61e 100644
--- a/engines/gamos/module.mk
+++ b/engines/gamos/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS = \
 	music.o \
 	proc.o \
 	movie.o \
+	saveload.o \
 	vm.o
 
 # This module can be built as a plugin
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
new file mode 100644
index 00000000000..b57d51c8282
--- /dev/null
+++ b/engines/gamos/saveload.cpp
@@ -0,0 +1,121 @@
+/* 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 "gamos/gamos.h"
+
+namespace Gamos {
+
+void GamosEngine::storeToGameScreen(int id) {
+    GameScreen &gs = _gameScreens[id];
+    gs._savedObjects.clear();
+
+    gs._savedStates = _states;
+
+    int objCount = 0;
+    for (int i = 0; i < _objects.size(); i++) {
+        const Object &obj = _objects[i];
+        if ((obj.flags & 3) == 3 || (obj.flags & 7) == 1)
+            objCount++;
+    }
+
+    int idx = 0;
+    gs._savedObjects.resize(objCount);
+    for (int i = 0; i < _objects.size(); i++) {
+        Object &obj = _objects[i];
+
+        if ( (obj.flags & 3) == 3 ) {
+            const int refObjIdx = idx;
+            if (obj.x == -1) {
+                gs._savedObjects[idx] = obj;
+                gs._savedObjects[idx].index = idx;
+                obj.flags = 0;
+                idx++;
+            } else {
+                Object &drawObj = _objects[ obj.x ];
+                gs._savedObjects[idx] = obj;
+                gs._savedObjects[idx].index = idx;
+                gs._savedObjects[idx].x = idx + 1;
+                gs._savedObjects[idx].y = idx + 1;
+                gs._savedObjects[idx + 1] = drawObj;
+                gs._savedObjects[idx + 1].index = idx + 1;
+                gs._savedObjects[idx + 1].pos = idx & 0xff;
+                gs._savedObjects[idx + 1].blk = (idx >> 8) & 0xff;
+                obj.flags = 0;
+                drawObj.flags = 0;
+                idx += 2;
+            }
+
+            for (int j = 0; j < _objects.size(); j++) {
+                Object &lobj = _objects[ j ];
+                if ((lobj.flags & 7) == 1 && ((lobj.blk << 8) | lobj.pos) == obj.index) {
+                    gs._savedObjects[idx] = lobj;
+                    gs._savedObjects[idx].index = idx;
+                    gs._savedObjects[idx].pos = refObjIdx & 0xff;
+                    gs._savedObjects[idx].blk = (refObjIdx >> 8) & 0xff;
+                    lobj.flags = 0;
+                    idx++;
+                }
+            }
+        } else if ( (obj.flags & 7) == 1 && obj.pos == 0xff && obj.blk == 0xff ) {
+            gs._savedObjects[idx] = obj;
+            gs._savedObjects[idx].index = idx;
+            obj.flags = 0;
+            idx++;
+        }
+    }
+
+    _objects.clear();
+}
+
+
+bool GamosEngine::switchToGameScreen(int id, bool doNotStore) {
+    if (_currentGameScreen != -1 && doNotStore == false)
+        storeToGameScreen(_currentGameScreen);
+
+    _currentGameScreen = id;
+    GameScreen &gs = _gameScreens[id];
+
+    addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes ));
+
+    _states = gs._savedStates;
+
+    for(const Object &obj : gs._savedObjects) {
+        Object *nobj = getFreeObject();
+        if (nobj->index != obj.index) {
+            warning("Error!  nobj->index != obj.index");
+            return false;
+        }
+
+        *nobj = obj;
+    }
+
+    gs._savedObjects.clear();
+    gs._savedStates.clear();
+
+    flushDirtyRects(false);
+
+    if (doNotStore == false && !setPaletteCurrentGS())
+        return false;
+
+    return true;
+}
+
+}


Commit: 6853d0c0dabf6dc09e52c42adb491bd632b3e5c9
    https://github.com/scummvm/scummvm/commit/6853d0c0dabf6dc09e52c42adb491bd632b3e5c9
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:32+01:00

Commit Message:
GAMOS: Make internal movie player use new implemented functions for use and restore palette and flush dirty rects

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/movie.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 884affd63bf..66f1744a932 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -905,6 +905,25 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 	}
 }
 
+void GamosEngine::flushDirtyRects(bool apply) {
+	if (apply) {
+		for(const Common::Rect &r : _dirtyRects) {
+			updateScreen(false, r);
+		}
+	}
+	_dirtyRects.clear();
+
+	_screen->update();
+
+	DAT_004177fd = 0xff;
+	DAT_004177fe = ACT_NONE;
+	PTR_00417388 = nullptr;
+
+	rndSeed(_system->getMillis());
+	PTR_004121b4 = nullptr;
+	FUN_0040255c(nullptr);
+}
+
 bool GamosEngine::usePalette(byte *pal, int num, int fade, bool winColors) {
 
 	static const byte winColorMap[20][3] = {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 5a60b3a6e9d..8593fe420f6 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -516,6 +516,8 @@ protected:
 	void addDirtyRect(const Common::Rect &rect);
 
 	void doDraw();
+	void flushDirtyRects(bool apply);
+
 	bool usePalette(byte *pal, int num, int fade, bool winColors);
 	bool setPaletteCurrentGS();
 
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 536bfd6c0fd..cdcc4fef81d 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -63,6 +63,8 @@ bool MoviePlayer::deinit() {
     _gamos->stopMidi();
     _gamos->stopMCI();
 
+    _gamos->setPaletteCurrentGS();
+
     _file = nullptr;
     return true;
 }
@@ -295,9 +297,8 @@ int MoviePlayer::processImageChunk() {
 
     }
 
-    if (_doUpdateScreen) {
-        //FUN_00403c70(true);
-    }
+    if (_doUpdateScreen)
+        _gamos->flushDirtyRects(true);
 
     uint32 tstamp = 0;
     uint8 act = processMessages(keepAct, &tstamp);
@@ -357,8 +358,8 @@ int MoviePlayer::processPaletteChunk() {
     if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
         return 0;
 
-    _screen->setPalette(_paletteBuffer.data());
-    //g_system->getPaletteManager()->setPalette(PalColors.data(), 0, 256);
+    if (!_gamos->usePalette(_paletteBuffer.data(), 256,  _gamos->_fadeEffectID, false))
+        return 0;
 
     return 1;
 }


Commit: 282aeac844017cb9247de85f8c88bb5c4e8d0f12
    https://github.com/scummvm/scummvm/commit/282aeac844017cb9247de85f8c88bb5c4e8d0f12
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:33+01:00

Commit Message:
GAMOS: Update screen between frames for smooth mouse draw.

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 66f1744a932..aa69c9e995f 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -105,6 +105,8 @@ Common::Error GamosEngine::run() {
 	Common::Event e;
 
 	while (!shouldQuit()) {
+		Common::Point prevMousePos = _messageProc._mouseReportedPos;
+
 		while (_system->getEventManager()->pollEvent(e)) {
 			_messageProc.processMessage(e);
 		}
@@ -130,6 +132,9 @@ Common::Error GamosEngine::run() {
 			_messageProc._rawKeyCode = ACT_NONE;
 
 			doDraw();
+		} else {
+			if (prevMousePos != _messageProc._mouseReportedPos)
+				_screen->update();
 		}
 
 		//if (_delayTime)


Commit: fad23b610ec0c839e40df7efa22b3286b65daf38
    https://github.com/scummvm/scummvm/commit/fad23b610ec0c839e40df7efa22b3286b65daf38
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:33+01:00

Commit Message:
GAMOS: fix wrong detection of compressed images

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index aa69c9e995f..de0df99d45b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -778,8 +778,13 @@ bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size
 		img->cSize = s.readSint32LE();
 	} else {
 		if (_sprites[id].field_1 & 0x80) {
-			img->offset = _arch._lastReadDataOffset;
-			img->cSize = _arch._lastReadSize;
+			if (_arch._lastReadDecompressedSize) {
+				img->offset = _arch._lastReadDataOffset;
+				img->cSize = _arch._lastReadSize;
+			} else {
+				img->offset = _arch._lastReadDataOffset;
+				img->cSize = 0;
+			}
 		} else {
 			img->loaded = true;
 			img->rawData.assign(data + 4, data + dataSize);


Commit: 682c97b313c0d8f6ff055a88cd53f0fac0ea2753
    https://github.com/scummvm/scummvm/commit/682c97b313c0d8f6ff055a88cd53f0fac0ea2753
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:34+01:00

Commit Message:
GAMOS: Fix checkers screen update

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index de0df99d45b..08d7ce7cdc5 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -882,7 +882,7 @@ void GamosEngine::setErrMessage(const Common::String &msg) {
 	_errSet = true;
 }
 
-void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
+void GamosEngine::updateScreen(bool checkers, const Common::Rect &rect) {
 	if (_width == 0 || _height == 0)
 		return;
 
@@ -891,13 +891,17 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 		return;
 	}
 
+	/* checkers update */
 	static const Common::Point checkerCoords[16] = {
 		{0, 0}, {16, 32}, {48, 16}, {16, 48},
 		{0, 32}, {32, 48}, {16, 16}, {48, 0},
 		{32, 32}, {0, 48}, {32, 16}, {16, 0},
 		{48, 32}, {32, 0}, {0, 16}, {48, 48}};
 
-	const int16 maxDelay = (500 / 10) - 1;
+	/* 0.4sec */
+	const int16 maxDelay = (400 / 16) - 1;
+
+	_screen->clearDirtyRects();
 
 	for (int16 p = 0; p < 16; p++) {
 		uint32 val = _system->getMillis();
@@ -910,7 +914,7 @@ void GamosEngine::updateScreen(bool checkers, Common::Rect rect) {
 		_screen->update();
 		val = _system->getMillis() - val;
 
-		if (val > maxDelay)
+		if (val < maxDelay)
 			_system->delayMillis(maxDelay - val);
 	}
 }
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 8593fe420f6..7a1a81ed3d2 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -473,7 +473,7 @@ protected:
 
 	void setErrMessage(const Common::String &msg);
 
-	void updateScreen(bool checkers, Common::Rect rect);
+	void updateScreen(bool checkers, const Common::Rect &rect);
 
 	void readData2(const RawData &data);
 


Commit: a56561e4ed2e413dcce611ad0b1ffd9263f66043
    https://github.com/scummvm/scummvm/commit/a56561e4ed2e413dcce611ad0b1ffd9263f66043
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:34+01:00

Commit Message:
GAMOS: Implement save-load state files used for gameplay progress

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 08d7ce7cdc5..e32250a6e82 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -140,6 +140,17 @@ Common::Error GamosEngine::run() {
 		//if (_delayTime)
 	}
 
+	stopSounds();
+	stopMidi();
+	stopMCI();
+
+	_d2_fld17 = 1;
+	_enableMidi = true;
+	_d2_fld14 = 1;
+	_d2_fld16 = 1;
+	_runReadDataMod = true;
+	writeStateFile();
+
 	return Common::kNoError;
 }
 
@@ -227,15 +238,27 @@ bool GamosEngine::loader2() {
 }
 
 bool GamosEngine::loadModule(uint id) {
-	if ( (!_runReadDataMod && !initOrLoadSave(_saveLoadID)) ||
+	if ( (!_runReadDataMod && !writeStateFile()) ||
 	     !_arch.seekDir(1) )
 		return false;
 
 	_currentModuleID = id;
 	const byte targetDir = 2 + id;
 
+	//DAT_004126e4 = 1;
 	_currentGameScreen = -1;
 	_readingBkgMainId = -1;
+	//DAT_004172f8 = 0;
+	//DAT_004126ec = 0;
+	//INT_004126e8 = 0;
+
+	_xorSeq[0].clear();
+	_xorSeq[1].clear();
+	_xorSeq[2].clear();
+
+	stopMidi();
+	stopMCI();
+	stopSounds();
 
 	/* Complete me */
 
@@ -384,6 +407,8 @@ bool GamosEngine::loadModule(uint id) {
 	// Reverse Here
 	setCursor(0, false);
 
+	if (!loadStateFile())
+		return false;
 
 	int bkg = _readingBkgMainId;
 	if (bkg == -1)
@@ -528,10 +553,6 @@ bool GamosEngine::reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3
 }
 
 
-bool GamosEngine::initOrLoadSave(int32) {
-	return false;
-}
-
 bool GamosEngine::initMainDatas() {
 	RawData rawdata;
 
@@ -541,6 +562,12 @@ bool GamosEngine::initMainDatas() {
 	Common::MemoryReadStream dataStream(rawdata.data(), rawdata.size(), DisposeAfterUse::NO);
 
 	_magic = dataStream.readUint32LE();
+
+	if (_magic != getEngineVersion()) {
+		error("InitMainData: Invalid engine version! get %x expecting %x", _magic, getEngineVersion());
+		return false;
+	}
+
 	_pages1kbCount = dataStream.readUint32LE();
 	_readBufSize = dataStream.readUint32LE();
 	_width = dataStream.readUint32LE();
@@ -701,8 +728,8 @@ void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
 	seq.resize(num);
 
 	for(uint i = 0; i < num; ++i) {
-		seq[i].len = dataStream.readUint32LE();
 		seq[i].pos = dataStream.readUint32LE();
+		seq[i].len = dataStream.readUint32LE();
 	}
 }
 
@@ -1035,24 +1062,79 @@ bool GamosEngine::setPaletteCurrentGS() {
 
 void GamosEngine::readData2(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
-	dataStream.seek(4); // FIX ME
-	_messageProc._gd2flags = dataStream.readByte(); //4
-	//5
-	//x14
-	dataStream.seek(0x14);
-	_d2_fld14 = dataStream.readByte(); // x14
-	_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
-	_d2_fld16 = dataStream.readByte(); // x16
-	_d2_fld17 = dataStream.readByte(); // x17
-	_d2_fld18 = dataStream.readByte(); // x18
-	//x19
-
-	dataStream.seek(0x38);
-	_midiTrack = dataStream.readUint32LE(); //0x38
-	_mouseCursorImgId = dataStream.readUint32LE(); //0x3c
-	//0x40
-	for (int i = 0; i < 12; i++) {
-		_messageProc._keyCodes[i] = dataStream.readByte();
+
+	printf("Game data size %d\n", data.size());
+
+	if (getEngineVersion() == 0x80000018) {
+		_stateExt = dataStream.readString(0, 4); // FIX ME
+		dataStream.seek(4);
+		_messageProc._gd2flags = dataStream.readByte(); //4
+		dataStream.seek(8);
+		_svModuleId = dataStream.readSint32LE(); // 8
+		_svGameScreen = dataStream.readSint32LE(); // c
+		_d2_fld10 = dataStream.readUint32LE(); // x10
+		_d2_fld14 = dataStream.readByte(); // x14
+		_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
+		_d2_fld16 = dataStream.readByte(); // x16
+		_d2_fld17 = dataStream.readByte(); // x17
+		_d2_fld18 = dataStream.readByte(); // x18
+		_d2_fld19 = dataStream.readByte(); // x19
+		_d2_outLeft = dataStream.readSint32LE(); // x1c
+		_d2_outTop = dataStream.readSint32LE(); // x20
+		_d2_index = dataStream.readSint16LE(); // x24
+		_d2_fld26 = dataStream.readSint16LE(); // x26
+		_d2_fld28 = dataStream.readSint16LE(); // x28
+		_d2_fld2a = dataStream.readSint16LE(); // x2a
+		_d2_fld2c = dataStream.readByte(); // x2c
+		_d2_fld2d = dataStream.readByte(); // x2d
+		_d2_fld2e = dataStream.readByte(); // x2e
+		_d2_fld2f = dataStream.readByte(); // x2f
+		_sndChannels = dataStream.readByte(); // x30
+		_sndVolume = dataStream.readByte(); // x34
+		_midiVolume = dataStream.readByte(); // x1a
+		_svFps = dataStream.readByte(); // x1b
+		_svFrame = dataStream.readSint32LE(); // x1c
+		_midiTrack = dataStream.readUint32LE(); //0x38
+		_mouseCursorImgId = dataStream.readUint32LE(); //0x3c
+		//0x40
+		for (int i = 0; i < 12; i++) {
+			_messageProc._keyCodes[i] = dataStream.readByte();
+		}
+	} else if (getEngineVersion() == 0x80000016) {
+		_stateExt = dataStream.readString(0, 4); // FIX ME
+		dataStream.seek(4);
+		_messageProc._gd2flags = dataStream.readByte(); //4
+		dataStream.seek(8);
+		_svModuleId = dataStream.readSint32LE();
+		_svGameScreen = dataStream.readSint32LE();
+		_d2_fld10 = dataStream.readUint32LE();
+		_d2_fld14 = dataStream.readByte(); // x14
+		_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
+		_d2_fld16 = dataStream.readByte(); // x16
+		_d2_fld17 = dataStream.readByte(); // x17
+		_d2_fld18 = 0;
+		_d2_fld19 = 0;
+		_d2_outLeft = 0;
+		_d2_outTop = 0;
+		_d2_index = -1;
+		_d2_fld26 = 16;
+		_d2_fld28 = 80;
+		_d2_fld2a = -1;
+		_d2_fld2c = 0;
+		_d2_fld2d = 0;
+		_d2_fld2e = 0;
+		_d2_fld2f = 0;
+		_sndChannels = dataStream.readByte(); // x18
+		_sndVolume = dataStream.readByte(); // x19
+		_midiVolume = dataStream.readByte(); // x1a
+		_svFps = dataStream.readByte(); // x1b
+		_svFrame = dataStream.readSint32LE(); // x1c
+		_midiTrack = dataStream.readUint32LE(); // x20
+		_mouseCursorImgId = dataStream.readUint32LE(); // x24
+		//0x28
+		for (int i = 0; i < 12; i++) {
+			_messageProc._keyCodes[i] = dataStream.readByte();
+		}
 	}
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 7a1a81ed3d2..f30f118c98c 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -256,7 +256,7 @@ private:
 	bool _runReadDataMod;
 	int _currentModuleID;
 
-	byte _saveLoadID;
+	byte _saveLoadID = 0;
 
 	uint32 _magic;
 	uint32 _pages1kbCount;
@@ -327,10 +327,31 @@ private:
 
 	/* Data2 */
 
+	Common::String _stateExt;
+
+	int32 _svModuleId = 0;
+	int32 _svGameScreen = 0;
+	uint32 _d2_fld10 = 0;
 	uint8 _d2_fld14 = 0;
 	uint8 _d2_fld16 = 0;
 	uint8 _d2_fld17 = 0;
 	uint8 _d2_fld18 = 0;
+	uint8 _d2_fld19 = 0;
+	int32 _d2_outLeft = 0;
+	int32 _d2_outTop = 0;
+	int32 _d2_index = 0;
+	int16 _d2_fld26 = 0;
+	int16 _d2_fld28 = 0;
+	int16 _d2_fld2a = 0;
+	uint8 _d2_fld2c = 0;
+	uint8 _d2_fld2d = 0;
+	uint8 _d2_fld2e = 0;
+	uint8 _d2_fld2f = 0;
+	uint8 _sndChannels = 0;
+	uint8 _sndVolume = 0;
+	uint8 _midiVolume = 0;
+	uint8 _svFps = 0;
+	uint32 _svFrame = 0;
 
 	bool _enableMidi = false;
 	int32 _midiTrack = 0;
@@ -434,8 +455,6 @@ protected:
 
 	bool reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3);
 
-	bool initOrLoadSave(int32);
-
 	bool initMainDatas();
 
 	bool init(const Common::String &moduleName);
@@ -558,10 +577,23 @@ protected:
 	byte FUN_004081b8(uint8 cv, uint8 sv);
 
 
+
+	/* save-load */
 	void storeToGameScreen(int id);
 	bool switchToGameScreen(int id, bool doNotStore);
 
+	Common::String makeSaveName(const Common::String &main, int id, const Common::String &ext) const;
+
+	void writeVMData(Common::SeekableWriteStream *stream, const Common::Array<XorArg> &seq);
+	void readVMData(Common::SeekableReadStream *stream, const Common::Array<XorArg> &seq);
+
+	bool writeStateFile();
+	void writeStateData(Common::SeekableWriteStream *stream);
+
+	void zeroVMData(const Common::Array<XorArg> &seq);
 
+	bool loadStateFile();
+	void loadStateData(Common::SeekableReadStream *stream);
 
 	void vmCallDispatcher(VM *vm, uint32 funcID);
 
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index b57d51c8282..39fa70ac789 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "gamos/gamos.h"
+#include "common/savefile.h"
 
 namespace Gamos {
 
@@ -118,4 +119,190 @@ bool GamosEngine::switchToGameScreen(int id, bool doNotStore) {
     return true;
 }
 
+Common::String GamosEngine::makeSaveName(const Common::String &main, int id, const Common::String &ext) const {
+    Common::String tmp = main;
+    tmp.toUppercase();
+    uint32 idx = tmp.find(".EXE");
+    if (idx != Common::String::npos)
+        tmp.erase(idx);
+    return Common::String::format("%s%d.%s", tmp.c_str(), id, ext.c_str());
+}
+
+
+bool GamosEngine::writeStateFile() {
+	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
+    Common::SaveFileManager *sm = _system->getSavefileManager();
+
+    if (!_runReadDataMod) {
+        if (sm->exists(fname)) {
+            Common::InSaveFile *rsv = sm->openForLoading(fname);
+            byte svdata[0x4c];
+            rsv->read(svdata, 0x4c);
+            delete rsv;
+
+            Common::OutSaveFile *osv = sm->openForSaving(fname);
+            osv->write(svdata, 0x4c);
+
+            writeVMData(osv, _xorSeq[0]);
+            writeVMData(osv, _xorSeq[1]);
+
+            osv->finalize();
+            delete osv;
+        }
+    } else {
+        _d2_fld10 = 0;
+        Common::OutSaveFile *osv = sm->openForSaving(fname);
+
+        writeStateData(osv);
+        writeVMData(osv, _xorSeq[0]);
+        writeVMData(osv, _xorSeq[1]);
+
+        osv->finalize();
+        delete osv;
+    }
+    return true;
+}
+
+bool GamosEngine::loadStateFile() {
+    Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
+    Common::SaveFileManager *sm = _system->getSavefileManager();
+
+    if (!_runReadDataMod) {
+        if (sm->exists(fname)) {
+            Common::SeekableReadStream *rs = sm->openForLoading(fname);
+            rs->seek(0x4c);
+            readVMData(rs, _xorSeq[0]);
+            readVMData(rs, _xorSeq[1]);
+        }
+    } else {
+        if (!sm->exists(fname))
+            writeStateFile();
+        else {
+            Common::SeekableReadStream *rs = sm->openForLoading(fname);
+
+            loadStateData(rs);
+            readVMData(rs, _xorSeq[0]);
+            readVMData(rs, _xorSeq[1]);
+
+            zeroVMData(_xorSeq[1]);
+
+            _runReadDataMod = false;
+
+            delete rs;
+        }
+    }
+    return true;
+}
+
+void GamosEngine::writeStateData(Common::SeekableWriteStream *stream) {
+    byte buf[4] = {0, 0, 0, 0};
+    memcpy(buf, _stateExt.c_str(), _stateExt.size() > 4 ? 4 : _stateExt.size());
+
+    stream->write(buf, 4); // 0
+    stream->writeByte(_messageProc._gd2flags);  // 4
+    stream->writeByte(0);  // 5
+    stream->writeByte(0);  // 6
+    stream->writeByte(0);  // 7
+    stream->writeSint32LE(_svModuleId); // 8
+	stream->writeSint32LE(_svGameScreen); // 0xc
+    stream->writeUint32LE(_d2_fld10); // 0x10
+    stream->writeByte(_d2_fld14); // 0x14
+    stream->writeByte(_enableMidi ? 1 : 0); // 0x15
+    stream->writeByte(_d2_fld16); // 0x16
+    stream->writeByte(_d2_fld17); // 0x17
+    stream->writeByte(_d2_fld18); // 0x18
+    stream->writeByte(_d2_fld19); // 0x19
+    stream->writeByte(0); // 0x1a
+    stream->writeByte(0); // 0x1b
+    stream->writeSint32LE(_d2_outLeft); // 0x1c
+    stream->writeSint32LE(_d2_outTop); // 0x20
+    stream->writeSint16LE(_d2_index); // 0x24
+    stream->writeSint16LE(_d2_fld26); // 0x26
+    stream->writeSint16LE(_d2_fld28); // 0x28
+    stream->writeSint16LE(_d2_fld2a); // 0x2a
+    stream->writeByte(_d2_fld2c); // 0x2c
+    stream->writeByte(_d2_fld2d); // 0x2d
+    stream->writeByte(_d2_fld2e); // 0x2e
+    stream->writeByte(_d2_fld2f); // 0x2f
+    stream->writeByte(_sndChannels); // 0x30
+    stream->writeByte(_sndVolume); // 0x31
+    stream->writeByte(_midiVolume); // 0x32
+    stream->writeByte(_svFps); // 0x33
+    stream->writeSint32LE(_svFrame); // 0x34
+    stream->writeUint32LE(_midiTrack); // 0x38
+    stream->writeUint32LE(_mouseCursorImgId); // 0x3c
+    // 0x40
+    for (int i = 0; i < 12; i++)
+        stream->writeByte(_messageProc._keyCodes[i]);
+}
+
+void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
+    _stateExt = dataStream->readString(0, 4); // FIX ME
+	dataStream->seek(4);
+    _messageProc._gd2flags = dataStream->readByte(); //4
+    dataStream->seek(8);
+    _svModuleId = dataStream->readSint32LE(); // 8
+    _svGameScreen = dataStream->readSint32LE(); // c
+    _d2_fld10 = dataStream->readUint32LE(); // x10
+    _d2_fld14 = dataStream->readByte(); // x14
+    _enableMidi = dataStream->readByte() != 0 ? true : false; //x15
+    _d2_fld16 = dataStream->readByte(); // x16
+    _d2_fld17 = dataStream->readByte(); // x17
+    _d2_fld18 = dataStream->readByte(); // x18
+    _d2_fld19 = dataStream->readByte(); // x19
+    dataStream->seek(0x1c);
+    _d2_outLeft = dataStream->readSint32LE(); // x1c
+    _d2_outTop = dataStream->readSint32LE(); // x20
+    _d2_index = dataStream->readSint16LE(); // x24
+    _d2_fld26 = dataStream->readSint16LE(); // x26
+    _d2_fld28 = dataStream->readSint16LE(); // x28
+    _d2_fld2a = dataStream->readSint16LE(); // x2a
+    _d2_fld2c = dataStream->readByte(); // x2c
+    _d2_fld2d = dataStream->readByte(); // x2d
+    _d2_fld2e = dataStream->readByte(); // x2e
+    _d2_fld2f = dataStream->readByte(); // x2f
+    _sndChannels = dataStream->readByte(); // x30
+    _sndVolume = dataStream->readByte(); // x34
+    _midiVolume = dataStream->readByte(); // x1a
+    _svFps = dataStream->readByte(); // x1b
+    _svFrame = dataStream->readSint32LE(); // x1c
+    _midiTrack = dataStream->readUint32LE(); //0x38
+    _mouseCursorImgId = dataStream->readUint32LE(); //0x3c
+
+    for (int i = 0; i < 12; i++)
+        _messageProc._keyCodes[i] = dataStream->readByte();
+}
+
+
+void GamosEngine::writeVMData(Common::SeekableWriteStream *stream, const Common::Array<XorArg> &seq) {
+    for (const XorArg &xarg : seq) {
+        Common::Array<byte> tmp = VM::readMemBlocks(xarg.pos, xarg.len);
+
+        //xor data in tmp
+        //...
+
+        // and write it
+        stream->write(tmp.data(), xarg.len);
+    }
+}
+
+void GamosEngine::readVMData(Common::SeekableReadStream *stream, const Common::Array<XorArg> &seq) {
+    Common::Array<byte> buf;
+    for (const XorArg &xarg : seq) {
+        if (buf.size() < xarg.len)
+            buf.resize(xarg.len);
+        stream->read(buf.data(), xarg.len);
+        //xor data in buf
+        //...
+
+        // and write it
+        VM::writeMemory(xarg.pos, buf.data(), xarg.len);
+    }
+}
+
+void GamosEngine::zeroVMData(const Common::Array<XorArg> &seq) {
+    for (const XorArg &xarg : seq)
+        VM::zeroMemory(xarg.pos, xarg.len);
+}
+
 }
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 97006d852fd..2dc5ab9352b 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -614,6 +614,28 @@ void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
     }
 }
 
+void VM::zeroMemory(uint32 address, uint32 count) {
+    uint32 blockAddr = address & (~0xff);
+    uint32 pos = 0;
+    uint32 remain = count;
+
+    for (uint32 addr = blockAddr; addr < address + count; addr += 0x100) {
+        MemoryBlock *block = findMemoryBlock(addr);
+
+        uint32 zeroCnt = (addr + 0x100) - (address + pos);
+        if (zeroCnt > remain)
+            zeroCnt = remain;
+
+        uint32 blockPos = (address + pos) - addr;
+
+        if (block)
+            memset(block->data + blockPos, 0, zeroCnt);
+
+        pos += zeroCnt;
+        remain -= zeroCnt;
+    }
+}
+
 VM::MemoryBlock *VM::findMemoryBlock(uint32 address) {
     Common::HashMap<uint32, MemoryBlock>::iterator it = _memMap.find(address & (~0xff));
     if (it == _memMap.end())
@@ -631,9 +653,14 @@ VM::MemoryBlock *VM::createBlock(uint32 address) {
 
 
 Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
-    Common::Array<byte> data;
-    data.resize(count);
+    Common::Array<byte> data(count);
+
+    readMemBlocks(data.data(), address, count);
 
+    return data;
+}
+
+void VM::readMemBlocks(byte *dst, uint32 address, uint32 count) {
     MemoryBlock *blk = findMemoryBlock(address);
 
     uint32 pos = 0;
@@ -641,13 +668,13 @@ Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
     uint32 remain = count;
     while(remain > 0) {
         uint32 dataCpyCount = (blockAddr + 0x100) - (address + pos);
-        if (dataCpyCount < remain)
+        if (dataCpyCount > remain)
             dataCpyCount = remain;
 
         if (!blk) {
-            memset(data.data() + pos, 0, dataCpyCount);
+            memset(dst + pos, 0, dataCpyCount);
         } else {
-            memcpy(data.data() + pos, blk->data + (address + pos - blk->address), dataCpyCount);
+            memcpy(dst + pos, blk->data + (address + pos - blk->address), dataCpyCount);
         }
 
         pos += dataCpyCount;
@@ -655,7 +682,6 @@ Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
         blockAddr += 0x100;
         blk = findMemoryBlock(blockAddr);
     }
-    return data;
 }
 
 Common::String VM::readMemString(uint32 address, uint32 maxLen) {
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index 1f7d7739f10..b5047875b8a 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -141,11 +141,14 @@ public:
     static void clearMemory();
     static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
 
+    static void zeroMemory(uint32 address, uint32 count);
+
     static MemoryBlock *findMemoryBlock(uint32 address);
 
     static MemoryBlock *createBlock(uint32 address);
 
     static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+    static void readMemBlocks(byte *dst, uint32 address, uint32 count);
 
     static Common::String readMemString(uint32 address, uint32 maxLen = 256);
 


Commit: 3f695b6cd8e7e5f092c6e13ace760d5a3960789d
    https://github.com/scummvm/scummvm/commit/3f695b6cd8e7e5f092c6e13ace760d5a3960789d
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:34+01:00

Commit Message:
GAMOS: Because in of games one of ImageSeq can be referenced multiple times load it into just array of pointers and reference it as pointer in Sprite structure

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index e32250a6e82..754bf02626b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -545,9 +545,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 
 bool GamosEngine::reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3) {
 	if (tp == RESTP_43) {
-		_sprites[pid].sequences[p1][p2].image = _images.back();
+		_sprites[pid].sequences[p1]->operator[](p2).image = _images.back();
+	} else if (tp == RESTP_42) {
+		_sprites[pid].sequences[p1] = _imgSeq.back();
 	} else {
-		return false;
+		error("Reuse of resource not implemented: resource type %x, id %d %d %d %d", tp, pid, p1, p2, p3);
 	}
 	return true;
 }
@@ -768,7 +770,8 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 		_sprites[id].sequences.resize(1);
 
 	int32 count = dataSize / 8;
-	_sprites[id].sequences[p1].resize(count);
+	_imgSeq.push_back( new ImageSeq(count) );
+	_sprites[id].sequences[p1] = _imgSeq.back();
 
 	Common::MemoryReadStream strm(data, dataSize);
 	for(int i = 0; i < count; ++i) {
@@ -778,7 +781,7 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 			exit(0);
 		}
 
-		ImagePos &imgpos = _sprites[id].sequences[p1][i];
+		ImagePos &imgpos = _sprites[id].sequences[p1]->operator[](i);
 		imgpos.xoffset = strm.readSint16LE();
 		imgpos.yoffset = strm.readSint16LE();
 	}
@@ -787,9 +790,9 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 
 bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize) {
 	_images.push_back( new Image() );
-	_sprites[id].sequences[p1][p2].image = _images.back();
+	_sprites[id].sequences[p1]->operator[](p2).image = _images.back();
 
-	Image *img = _sprites[id].sequences[p1][p2].image;
+	Image *img = _sprites[id].sequences[p1]->operator[](p2).image;
 
 	Common::MemoryReadStream s(data, dataSize);
 	img->surface.pitch = img->surface.w = s.readSint16LE();
@@ -1979,9 +1982,12 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 	} else {
 		addDirtRectOnObject(obj);
 		obj->actID++;
-		if (obj->actID == obj->fld_2) {
+		obj->frame++;
+
+		if (obj->frame == obj->fld_2) {
 			obj->actID = 0;
-			obj->pImg = obj->pImg - (obj->fld_2 - 1);
+			obj->frame = 0;
+			obj->pImg = &_sprites[obj->sprId].sequences[obj->seqId]->operator[](obj->frame);
 			if (p2 || (obj->flags & 4)) {
 				addDirtRectOnObject(obj);
 				if (p1)
@@ -1989,7 +1995,7 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 				return true;
 			}
 		} else {
-			obj->pImg++;
+			obj->pImg = &_sprites[obj->sprId].sequences[obj->seqId]->operator[](obj->frame);
 		}
 
 		if ((obj->flags & 0x40) == 0)
@@ -2010,7 +2016,7 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 	if (obj->pos != 255 && obj->blk != 255) {
 		Object *o = &_objects[(obj->blk * 0x100) + obj->pos];
 		if (o->flags & 4) {
-			int t = obj->actID + 1;
+			int t = obj->frame + 1;
 			x += (o->pos - obj->fld_4) * _gridCellW * t / obj->fld_2;
 			y += (o->blk - obj->fld_5) * _gridCellH * t / obj->fld_2;
 		}
@@ -2611,12 +2617,14 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 	obj->flags &= ~0x18;
 	obj->actID = 0;
+	obj->frame = 0;
 	obj->sprId = sprId;
 
 	Sprite &spr = _sprites[sprId];
 
 	if (spr.field_2 == 1) {
-		obj->pImg = &spr.sequences[0][0];
+		obj->seqId = 0;
+		obj->pImg = &spr.sequences[0]->operator[](0);
 		if (BYTE_004177f6 == 8) {
 			if (spr.field_1 & 2)
 				obj->flags |= 8;
@@ -2683,7 +2691,8 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 			}
 		}
 
-		obj->pImg = &spr.sequences[frm][0];
+		obj->pImg = &spr.sequences[frm]->operator[](0);
+		obj->seqId = frm;
 	}
 	if (!p) {
 		obj->fld_4 = DAT_00417228;
@@ -2748,12 +2757,15 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 		_mouseCursorImgId = id;
 
 		_cursorObject.sprId = id;
+		_cursorObject.frame = 0;
+		_cursorObject.seqId = 0;
+
 		_cursorObject.flags = 0xc1;
 		_cursorObject.fld_2 = _sprites[id].field_3; // max frames
 		_cursorObject.actID = 0; //frame
 		_cursorObject.x = 0;
 		_cursorObject.y = 0;
-		_cursorObject.pImg = &_sprites[id].sequences[0][0];
+		_cursorObject.pImg = &_sprites[id].sequences[0]->operator[](0);
 
 		_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(),
 								 _cursorObject.pImg->image->surface.w,
@@ -2971,7 +2983,7 @@ Object *GamosEngine::addSubtitleImage(int32 frame, int32 spr, int32 *pX, int32 y
 	obj->sprId = spr;
 	obj->seqId = 0;
 	obj->frame = frame - _sprites[spr].field_1;
-	obj->pImg = &_sprites[spr].sequences[obj->seqId][obj->frame];
+	obj->pImg = &_sprites[spr].sequences[obj->seqId]->operator[](obj->frame);
 
 	*pX += obj->pImg->image->surface.w - obj->pImg->xoffset;
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index f30f118c98c..de0fb84dffb 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -130,7 +130,7 @@ struct Sprite {
 	byte field_2;
 	byte field_3;
 
-	Common::Array<ImageSeq> sequences;
+	Common::Array<ImageSeq *> sequences;
 };
 
 /* Used to xor savedata */
@@ -288,6 +288,7 @@ private:
 	Common::Array<uint32> _movieOffsets;
 
 	Common::Array<Image *> _images;
+	Common::Array<ImageSeq *> _imgSeq;
 
 	Common::Point _bkgUpdateSizes;
 


Commit: ff7cee7ed49a9b217f4441e24e1c2b464075ad8e
    https://github.com/scummvm/scummvm/commit/ff7cee7ed49a9b217f4441e24e1c2b464075ad8e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:35+01:00

Commit Message:
GAMOS: Make Images and ImageSeq free on exit and on loading of a new "module"

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 754bf02626b..319f8cced96 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -65,6 +65,8 @@ GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) :
 }
 
 GamosEngine::~GamosEngine() {
+	freeImages();
+	freeSequences();
 	delete _screen;
 }
 
@@ -84,6 +86,18 @@ uint32 GamosEngine::getEngineVersion() const {
 	return _gameDescription->engineVersion;
 }
 
+void GamosEngine::freeImages() {
+	for (Image *img : _images)
+		delete img;
+
+	_images.clear();
+}
+
+void GamosEngine::freeSequences() {
+	for (ImageSeq *seq : _imgSeq)
+		delete seq;
+
+	_imgSeq.clear();
 }
 
 Common::Error GamosEngine::run() {
@@ -658,6 +672,9 @@ void GamosEngine::setFPS(uint fps) {
 void GamosEngine::readElementsConfig(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size(), DisposeAfterUse::NO);
 
+	freeImages();
+	freeSequences();
+
 	uint32 bkgnum1 = dataStream.readUint32LE(); // 0
 	uint32 bkgnum2 = dataStream.readUint32LE(); // 4
 	_statesWidth = dataStream.readUint32LE(); // 8
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index de0fb84dffb..9af1f3f3602 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -476,6 +476,9 @@ protected:
 
 	bool loadRes18(int32 id, const byte *data, size_t dataSize);
 
+	void freeImages();
+	void freeSequences();
+
 
 	bool playMidi(Common::Array<byte> *buffer);
 


Commit: 1e068131005f5802905bd738ff0771659318ddfc
    https://github.com/scummvm/scummvm/commit/1e068131005f5802905bd738ff0771659318ddfc
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:35+01:00

Commit Message:
GAMOS: Simplify logic of dirty region intersections check

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 319f8cced96..f426d26e8dd 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2071,42 +2071,23 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 		return;
 	}
 
-	int flags = 0;
-
+	bool intersects = 0;
 	for(int i = 0; i < _dirtyRects.size(); i++) {
 		Common::Rect &r = _dirtyRects[i];
 		if (!rect.intersects(r))
 			continue;
 
-		flags |= 1;
+		intersects = true;
 
-		if (rect.left < r.left) {
-			r.left = rect.left;
-			flags |= 2;
-		}
-		if (rect.right > r.right) {
-			r.right = rect.right;
-			flags |= 2;
-		}
-		if (rect.top < r.top) {
-			r.top = rect.top;
-			flags |= 2;
-		}
-		if (rect.bottom > r.bottom) {
-			r.bottom = rect.bottom;
-			flags |= 2;
-		}
+		r.extend(rect);
 		break;
 	}
 
-	if (flags == 0) {
+	if (!intersects) {
 		_dirtyRects.push_back(rect);
 		return;
 	}
 
-	if ( !(flags & 2) )
-		return;
-
 	rerunCheck:
 	for(int i = _dirtyRects.size() - 2; i > 0; i--) {
 		for (int j = _dirtyRects.size() - 1; j > i; j--) {


Commit: c5951670eb0a253cdb1a03b7e3569d0927ab2c95
    https://github.com/scummvm/scummvm/commit/c5951670eb0a253cdb1a03b7e3569d0927ab2c95
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:35+01:00

Commit Message:
GAMOS: Fix wrong usage of high 4 bits which represents ActEntry.t

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index f426d26e8dd..ff5db41f690 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1618,7 +1618,7 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
         PTR_00417218->flags = (PTR_00417218->flags & 0xf) | (e.t << 4);
 
 		uint16 &tref = _states.at(DAT_00417220, DAT_00417224);
-		tref = (tref & 0xff) | (BYTE_004177f6 << 8);
+		tref = (tref & 0xff) | (BYTE_004177f6 << 12);
 
         BYTE_00412200 = 1;
     }
@@ -1702,8 +1702,8 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 			PTR_004121b4 = obj;
 	}
 
-	executeScript(e.t << 4, y, x, odat, index, obj, &act, act.onCreateAddress);
 	rthing = (e.t << 12) | (e.flags << 8) | oid;
+	executeScript(e.t, y, x, odat, index, obj, &act, act.onCreateAddress);
 }
 
 void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
@@ -1760,7 +1760,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	if (povar4)
 		rthing = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
 
-	executeScript(rthing >> 8, id, pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+	executeScript(rthing >> 12, id, pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
 }
 
 Object *GamosEngine::getFreeObject() {


Commit: 3b7b264ec994614b74135581979526f67483245f
    https://github.com/scummvm/scummvm/commit/3b7b264ec994614b74135581979526f67483245f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:36+01:00

Commit Message:
GAMOS: Fix crash in FUN_0040255c on null object

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index ff5db41f690..9f37f9cc21d 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2729,10 +2729,15 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 	if (obj == PTR_004121b4) {
 		PTR_004121b4 = nullptr;
 		int32 n = 0;
+
+		int16 objIndex = -1;
+		if (obj)
+			objIndex = obj->index;
+
 		for (int32 i = 0; i < _objects.size(); i++) {
 			Object &robj = _objects[i];
 
-			if (robj.index > obj->index)
+			if (robj.index > objIndex)
 				n++;
 
 			if ( (robj.flags & 3) == 3 && (_objectActions[robj.actID].unk1 & 0xff) == 3 ) {


Commit: 1bc20af9feef3afdad487c91c964914afba1530e
    https://github.com/scummvm/scummvm/commit/1bc20af9feef3afdad487c91c964914afba1530e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:36+01:00

Commit Message:
GAMOS: Blit object with 0x40 flag set as it's not apply x/y offsets

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 9f37f9cc21d..7a3d16879d6 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2170,10 +2170,17 @@ void GamosEngine::doDraw() {
 				flip |= Graphics::FLIP_H;
 			if (o->flags & 0x10)
 				flip |= Graphics::FLIP_V;
-			Blitter::blit(&o->pImg->image->surface,
-						   Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
-		                   _screen->surfacePtr(),
-						   Common::Rect(o->x, o->y, _screen->w, _screen->h), flip);
+			if (o->flags & 0x40) {
+				Blitter::blit(&o->pImg->image->surface,
+					Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
+					_screen->surfacePtr(),
+					Common::Rect(o->x - o->pImg->xoffset, o->y - o->pImg->yoffset, _screen->w, _screen->h), flip);
+			} else {
+				Blitter::blit(&o->pImg->image->surface,
+					Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
+					_screen->surfacePtr(),
+					Common::Rect(o->x, o->y, o->x + o->pImg->image->surface.w, o->y + o->pImg->image->surface.h), flip);
+			}
 		}
 	}
 


Commit: 2023238aea7837bd174e77d3b7ecc6955b41368b
    https://github.com/scummvm/scummvm/commit/2023238aea7837bd174e77d3b7ecc6955b41368b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:36+01:00

Commit Message:
GAMOS: Disable instruction logging for VM because seems it's stable

Changed paths:
    engines/gamos/vm.cpp


diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 2dc5ab9352b..33727b7e952 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -133,7 +133,7 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 
     SP = STACK_POS;
 
-    Common::Array<OpLog> cmdlog;
+    //Common::Array<OpLog> cmdlog;
 
     bool loop = true;
     while (loop) {
@@ -141,7 +141,7 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
             return 0;
 
         byte op = _readAccess.getU8(ESI);
-        cmdlog.push_back({ESI, (OP)op, SP});
+        //cmdlog.push_back({ESI, (OP)op, SP});
         ESI++;
 
         switch (op) {
@@ -595,7 +595,7 @@ void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
     uint32 pos = 0;
     uint32 remain = dataSize;
 
-    printf("Write memory at %x sz %x\n", address, dataSize);
+    //printf("Write memory at %x sz %x\n", address, dataSize);
 
     for (uint32 addr = blockAddr; addr < address + dataSize; addr += 0x100) {
         MemoryBlock &block = _memMap.getOrCreateVal(addr);


Commit: 5d42472c81d73950a74149239a030895b829e344
    https://github.com/scummvm/scummvm/commit/5d42472c81d73950a74149239a030895b829e344
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:37+01:00

Commit Message:
GAMOS: Implement multiple VM callback functions used in games

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 7a3d16879d6..532e7d6890c 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2340,6 +2340,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 		break;
 
+	case 27:
+		FUN_004025d0();
+		vm->EAX.val = 1;
+		break;
+
 	case 30: {
 		if (PTR_00417218->y != -1) {
 			Object *obj = &_objects[PTR_00417218->y];
@@ -2365,6 +2370,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.val = 1;
 		break;
 
+	case 34: {
+		VM::Reg regRef = vm->popReg();
+		vm->setMem8(regRef.ref, regRef.val, PTR_00417218->fld_5);
+		vm->EAX.val = 1;
+	} break;
+
 	case 35:
 		arg1 = vm->pop32();
 
@@ -2476,6 +2487,70 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			vm->EAX.val = 1;
 		break;
 
+	case 39:
+		arg1 = vm->pop32();
+		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412c9c)
+			vm->EAX.val = 0;
+		else
+			vm->EAX.val = 1;
+		break;
+
+	case 42: {
+		arg1 = vm->pop32();
+		if (DAT_00417804 != 0) {
+			if (arg1 == 0) {
+				DAT_00417804 = 0;
+				DAT_004177fe = 255;
+				DAT_00417805 = 255;
+				DAT_004177fd = 255;
+			} else if (arg1 == 1) {
+				ActEntry tmp;
+				tmp.value = 0xfe;
+				tmp.t = BYTE_004177f6;
+				tmp.flags = 0;
+				FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
+			} else if (arg1 == 2) {
+				ActEntry tmp;
+				tmp.value = 0;
+				tmp.t = BYTE_004177f6;
+				tmp.flags = 0;
+				tmp.x = DAT_00412c94 - DAT_00412c8c;
+				tmp.y = DAT_00412c98 - DAT_00412c90;
+				FUN_00402a68(tmp);
+			}
+		}
+		vm->EAX.val = 1;
+	} break;
+
+	case 43: {
+		arg1 = vm->pop32();
+		if (DAT_00417804) {
+			ActEntry tmp;
+			tmp.value = arg1;
+			tmp.t = BYTE_004177f6;
+			tmp.flags = 0;
+			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
+		}
+		vm->EAX.val = 1;
+	} break;
+
+	case 44: {
+		arg1 = vm->pop32();
+		if (DAT_00417804) {
+			ActEntry tmp;
+			tmp.value = arg1;
+			tmp.t = BYTE_004177f6;
+			tmp.flags = 1;
+			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
+		}
+		vm->EAX.val = 1;
+	} break;
+
+	case 45:
+		arg1 = vm->pop32();
+		vm->EAX.val = (PTR_00417218->flags & arg1) ? 1 : 0;
+		break;
+
 	case 47: {
 		arg1 = vm->pop32();
 
@@ -3475,6 +3550,30 @@ void Actions::parse(const byte *data, size_t dataSize) {
 }
 
 
+void GamosEngine::FUN_004025d0() {
+	if (PTR_00417218->fld_2 != 0xfe) {
+		ObjectAction &act = _objectActions[PTR_00417218->fld_2];
+		PTR_00417218->pos;
+
+		for(int i = 0; i < _objects.size(); i++) {
+			Object &obj = _objects[i];
+			if ( (obj.flags & 0xC1) == 0x81 &&
+			     obj.pos == 0xff && obj.blk == 0xff &&
+				 obj.fld_4 == PTR_00417218->pos &&
+				 obj.fld_5 == PTR_00417218->blk ) {
+
+				removeObjectMarkDirty(&obj);
+				break;
+			}
+		}
+
+		executeScript(PTR_00417218->fld_3 >> 4, PTR_00417218->blk, PTR_00417218->pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+		PTR_00417218->fld_2 = 0xfe;
+		PTR_00417218->fld_3 = 0xf0;
+	}
+}
+
+
 bool GamosEngine::FUN_004033a8(Common::Point mouseMove) {
 	_cursorObject.x = mouseMove.x;
 	_cursorObject.y = mouseMove.y;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 9af1f3f3602..541aa5b92a2 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -581,6 +581,9 @@ protected:
 	byte FUN_004081b8(uint8 cv, uint8 sv);
 
 
+	void FUN_004025d0();
+
+
 
 	/* save-load */
 	void storeToGameScreen(int id);


Commit: fcc1ebaefce6638d62b5789cc9cccaa3f3f13bd9
    https://github.com/scummvm/scummvm/commit/fcc1ebaefce6638d62b5789cc9cccaa3f3f13bd9
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:37+01:00

Commit Message:
GAMOS: Fix warning

Changed paths:
    engines/gamos/vm.cpp


diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 33727b7e952..c8ea75085ca 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -1037,7 +1037,7 @@ Common::String VM::opLog(const Common::Array<OpLog> &log) {
 
 void VM::printDisassembly(uint32 address) {
     Common::String tmp = disassembly(address);
-    warning(tmp.c_str());
+    warning("%s", tmp.c_str());
 }
 
 }


Commit: 90755e69c0826caaff5440be5035b93487d30ed6
    https://github.com/scummvm/scummvm/commit/90755e69c0826caaff5440be5035b93487d30ed6
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:37+01:00

Commit Message:
GAMOS: printf -> warning

Changed paths:
    engines/gamos/file.cpp
    engines/gamos/gamos.cpp
    engines/gamos/movie.cpp
    engines/gamos/vm.cpp


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index 80c3d485722..f2d52b83991 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -19,8 +19,6 @@
  *
  */
 
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
-
 #include "gamos/gamos.h"
 
 namespace Gamos {
@@ -102,7 +100,7 @@ int32 Archive::readPackedInt() {
     if (skipsz) {
         skip(skipsz);
         /* warning !!!! */
-        printf("readPackedInt skipped %d\n", skipsz);
+        warning("readPackedInt skipped %d", skipsz);
     }
 
     static int32 negs[4] {0, -1, -1025, -263169};
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 532e7d6890c..06424a6dcf9 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -19,8 +19,6 @@
  *
  */
 
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
-#define FORBIDDEN_SYMBOL_EXCEPTION_sprintf
 #define FORBIDDEN_SYMBOL_EXCEPTION_exit
 #define FORBIDDEN_SYMBOL_EXCEPTION_rand
 #define FORBIDDEN_SYMBOL_EXCEPTION_FILE
@@ -212,7 +210,7 @@ bool GamosEngine::loader2() {
 			p2 = dataStream.readSint32LE();
 		} else if (curByte == 7) {
 			int32 needsz = dataStream.readSint32LE(); // check free mem ?
-			//printf("7777 want %d\n", needsz);
+			//warning("7777 want %d", needsz);
 		} else if (curByte == 0x40) {
 			resSize = 4;
 			resType = 0x40;
@@ -239,11 +237,11 @@ bool GamosEngine::loader2() {
 
 			dataStream.skip(resSize);
 		} else if (curByte == 0xff) {
-			//printf("0xFF  %d %d %d \n", pid, p1, p2);
+			//warning("0xFF  %d %d %d", pid, p1, p2);
 			if (!reuseLastResource(resType, pid, p1, p2, 0))
 				return false;
 		} else {
-			printf("loader2 want %x\n", curByte);
+			warning("loader2 want %x", curByte);
 			return false;
 		}
 	}
@@ -361,7 +359,7 @@ bool GamosEngine::loadModule(uint id) {
 						break;
 
 					case RESTP_43:
-						//printf("t %x sz %x sum %x\n", prevByte, data.size(), _loadedDataSize);
+						//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
 						if (_onlyScanImage)
 							_loadedDataSize += 0x10;
 						else
@@ -369,7 +367,7 @@ bool GamosEngine::loadModule(uint id) {
 						break;
 
 					default:
-						//printf("t %x sz %x sum %x\n", prevByte, data.size(), _loadedDataSize);
+						//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
 						_loadedDataSize += datasz;
 						break;
 				}
@@ -481,11 +479,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_21) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onCreateAddress = _loadedDataSize + p3;
-		//printf("RESTP_21 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
+		//warning("RESTP_21 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_22) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onDeleteAddress = _loadedDataSize + p3;
-		//printf("RESTP_22 %x pid %d sz %x\n", _loadedDataSize, pid, dataSize);
+		//warning("RESTP_22 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_23) {
 		if (dataSize % 4 != 0 || dataSize < 4)
 			return false;
@@ -496,11 +494,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_2B) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].actions[p1].conditionAddress = _loadedDataSize + p3;
-		//printf("RESTP_2B %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
+		//warning("RESTP_2B %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_2C) {
 		VM::writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].actions[p1].functionAddress = _loadedDataSize + p3;
-		//printf("RESTP_2C %x pid %d p1 %d sz %x\n", _loadedDataSize, pid, p1, dataSize);
+		//warning("RESTP_2C %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
 		warning("Data 38 size %zu", dataSize);
 		_thing2[pid].field_0.assign(data, data + dataSize);
@@ -521,10 +519,10 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_51) {
 		uint32 datSz = getU32(data) & (~3);
 		_soundSamples[pid].assign(data + 4, data + 4 + datSz);
-		//printf("sound  size %d\n", dataSize);
+		//warning("sound  size %d", dataSize);
 	} else if (tp == RESTP_52) {
 		return loadRes52(pid, data, dataSize);
-		//printf("midi  size %d\n", dataSize);
+		//warning("midi  size %d", dataSize);
 	} else if (tp == RESTP_60) {
 		_subtitleActions[pid].parse(data, dataSize);
 	} else if (tp == RESTP_61) {
@@ -781,7 +779,7 @@ bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
 }
 
 bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSize) {
-	//printf("loadRes42 pid %d p %d sz %x\n",id, p1, dataSize);
+	//warning("loadRes42 pid %d p %d sz %x",id, p1, dataSize);
 
 	if (_sprites[id].sequences.size() == 0)
 		_sprites[id].sequences.resize(1);
@@ -863,7 +861,7 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 	if (_readingBkgMainId == -1 && (strm.readUint32LE() & 0x80000000) )
 		_readingBkgMainId = id;
 
-	//printf("res 18 id %d 4: %x\n", id, strm.readUint32LE());
+	//warning("res 18 id %d 4: %x", id, strm.readUint32LE());
 
 	strm.seek(8);
 
@@ -872,7 +870,7 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 
 	uint32 imgsize = strm.readUint32LE();
 
-	//printf("res 18 id %d 14: %x\n", id, strm.readUint32LE());
+	//warning("res 18 id %d 14: %x", id, strm.readUint32LE());
 
 	bimg._bkgImage.setPixels(bimg._bkgImageData.data() + 0x18);
 	bimg._bkgImage.format = Graphics::PixelFormat::createFormatCLUT8();
@@ -1083,7 +1081,7 @@ bool GamosEngine::setPaletteCurrentGS() {
 void GamosEngine::readData2(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
 
-	printf("Game data size %d\n", data.size());
+	warning("Game data size %d", data.size());
 
 	if (getEngineVersion() == 0x80000018) {
 		_stateExt = dataStream.readString(0, 4); // FIX ME
@@ -2258,7 +2256,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		break;
 	case 5:
 		arg1 = vm->pop32();
-		//printf("func 5 %x check %x \n", PTR_00417218->fld_4 & 0xb0, arg1);
+		//warning("func 5 %x check %x", PTR_00417218->fld_4 & 0xb0, arg1);
 		vm->EAX.val = (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0;
 		break;
 	case 6:
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index cdcc4fef81d..a4ca65683ad 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -19,8 +19,6 @@
  *
  */
 
- #define FORBIDDEN_SYMBOL_EXCEPTION_printf
-
 #include "gamos/gamos.h"
 
 namespace Gamos {
@@ -138,7 +136,7 @@ bool MoviePlayer::error() {
 }
 
 int MoviePlayer::processControlChunk() {
-    printf("%x movieProcessControl %d\n", _file->pos(), _hdrBytes[1]);
+    warning("%x movieProcessControl %d", _file->pos(), _hdrBytes[1]);
 
     switch(_hdrBytes[1]) {
     case 0:
@@ -211,7 +209,7 @@ int MoviePlayer::processControlChunk() {
 }
 
 int MoviePlayer::processImageChunk() {
-    printf("%x movieProcessImageChunk %d\n", _file->pos(), _hdrValue1);
+    warning("%x movieProcessImageChunk %d", _file->pos(), _hdrValue1);
     if (!readCompressed(_bufferSize, &_buffer))
         return 0;
 
@@ -278,7 +276,7 @@ int MoviePlayer::processImageChunk() {
                 wh = _frameSize;
             }
 
-            printf("movie blit%d %d %d %d %d\n", val & 3, xy.x, xy.y, wh.x, wh.y);
+            warning("movie blit%d %d %d %d %d", val & 3, xy.x, xy.y, wh.x, wh.y);
             static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) =
                {&blit0,
                 &blit1,
@@ -354,7 +352,7 @@ int MoviePlayer::processImageChunk() {
 }
 
 int MoviePlayer::processPaletteChunk() {
-    printf("%x movieProcessPaletteChunk\n", _file->pos());
+    warning("%x movieProcessPaletteChunk", _file->pos());
     if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
         return 0;
 
@@ -365,14 +363,14 @@ int MoviePlayer::processPaletteChunk() {
 }
 
 int MoviePlayer::processSoundChunk() {
-    printf("%x movieProcessSoundChunk\n", _file->pos());
+    warning("%x movieProcessSoundChunk", _file->pos());
     if (!readCompressed(_soundBufferSize, &_soundBuffer))
         return 0;
     return 1;
 }
 
 int MoviePlayer::proccessMidiChunk() {
-    printf("%x movieProccessMidiChunk\n", _file->pos());
+    warning("%x movieProcessMidiChunk", _file->pos());
 
     if (_midiStarted && (_forceStopMidi == false || _hdrBytes[1] != 0)) {
         _gamos->stopMidi();
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index c8ea75085ca..9c259adbcf3 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -18,7 +18,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-#define FORBIDDEN_SYMBOL_EXCEPTION_printf
 #define FORBIDDEN_SYMBOL_EXCEPTION_fopen
 #define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
 #define FORBIDDEN_SYMBOL_EXCEPTION_FILE
@@ -595,7 +594,7 @@ void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
     uint32 pos = 0;
     uint32 remain = dataSize;
 
-    //printf("Write memory at %x sz %x\n", address, dataSize);
+    //warning("Write memory at %x sz %x", address, dataSize);
 
     for (uint32 addr = blockAddr; addr < address + dataSize; addr += 0x100) {
         MemoryBlock &block = _memMap.getOrCreateVal(addr);


Commit: a761316413b747d0566b4d06efefc76562fdeb96
    https://github.com/scummvm/scummvm/commit/a761316413b747d0566b4d06efefc76562fdeb96
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:38+01:00

Commit Message:
GAMOS: Fix warnings

Changed paths:
    engines/gamos/movie.cpp


diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index a4ca65683ad..e37c9b2305e 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -136,7 +136,7 @@ bool MoviePlayer::error() {
 }
 
 int MoviePlayer::processControlChunk() {
-    warning("%x movieProcessControl %d", _file->pos(), _hdrBytes[1]);
+    warning("%x movieProcessControl %d", (uint32)_file->pos(), _hdrBytes[1]);
 
     switch(_hdrBytes[1]) {
     case 0:
@@ -209,7 +209,7 @@ int MoviePlayer::processControlChunk() {
 }
 
 int MoviePlayer::processImageChunk() {
-    warning("%x movieProcessImageChunk %d", _file->pos(), _hdrValue1);
+    warning("%x movieProcessImageChunk %d", (uint32)_file->pos(), _hdrValue1);
     if (!readCompressed(_bufferSize, &_buffer))
         return 0;
 
@@ -352,7 +352,7 @@ int MoviePlayer::processImageChunk() {
 }
 
 int MoviePlayer::processPaletteChunk() {
-    warning("%x movieProcessPaletteChunk", _file->pos());
+    warning("%x movieProcessPaletteChunk", (uint32)_file->pos());
     if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
         return 0;
 
@@ -363,14 +363,14 @@ int MoviePlayer::processPaletteChunk() {
 }
 
 int MoviePlayer::processSoundChunk() {
-    warning("%x movieProcessSoundChunk", _file->pos());
+    warning("%x movieProcessSoundChunk", (uint32)_file->pos());
     if (!readCompressed(_soundBufferSize, &_soundBuffer))
         return 0;
     return 1;
 }
 
 int MoviePlayer::proccessMidiChunk() {
-    warning("%x movieProcessMidiChunk", _file->pos());
+    warning("%x movieProcessMidiChunk", (uint32)_file->pos());
 
     if (_midiStarted && (_forceStopMidi == false || _hdrBytes[1] != 0)) {
         _gamos->stopMidi();


Commit: 7b1a99f0c02be11d4e86773e84061adda251c8a5
    https://github.com/scummvm/scummvm/commit/7b1a99f0c02be11d4e86773e84061adda251c8a5
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:38+01:00

Commit Message:
GAMOS: Replace fprintf() with proper Common::DumpFile usage

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/vm.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 06424a6dcf9..40468e75887 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -21,12 +21,6 @@
 
 #define FORBIDDEN_SYMBOL_EXCEPTION_exit
 #define FORBIDDEN_SYMBOL_EXCEPTION_rand
-#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
-#define FORBIDDEN_SYMBOL_EXCEPTION_fopen
-#define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
-#define FORBIDDEN_SYMBOL_EXCEPTION_fclose
-#define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
-#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
 
 
 #include "gamos/gamos.h"
@@ -3586,51 +3580,49 @@ bool GamosEngine::FUN_004038b8() {
 
 void GamosEngine::dumpActions() {
 	Common::String t = Common::String::format("actions_%d.txt", _currentModuleID);
-	FILE *f = fopen(t.c_str(), "wb");
+
+	Common::DumpFile f;
+
+	if (!f.open(t.c_str(), true))
+		error("Cannot create actions dump file");
+
 	int i = 0;
 	for (ObjectAction &act : _objectActions) {
-		fprintf(f, "Act %d : %x\n", i, act.unk1);
+		f.writeString(Common::String::format("Act %d : %x\n", i, act.unk1));
 		if (act.onCreateAddress != -1) {
 			t = VM::disassembly(act.onCreateAddress);
-			fprintf(f, "Script1 : \n");
-			fwrite(t.c_str(), t.size(), 1, f);
-			fprintf(f, "\n");
+			f.writeString(Common::String::format("Script1 : \n%s\n", t.c_str()));
 		}
 
 		if (act.onDeleteAddress != -1) {
 			t = VM::disassembly(act.onDeleteAddress);
-			fprintf(f, "Script2 : \n");
-			fwrite(t.c_str(), t.size(), 1, f);
-			fprintf(f, "\n");
+			f.writeString(Common::String::format("Script2 : \n%s\n", t.c_str()));
 		}
 
 		int j = 0;
 		for (Actions &sc : act.actions) {
-			fprintf(f, "subscript %d : \n", j);
+			f.writeString(Common::String::format("subscript %d : \n", j));
 
 			if (sc.conditionAddress != -1) {
 				t = VM::disassembly(sc.conditionAddress);
-				fprintf(f, "condition : \n");
-				fwrite(t.c_str(), t.size(), 1, f);
-				fprintf(f, "\n");
+				f.writeString(Common::String::format("condition : \n%s\n", t.c_str()));
 			}
 
 			if (sc.functionAddress != -1) {
 				t = VM::disassembly(sc.functionAddress);
-				fprintf(f, "action : \n");
-				fwrite(t.c_str(), t.size(), 1, f);
-				fprintf(f, "\n");
+				f.writeString(Common::String::format("action : \n%s\n", t.c_str()));
 			}
 
 			j++;
 		}
 
 
-		fprintf(f, "\n\n#############################################\n\n");
+		f.writeString("\n\n#############################################\n\n");
 
 		i++;
 	}
-	fclose(f);
+	f.flush();
+	f.close();
 
 	warning("Actions saved into actions_%d.txt", _currentModuleID);
 }
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index 9c259adbcf3..c014153afd7 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -18,10 +18,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-#define FORBIDDEN_SYMBOL_EXCEPTION_fopen
-#define FORBIDDEN_SYMBOL_EXCEPTION_fwrite
-#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
-#define FORBIDDEN_SYMBOL_EXCEPTION_fclose
+
 #include "gamos/gamos.h"
 
 namespace Gamos {
@@ -1027,9 +1024,13 @@ Common::String VM::opLog(const Common::Array<OpLog> &log) {
         tmp += Common::String::format("%08x: SP:%04x OP:[%02d] ", l.addr, l.sp, l.op) + decodeOp(l.addr) + "\n";
     }
 
-    FILE *f = fopen("oplog", "wb");
-    fwrite(tmp.c_str(), tmp.size(), 1, f);
-    fclose(f);
+    Common::DumpFile f;
+
+    if (f.open("oplog", true)) {
+        f.writeString(tmp);
+        f.flush();
+        f.close();
+    }
 
     return tmp;
 }


Commit: faad47a29d1e13c5e3fa2d6f9bb981d1c2ec05ea
    https://github.com/scummvm/scummvm/commit/faad47a29d1e13c5e3fa2d6f9bb981d1c2ec05ea
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:39+01:00

Commit Message:
GAMOS: Eliminated exit() call useage

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 40468e75887..97ae7ce5515 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -19,10 +19,6 @@
  *
  */
 
-#define FORBIDDEN_SYMBOL_EXCEPTION_exit
-#define FORBIDDEN_SYMBOL_EXCEPTION_rand
-
-
 #include "gamos/gamos.h"
 #include "graphics/framelimiter.h"
 #include "gamos/detection.h"
@@ -762,10 +758,9 @@ bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
 }
 
 bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
-	if (*(const uint32 *)data != 0) {
-		warning("41 not null!!!");
-		exit(0);
-	}
+	if (*(const uint32 *)data != 0)
+		error("41 not null!!!");
+
 	if (dataSize % 4)
 		warning("loadRes41 datasize > 4");
 	_sprites[id].sequences.resize(dataSize / 4);
@@ -786,8 +781,7 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 	for(int i = 0; i < count; ++i) {
 		int32 dataz = strm.readSint32LE();
 		if (dataz != 0) {
-			warning("42    nut null");
-			exit(0);
+			error("42    nut null");
 		}
 
 		ImagePos &imgpos = _sprites[id].sequences[p1]->operator[](i);


Commit: 83817b935b7447e024d1408e495d04fdcb93ef4c
    https://github.com/scummvm/scummvm/commit/83817b935b7447e024d1408e495d04fdcb93ef4c
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:39+01:00

Commit Message:
JANITORIAL: Run astyle

Changed paths:
    engines/gamos/array2d.h
    engines/gamos/blit.cpp
    engines/gamos/blit.h
    engines/gamos/detection.cpp
    engines/gamos/file.cpp
    engines/gamos/file.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/keycodes.cpp
    engines/gamos/keycodes.h
    engines/gamos/metaengine.cpp
    engines/gamos/movie.cpp
    engines/gamos/movie.h
    engines/gamos/music.cpp
    engines/gamos/music.h
    engines/gamos/pool.h
    engines/gamos/proc.cpp
    engines/gamos/proc.h
    engines/gamos/saveload.cpp
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/array2d.h b/engines/gamos/array2d.h
index 2546825f9d4..5635cab4be2 100644
--- a/engines/gamos/array2d.h
+++ b/engines/gamos/array2d.h
@@ -27,132 +27,131 @@
 #include "common/rect.h"
 
 template <class T>
-class Array2D : protected Common::Array<T>
-{
+class Array2D : protected Common::Array<T> {
 private:
-    typedef Common::Array<T> __base;
+	typedef Common::Array<T> __base;
 public:
-    typedef uint size_type; /*!< Size type of the array. */
+	typedef uint size_type; /*!< Size type of the array. */
 
-    using Common::Array<T>::data;
-    using Common::Array<T>::operator[];
-    using Common::Array<T>::size;
-    using Common::Array<T>::begin;
-    using Common::Array<T>::end;
-    using Common::Array<T>::empty;
+	using Common::Array<T>::data;
+	using Common::Array<T>::operator[];
+	using Common::Array<T>::size;
+	using Common::Array<T>::begin;
+	using Common::Array<T>::end;
+	using Common::Array<T>::empty;
 
 public:
 
 
-    Array2D() = default;
-    Array2D( Array2D && ) = default;
-    Array2D( const Array2D & ) = default;
+	Array2D() = default;
+	Array2D(Array2D &&) = default;
+	Array2D(const Array2D &) = default;
 
-    Array2D& operator=( const Array2D & ) = default;
-    Array2D& operator=( Array2D && ) = default;
+	Array2D &operator=(const Array2D &) = default;
+	Array2D &operator=(Array2D &&) = default;
 
-    Array2D(size_type w, size_type h) {
-        resize(w, h);
-    }
+	Array2D(size_type w, size_type h) {
+		resize(w, h);
+	}
 
-    Array2D(const Common::Point &sz) {
-        resize(sz);
-    }
+	Array2D(const Common::Point &sz) {
+		resize(sz);
+	}
 
-    Array2D<T>* copy() {
-        Array2D<T> *tmp = new Array2D<T>;
-        *tmp = *this;
-        return tmp;
-    }
+	Array2D<T> *copy() {
+		Array2D<T> *tmp = new Array2D<T>;
+		*tmp = *this;
+		return tmp;
+	}
 
-    void resize(const Common::Point &sz) {
-        _w = sz.x;
-        _h = sz.y;
+	void resize(const Common::Point &sz) {
+		_w = sz.x;
+		_h = sz.y;
 
-        __base::resize(_w * _h);
-    }
+		__base::resize(_w * _h);
+	}
 
-    void resize(size_type w, size_type h) {
-        _w = w;
-        _h = h;
+	void resize(size_type w, size_type h) {
+		_w = w;
+		_h = h;
 
-        __base::resize(_w * _h);
-    }
+		__base::resize(_w * _h);
+	}
 
-    T& at(size_type x, size_type y) {
-        return __base::operator[](x + y * _w);
-    }
+	T &at(size_type x, size_type y) {
+		return __base::operator[](x + y * _w);
+	}
 
-    T& at(const Common::Point &p) {
-        return __base::operator[](p.x + p.y * _w);
-    }
+	T &at(const Common::Point &p) {
+		return __base::operator[](p.x + p.y * _w);
+	}
 
-    T& at(size_type n) {
-        return __base::operator[](n);
-    }
+	T &at(size_type n) {
+		return __base::operator[](n);
+	}
 
-    T& operator()(size_type x, size_type y) {
-        return at(x + y * _w);
-    }
+	T &operator()(size_type x, size_type y) {
+		return at(x + y * _w);
+	}
 
-    T& operator()(const Common::Point &p) {
-        return at(p.x + p.y * _w);
-    }
+	T &operator()(const Common::Point &p) {
+		return at(p.x + p.y * _w);
+	}
 
-    T* getLinePtr(size_type y) {
-        return &(at(y * _w));
-    }
+	T *getLinePtr(size_type y) {
+		return &(at(y * _w));
+	}
 
-    const T* getLinePtr(size_type y) const {
-        return &(at(y * _w));
-    }
+	const T *getLinePtr(size_type y) const {
+		return &(at(y * _w));
+	}
 
-    Common::Point sizes() const {
-        return Common::Point(_w, _h);
-    }
+	Common::Point sizes() const {
+		return Common::Point(_w, _h);
+	}
 
-    size_type getIndex(size_type x, size_type y) const {
-        size_t n = x + y * _w;
-        if (n < size())
-            return n;
-        return -1;
-    }
+	size_type getIndex(size_type x, size_type y) const {
+		size_t n = x + y * _w;
+		if (n < size())
+			return n;
+		return -1;
+	}
 
-    Common::Point indexToCoords(size_type id) const {
-        if (id >= 0 && id < size())
-            return Common::Point(id % _w, id / _w);
-        return Common::Point(-1, -1);
-    }
+	Common::Point indexToCoords(size_type id) const {
+		if (id >= 0 && id < size())
+			return Common::Point(id % _w, id / _w);
+		return Common::Point(-1, -1);
+	}
 
-    size_type width() const {
-        return _w;
-    }
+	size_type width() const {
+		return _w;
+	}
 
-    size_type height() const {
-        return _h;
-    }
+	size_type height() const {
+		return _h;
+	}
 
-    void clear() {
-        _w = 0;
-        _h = 0;
-        Common::Array<T>::clear();
-    }
+	void clear() {
+		_w = 0;
+		_h = 0;
+		Common::Array<T>::clear();
+	}
 
-    bool isNotNull() const {
-        return _w > 0 && _h > 0;
-    }
+	bool isNotNull() const {
+		return _w > 0 && _h > 0;
+	}
 
-    bool isNull() const {
-        return _w == 0 || _h == 0;
-    }
-
-    bool isOk() const {
-        return _w > 0 && _h > 0 && (size() == _w * _h);
-    }
+	bool isNull() const {
+		return _w == 0 || _h == 0;
+	}
+
+	bool isOk() const {
+		return _w > 0 && _h > 0 && (size() == _w * _h);
+	}
 
 protected:
-    size_type _w = 0;
-    size_type _h = 0;
+	size_type _w = 0;
+	size_type _h = 0;
 };
 
 
diff --git a/engines/gamos/blit.cpp b/engines/gamos/blit.cpp
index 859d709794e..21cd1e42413 100644
--- a/engines/gamos/blit.cpp
+++ b/engines/gamos/blit.cpp
@@ -24,144 +24,144 @@
 namespace Gamos {
 
 void Blitter::blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
-    if (dst->format != src->format)
-        return;
+	if (dst->format != src->format)
+		return;
 
-    Common::Rect drect = dstRect;
-    if (drect.right <= drect.left)
-        drect.right = dst->w;
-    if (drect.bottom <= drect.top)
-        drect.bottom = dst->h;
+	Common::Rect drect = dstRect;
+	if (drect.right <= drect.left)
+		drect.right = dst->w;
+	if (drect.bottom <= drect.top)
+		drect.bottom = dst->h;
 
-    drect.clip(dst->w, dst->h);
+	drect.clip(dst->w, dst->h);
 
-    Common::Rect srect = srcRect;
-    srect.translate(dstRect.left, dstRect.top);
-    srect.clip(drect);
+	Common::Rect srect = srcRect;
+	srect.translate(dstRect.left, dstRect.top);
+	srect.clip(drect);
 
-    drect = srect;
-    srect.translate(-dstRect.left, -dstRect.top);
+	drect = srect;
+	srect.translate(-dstRect.left, -dstRect.top);
 
-    if (srect.isEmpty())
-        return;
+	if (srect.isEmpty())
+		return;
 
-    for(int y = 0; y < srect.height(); y++) {
-        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-        byte *psrc = (byte *)src->getBasePtr(srect.left, srect.top + y);
-        for(int x = srect.left; x < srect.right; x++) {
-            if (*psrc != 0)
-                *pdst = *psrc;
+	for (int y = 0; y < srect.height(); y++) {
+		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+		byte *psrc = (byte *)src->getBasePtr(srect.left, srect.top + y);
+		for (int x = srect.left; x < srect.right; x++) {
+			if (*psrc != 0)
+				*pdst = *psrc;
 
-            psrc++;
-            pdst++;
-        }
-    }
+			psrc++;
+			pdst++;
+		}
+	}
 
 }
 
 void Blitter::blitFlipH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
-    if (dst->format != src->format)
-        return;
-
-    Common::Rect drect = dstRect;
-    if (drect.right <= drect.left)
-        drect.right = dst->w;
-    if (drect.bottom <= drect.top)
-        drect.bottom = dst->h;
-
-    drect.clip(dst->w, dst->h);
-
-    Common::Rect srect = srcRect;
-    srect.translate(dstRect.left, dstRect.top);
-    srect.clip(drect);
-
-    drect = srect;
-    srect.translate(-dstRect.left, -dstRect.top);
-
-    if (srect.isEmpty())
-        return;
-
-    for(int y = srect.top; y < srect.bottom; y++) {
-        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-        byte *psrc = (byte *)src->getBasePtr(srect.right - 1, y);
-        for(int x = srect.left; x < srect.right; x++) {
-            if (*psrc != 0)
-                *pdst = *psrc;
-
-            psrc--;
-            pdst++;
-        }
-    }
+	if (dst->format != src->format)
+		return;
+
+	Common::Rect drect = dstRect;
+	if (drect.right <= drect.left)
+		drect.right = dst->w;
+	if (drect.bottom <= drect.top)
+		drect.bottom = dst->h;
+
+	drect.clip(dst->w, dst->h);
+
+	Common::Rect srect = srcRect;
+	srect.translate(dstRect.left, dstRect.top);
+	srect.clip(drect);
+
+	drect = srect;
+	srect.translate(-dstRect.left, -dstRect.top);
+
+	if (srect.isEmpty())
+		return;
+
+	for (int y = srect.top; y < srect.bottom; y++) {
+		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+		byte *psrc = (byte *)src->getBasePtr(srect.right - 1, y);
+		for (int x = srect.left; x < srect.right; x++) {
+			if (*psrc != 0)
+				*pdst = *psrc;
+
+			psrc--;
+			pdst++;
+		}
+	}
 }
 
 void Blitter::blitFlipV(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
-    if (dst->format != src->format)
-        return;
-
-    Common::Rect drect = dstRect;
-    if (drect.right <= drect.left)
-        drect.right = dst->w;
-    if (drect.bottom <= drect.top)
-        drect.bottom = dst->h;
-
-    drect.clip(dst->w, dst->h);
-
-    Common::Rect srect = srcRect;
-    srect.translate(dstRect.left, dstRect.top);
-    srect.clip(drect);
-
-    drect = srect;
-    srect.translate(-dstRect.left, -dstRect.top);
-
-    if (srect.isEmpty())
-        return;
-
-    for(int y = srect.top; y < srect.bottom; y++) {
-        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-        byte *psrc = (byte *)src->getBasePtr(srect.left, srect.bottom - 1 - y);
-        for(int x = srect.left; x < srect.right; x++) {
-            if (*psrc != 0)
-                *pdst = *psrc;
-
-            psrc++;
-            pdst++;
-        }
-    }
+	if (dst->format != src->format)
+		return;
+
+	Common::Rect drect = dstRect;
+	if (drect.right <= drect.left)
+		drect.right = dst->w;
+	if (drect.bottom <= drect.top)
+		drect.bottom = dst->h;
+
+	drect.clip(dst->w, dst->h);
+
+	Common::Rect srect = srcRect;
+	srect.translate(dstRect.left, dstRect.top);
+	srect.clip(drect);
+
+	drect = srect;
+	srect.translate(-dstRect.left, -dstRect.top);
+
+	if (srect.isEmpty())
+		return;
+
+	for (int y = srect.top; y < srect.bottom; y++) {
+		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+		byte *psrc = (byte *)src->getBasePtr(srect.left, srect.bottom - 1 - y);
+		for (int x = srect.left; x < srect.right; x++) {
+			if (*psrc != 0)
+				*pdst = *psrc;
+
+			psrc++;
+			pdst++;
+		}
+	}
 }
 
 void Blitter::blitFlipVH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect) {
-    if (dst->format != src->format)
-        return;
-
-    Common::Rect drect = dstRect;
-    if (drect.right <= drect.left)
-        drect.right = dst->w;
-    if (drect.bottom <= drect.top)
-        drect.bottom = dst->h;
-
-    drect.clip(dst->w, dst->h);
-
-    Common::Rect srect = srcRect;
-    srect.translate(dstRect.left, dstRect.top);
-    srect.clip(drect);
-
-    drect = srect;
-    srect.translate(-dstRect.left, -dstRect.top);
-
-    if (srect.isEmpty())
-        return;
-
-    for(int y = srect.top; y < srect.bottom; y++) {
-        byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-        byte *psrc = (byte *)src->getBasePtr(srect.right - 1, srect.bottom - 1 - y);
-        for(int x = srect.left; x < srect.right; x++) {
-            if (*psrc != 0)
-                *pdst = *psrc;
-
-            psrc--;
-            pdst++;
-        }
-    }
+	if (dst->format != src->format)
+		return;
+
+	Common::Rect drect = dstRect;
+	if (drect.right <= drect.left)
+		drect.right = dst->w;
+	if (drect.bottom <= drect.top)
+		drect.bottom = dst->h;
+
+	drect.clip(dst->w, dst->h);
+
+	Common::Rect srect = srcRect;
+	srect.translate(dstRect.left, dstRect.top);
+	srect.clip(drect);
+
+	drect = srect;
+	srect.translate(-dstRect.left, -dstRect.top);
+
+	if (srect.isEmpty())
+		return;
+
+	for (int y = srect.top; y < srect.bottom; y++) {
+		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+		byte *psrc = (byte *)src->getBasePtr(srect.right - 1, srect.bottom - 1 - y);
+		for (int x = srect.left; x < srect.right; x++) {
+			if (*psrc != 0)
+				*pdst = *psrc;
+
+			psrc--;
+			pdst++;
+		}
+	}
 }
 
 }
diff --git a/engines/gamos/blit.h b/engines/gamos/blit.h
index 14896c44a7e..5830679e06f 100644
--- a/engines/gamos/blit.h
+++ b/engines/gamos/blit.h
@@ -29,31 +29,31 @@ namespace Gamos {
 
 class Blitter {
 protected:
-    static void blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
-    static void blitFlipH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
-    static void blitFlipV(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
-    static void blitFlipVH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+	static void blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+	static void blitFlipH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+	static void blitFlipV(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
+	static void blitFlipVH(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect);
 
 public:
-    static void blit(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect, uint flip = 0) {
-        switch(flip) {
-            default:
-                blitNormal(src, srcRect, dst, dstRect);
-                break;
-
-            case Graphics::FLIP_H:
-                blitFlipH(src, srcRect, dst, dstRect);
-                break;
-
-            case Graphics::FLIP_V:
-                blitFlipV(src, srcRect, dst, dstRect);
-                break;
-
-            case Graphics::FLIP_VH:
-                blitFlipVH(src, srcRect, dst, dstRect);
-                break;
-        }
-    };
+	static void blit(Graphics::Surface *src, const Common::Rect &srcRect, Graphics::Surface *dst, const Common::Rect &dstRect, uint flip = 0) {
+		switch (flip) {
+		default:
+			blitNormal(src, srcRect, dst, dstRect);
+			break;
+
+		case Graphics::FLIP_H:
+			blitFlipH(src, srcRect, dst, dstRect);
+			break;
+
+		case Graphics::FLIP_V:
+			blitFlipV(src, srcRect, dst, dstRect);
+			break;
+
+		case Graphics::FLIP_VH:
+			blitFlipVH(src, srcRect, dst, dstRect);
+			break;
+		}
+	};
 };
 
 }
diff --git a/engines/gamos/detection.cpp b/engines/gamos/detection.cpp
index 192bc6ea7aa..fbba85cc5db 100644
--- a/engines/gamos/detection.cpp
+++ b/engines/gamos/detection.cpp
@@ -33,7 +33,7 @@ class GamosMetaEngineDetection : public AdvancedMetaEngineDetection<Gamos::Gamos
 
 public:
 	GamosMetaEngineDetection(): AdvancedMetaEngineDetection(
-		Gamos::gameDescriptions, Gamos::gamosGames) {
+		    Gamos::gameDescriptions, Gamos::gamosGames) {
 	}
 	~GamosMetaEngineDetection() override {}
 
diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index f2d52b83991..48c4ba4a19d 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -30,179 +30,179 @@ Archive::~Archive() {
 };
 
 bool Archive::open(const Common::Path &name) {
-    bool res = File::open(name);
+	bool res = File::open(name);
 
-    if (!res)
-        return false;
+	if (!res)
+		return false;
 
-    seek(-12, SEEK_END);
+	seek(-12, SEEK_END);
 
-    _dirOffset = 12 + readUint32LE();
-    skip(4);
-    uint32 magic = readUint32LE();
+	_dirOffset = 12 + readUint32LE();
+	skip(4);
+	uint32 magic = readUint32LE();
 
-    if (magic != 0x3d53563d) // =VS=
-        return false;
+	if (magic != 0x3d53563d) // =VS=
+		return false;
 
-    seek(-_dirOffset, SEEK_END);
+	seek(-_dirOffset, SEEK_END);
 
-    _dirCount = readUint32LE();
-    _dataOffset = readUint32LE();
+	_dirCount = readUint32LE();
+	_dataOffset = readUint32LE();
 
-    seek(-(_dirOffset + _dirCount * 5), SEEK_END);
+	seek(-(_dirOffset + _dirCount * 5), SEEK_END);
 
-    _directories.resize(_dirCount);
+	_directories.resize(_dirCount);
 
-    for(uint i = 0; i < _dirCount; ++i) {
-        ArchiveDir &dir = _directories[i];
+	for (uint i = 0; i < _dirCount; ++i) {
+		ArchiveDir &dir = _directories[i];
 
-        dir.offset = readUint32LE();
-        dir.id = readByte();
-    }
+		dir.offset = readUint32LE();
+		dir.id = readByte();
+	}
 
-    return true;
+	return true;
 }
 
 bool Archive::seekDir(uint id) {
-    int16 idx = findDirByID(id);
-    if (idx < 0)
-        return false;
+	int16 idx = findDirByID(id);
+	if (idx < 0)
+		return false;
 
-    const ArchiveDir &dir = _directories[idx];
+	const ArchiveDir &dir = _directories[idx];
 
-    if ( !seek(_dataOffset + dir.offset, SEEK_SET) )
-        return false;
+	if (!seek(_dataOffset + dir.offset, SEEK_SET))
+		return false;
 
-    return true;
+	return true;
 }
 
 int32 Archive::readPackedInt() {
-    byte b = readByte();
-    if ( !(b & 0x80) )
-        return b;
-
-    byte num = 0;
-    byte skipsz = 0;
-    if ( !(b & 0x20) )
-        num = b & 0x1f;
-    else
-        num = 1 + ((b >> 2) & 3);
-
-    if (num > 4) {
-        skipsz = num - 4;
-        num = 4;
-    }
-
-    int32 val = 0;
-    for(int i = 0; i < num; ++i)
-        val |= readByte() << (i << 3);
-
-    if (skipsz) {
-        skip(skipsz);
-        /* warning !!!! */
-        warning("readPackedInt skipped %d", skipsz);
-    }
-
-    static int32 negs[4] {0, -1, -1025, -263169};
-    static int32 adds[4] {0, 0x80, 0x480, 0x40480};
-
-    if (b & 0x20) {
-        val += (b & 3) * (1 << ((num << 3) & 0x1f));
-        if (b & 0x10)
-            val = negs[num] - val;
-        else
-            val += adds[num];
-    }
-
-    return val;
+	byte b = readByte();
+	if (!(b & 0x80))
+		return b;
+
+	byte num = 0;
+	byte skipsz = 0;
+	if (!(b & 0x20))
+		num = b & 0x1f;
+	else
+		num = 1 + ((b >> 2) & 3);
+
+	if (num > 4) {
+		skipsz = num - 4;
+		num = 4;
+	}
+
+	int32 val = 0;
+	for (int i = 0; i < num; ++i)
+		val |= readByte() << (i << 3);
+
+	if (skipsz) {
+		skip(skipsz);
+		/* warning !!!! */
+		warning("readPackedInt skipped %d", skipsz);
+	}
+
+	static int32 negs[4] {0, -1, -1025, -263169};
+	static int32 adds[4] {0, 0x80, 0x480, 0x40480};
+
+	if (b & 0x20) {
+		val += (b & 3) * (1 << ((num << 3) & 0x1f));
+		if (b & 0x10)
+			val = negs[num] - val;
+		else
+			val += adds[num];
+	}
+
+	return val;
 }
 
 RawData *Archive::readCompressedData() {
-    RawData *data = new RawData();
-    if (!readCompressedData(data)) {
-        delete data;
-        data = nullptr;
-    }
-    return data;
+	RawData *data = new RawData();
+	if (!readCompressedData(data)) {
+		delete data;
+		data = nullptr;
+	}
+	return data;
 }
 
 bool Archive::readCompressedData(RawData *out) {
-    const byte t = readByte();
-    if ((t & 0x80) == 0)
-        return false;
-
-    _lastReadDecompressedSize = 0;
-    _lastReadSize = 0;
-
-    if (t & 0x40) {
-        /* small uncompressed data */
-        _lastReadSize = t & 0x1F;
-    } else {
-        /* read size */
-        const byte szsize = (t & 3) + 1;
-
-        /* big data size */
-        for (uint i = 0; i < szsize; ++i)
-            _lastReadSize |= readByte() << (i << 3);
-
-        /* is compressed */
-        if (t & 0xC) {
-            for (uint i = 0; i < szsize; ++i)
-                _lastReadDecompressedSize |= readByte() << (i << 3);
-        }
-    }
-
-    if (!_lastReadSize)
-        return false;
-
-    _lastReadDataOffset = pos();
-    out->resize(_lastReadSize);
-    read(out->data(), _lastReadSize);
-
-    if (!_lastReadDecompressedSize)
-        return true;
-
-    /* looks hacky but we just allocate array for decompressed and swap it with compressed */
-    RawData compressed(_lastReadDecompressedSize);
-    out->swap(compressed);
-
-    decompress(&compressed, out);
-    return true;
+	const byte t = readByte();
+	if ((t & 0x80) == 0)
+		return false;
+
+	_lastReadDecompressedSize = 0;
+	_lastReadSize = 0;
+
+	if (t & 0x40) {
+		/* small uncompressed data */
+		_lastReadSize = t & 0x1F;
+	} else {
+		/* read size */
+		const byte szsize = (t & 3) + 1;
+
+		/* big data size */
+		for (uint i = 0; i < szsize; ++i)
+			_lastReadSize |= readByte() << (i << 3);
+
+		/* is compressed */
+		if (t & 0xC) {
+			for (uint i = 0; i < szsize; ++i)
+				_lastReadDecompressedSize |= readByte() << (i << 3);
+		}
+	}
+
+	if (!_lastReadSize)
+		return false;
+
+	_lastReadDataOffset = pos();
+	out->resize(_lastReadSize);
+	read(out->data(), _lastReadSize);
+
+	if (!_lastReadDecompressedSize)
+		return true;
+
+	/* looks hacky but we just allocate array for decompressed and swap it with compressed */
+	RawData compressed(_lastReadDecompressedSize);
+	out->swap(compressed);
+
+	decompress(&compressed, out);
+	return true;
 }
 
 void Archive::decompress(RawData const *in, RawData *out) {
-    uint pos = 0;
-    uint outPos = 0;
-
-    while (pos < in->size()) {
-        byte ctrlBits = (*in)[pos];
-        pos++;
-
-        for(int bitsLeft = 8; bitsLeft > 0; --bitsLeft) {
-            if (pos >= in->size())
-                return;
-
-            if (ctrlBits & 1) {
-                (*out)[outPos] = (*in)[pos];
-                outPos++;
-                pos++;
-            } else {
-                byte b1 = (*in)[pos];
-                byte b2 = (*in)[pos + 1];
-                pos += 2;
-
-                byte num = (b2 & 0xF) + 3;
-                uint16 distance = b1 | ((b2 & 0xF0) << 4);
-
-                for(int i = 0; i < num; ++i) {
-                    (*out)[outPos] = (*out)[outPos - distance];
-                    outPos++;
-                }
-            }
-
-            ctrlBits >>= 1;
-        }
-    }
+	uint pos = 0;
+	uint outPos = 0;
+
+	while (pos < in->size()) {
+		byte ctrlBits = (*in)[pos];
+		pos++;
+
+		for (int bitsLeft = 8; bitsLeft > 0; --bitsLeft) {
+			if (pos >= in->size())
+				return;
+
+			if (ctrlBits & 1) {
+				(*out)[outPos] = (*in)[pos];
+				outPos++;
+				pos++;
+			} else {
+				byte b1 = (*in)[pos];
+				byte b2 = (*in)[pos + 1];
+				pos += 2;
+
+				byte num = (b2 & 0xF) + 3;
+				uint16 distance = b1 | ((b2 & 0xF0) << 4);
+
+				for (int i = 0; i < num; ++i) {
+					(*out)[outPos] = (*out)[outPos - distance];
+					outPos++;
+				}
+			}
+
+			ctrlBits >>= 1;
+		}
+	}
 }
 
 
diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index fb3179b3df6..82c42df9afc 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -29,8 +29,8 @@ namespace Gamos {
 typedef Common::Array<byte> RawData;
 
 struct ArchiveDir {
-    uint32 offset;
-    byte id;
+	uint32 offset;
+	byte id;
 };
 
 class Archive : public Common::File {
@@ -39,45 +39,45 @@ public:
 	~Archive() override;
 	bool open(const Common::Path &name) override;
 
-    uint16 getDirCount() const {
-        return _dirCount;
-    }
+	uint16 getDirCount() const {
+		return _dirCount;
+	}
 
-    int16 findDirByID(uint id) const {
-        for (uint i = 0; i < _directories.size(); ++i) {
-            if (_directories[i].id == id)
-                return i;
-        }
+	int16 findDirByID(uint id) const {
+		for (uint i = 0; i < _directories.size(); ++i) {
+			if (_directories[i].id == id)
+				return i;
+		}
 
-        return -1;
-    }
+		return -1;
+	}
 
-    bool seekDir(uint id);
+	bool seekDir(uint id);
 
-    int32 readPackedInt();
+	int32 readPackedInt();
 
-    RawData *readCompressedData();
-    bool readCompressedData(RawData *out);
+	RawData *readCompressedData();
+	bool readCompressedData(RawData *out);
 
-    static void decompress(RawData const *in, RawData *out);
+	static void decompress(RawData const *in, RawData *out);
 
 public:
 
-uint32 _lastReadSize = 0;
-uint32 _lastReadDecompressedSize = 0;
-uint32 _lastReadDataOffset = 0;
+	uint32 _lastReadSize = 0;
+	uint32 _lastReadDecompressedSize = 0;
+	uint32 _lastReadDataOffset = 0;
 
 
 private:
-    int32 _dirOffset;
+	int32 _dirOffset;
 
-    byte _dirCount;
-    uint32 _dataOffset;
+	byte _dirCount;
+	uint32 _dataOffset;
 
-    Common::Array<ArchiveDir> _directories;
+	Common::Array<ArchiveDir> _directories;
 
 
-    bool _error;
+	bool _error;
 };
 
 
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 97ae7ce5515..05ee1b29b50 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -43,9 +43,10 @@ GamosEngine *g_engine;
 
 
 const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c,
-										 0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47,
-										 0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
-										 0x32, 0x57, 0xdd, 0xb2, 0x38, 0xa7, 0x95, 0x7a};
+                                         0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47,
+                                         0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
+                                         0x32, 0x57, 0xdd, 0xb2, 0x38, 0xa7, 0x95, 0x7a
+                                        };
 
 GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
 	_gameDescription(gameDesc), _randomSource("Gamos") {
@@ -240,8 +241,8 @@ bool GamosEngine::loader2() {
 }
 
 bool GamosEngine::loadModule(uint id) {
-	if ( (!_runReadDataMod && !writeStateFile()) ||
-	     !_arch.seekDir(1) )
+	if ((!_runReadDataMod && !writeStateFile()) ||
+	        !_arch.seekDir(1))
 		return false;
 
 	_currentModuleID = id;
@@ -273,132 +274,132 @@ bool GamosEngine::loadModule(uint id) {
 	int32 p3 = 0;
 	int32 pid = 0;
 
-	while(doLoad) {
+	while (doLoad) {
 		byte curByte = _arch.readByte();
 
-		switch(curByte) {
-			case 0:
-				if (prefixLoaded) {
-					doLoad = false;
-					break;
-				}
+		switch (curByte) {
+		case 0:
+			if (prefixLoaded) {
+				doLoad = false;
+				break;
+			}
 
-				prefixLoaded = true;
+			prefixLoaded = true;
 
-				if (!_arch.seekDir(targetDir))
-					return false;
+			if (!_arch.seekDir(targetDir))
+				return false;
 
-				break;
-			case CONFTP_P1:
-				p1 = _arch.readPackedInt();
-				break;
-			case CONFTP_P2:
-				p2 = _arch.readPackedInt();
-				break;
-			case CONFTP_P3:
-				p3 = _arch.readPackedInt();
-				break;
-			case 4: {
-				_resReadOffset = _arch.pos();
-				bool isResource = true;
-				if (prevByte == RESTP_F) {
-					RawData data;
-					if (!_arch.readCompressedData(&data))
-						return false;
-					if (_runReadDataMod && BYTE_004177f7 == 0)
-						readData2(data);
-					if (BYTE_004177f7 == 0) {
-						//FUN_00403868();
-					}
-					isResource = false; /* do not loadResHandler */
-				} else if (prevByte == RESTP_10) {
-					if (!initMainDatas())
-						return false;
-					isResource = false; /* do not loadResHandler */
-				} else if (prevByte == RESTP_11) {
-					RawData data;
-					if (!_arch.readCompressedData(&data))
-						return false;
-					if (pid == id)
-						readElementsConfig(data);
-					isResource = false; /* do not loadResHandler */
-				} else if (prevByte == RESTP_18) {
-					/* free elements ? */
-					_readingBkgOffset = _arch.pos();
+			break;
+		case CONFTP_P1:
+			p1 = _arch.readPackedInt();
+			break;
+		case CONFTP_P2:
+			p2 = _arch.readPackedInt();
+			break;
+		case CONFTP_P3:
+			p3 = _arch.readPackedInt();
+			break;
+		case 4: {
+			_resReadOffset = _arch.pos();
+			bool isResource = true;
+			if (prevByte == RESTP_F) {
+				RawData data;
+				if (!_arch.readCompressedData(&data))
+					return false;
+				if (_runReadDataMod && BYTE_004177f7 == 0)
+					readData2(data);
+				if (BYTE_004177f7 == 0) {
+					//FUN_00403868();
 				}
-
+				isResource = false; /* do not loadResHandler */
+			} else if (prevByte == RESTP_10) {
+				if (!initMainDatas())
+					return false;
+				isResource = false; /* do not loadResHandler */
+			} else if (prevByte == RESTP_11) {
 				RawData data;
-				if (isResource) {
-					if (!_arch.readCompressedData(&data))
-						return false;
+				if (!_arch.readCompressedData(&data))
+					return false;
+				if (pid == id)
+					readElementsConfig(data);
+				isResource = false; /* do not loadResHandler */
+			} else if (prevByte == RESTP_18) {
+				/* free elements ? */
+				_readingBkgOffset = _arch.pos();
+			}
 
-					if (!loadResHandler(prevByte, pid, p1, p2, p3, data))
-						return false;
+			RawData data;
+			if (isResource) {
+				if (!_arch.readCompressedData(&data))
+					return false;
 
-				}
+				if (!loadResHandler(prevByte, pid, p1, p2, p3, data))
+					return false;
 
-				uint32 datasz = (data.size() + 3) & (~3);
+			}
 
-				switch (prevByte) {
-					case RESTP_11:
-					case RESTP_18:
-					case RESTP_19:
-					case RESTP_20:
-					case RESTP_40:
-					case RESTP_50:
-						break;
+			uint32 datasz = (data.size() + 3) & (~3);
 
-					case RESTP_43:
-						//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
-						if (_onlyScanImage)
-							_loadedDataSize += 0x10;
-						else
-							_loadedDataSize += datasz;
-						break;
+			switch (prevByte) {
+			case RESTP_11:
+			case RESTP_18:
+			case RESTP_19:
+			case RESTP_20:
+			case RESTP_40:
+			case RESTP_50:
+				break;
 
-					default:
-						//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
-						_loadedDataSize += datasz;
-						break;
-				}
+			case RESTP_43:
+				//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
+				if (_onlyScanImage)
+					_loadedDataSize += 0x10;
+				else
+					_loadedDataSize += datasz;
+				break;
 
+			default:
+				//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
+				_loadedDataSize += datasz;
 				break;
 			}
-			case 5: {
-				byte t = _arch.readByte();
-				if (t == 0 || (t & 0xec) != 0xec)
-					return false;
 
-				byte sz = (t & 3) + 1;
-				int32 movieSize = 0;
-				for(uint i = 0; i < sz; ++i)
-					movieSize |= _arch.readByte() << (i * 8);
+			break;
+		}
+		case 5: {
+			byte t = _arch.readByte();
+			if (t == 0 || (t & 0xec) != 0xec)
+				return false;
 
-				if (prevByte == 0x14)
-					_movieOffsets[pid] = _arch.pos();
+			byte sz = (t & 3) + 1;
+			int32 movieSize = 0;
+			for (uint i = 0; i < sz; ++i)
+				movieSize |= _arch.readByte() << (i * 8);
 
-				_arch.skip(movieSize);
-				break;
-			}
-			case 6:
-				if (!loader2())
-					return false;
-				break;
-			case 0xFF:
-				if (!reuseLastResource(prevByte, pid, p1, p2, 0))
-					return false;
-				break;
-			default:
-				p1 = 0;
-				p2 = 0;
-				p3 = 0;
-				pid = 0;
-				prevByte = curByte & CONFTP_RESMASK;
+			if (prevByte == 0x14)
+				_movieOffsets[pid] = _arch.pos();
+
+			_arch.skip(movieSize);
+			break;
+		}
+		case 6:
+			if (!loader2())
+				return false;
+			break;
+		case 0xFF:
+			if (!reuseLastResource(prevByte, pid, p1, p2, 0))
+				return false;
+			break;
+		default:
+			p1 = 0;
+			p2 = 0;
+			p3 = 0;
+			pid = 0;
+			prevByte = curByte & CONFTP_RESMASK;
 
-				if ( (curByte & CONFTP_IDFLG) == 0 )
-					pid = _arch.readPackedInt();
+			if ((curByte & CONFTP_IDFLG) == 0)
+				pid = _arch.readPackedInt();
 
-				break;
+			break;
 		}
 	}
 
@@ -416,7 +417,7 @@ bool GamosEngine::loadModule(uint id) {
 	if (bkg == -1)
 		bkg = 0;
 
-	if ( !switchToGameScreen(bkg, false) )
+	if (!switchToGameScreen(bkg, false))
 		return false;
 
 	return true;
@@ -432,12 +433,12 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		_addrKeyCode = _loadedDataSize + 3;
 		_addrCurrentFrame = _loadedDataSize + 4;
 
-		VM::memory().setU8( _addrBlk12, dataStream.readByte() );
+		VM::memory().setU8(_addrBlk12, dataStream.readByte());
 		dataStream.skip(1);
-		VM::memory().setU8( _addrFPS, _fps );
-		VM::memory().setU8( _addrKeyDown, dataStream.readByte() );
-		VM::memory().setU8( _addrKeyCode, dataStream.readByte() );
-		VM::memory().setU32( _addrCurrentFrame, dataStream.readUint32LE() );
+		VM::memory().setU8(_addrFPS, _fps);
+		VM::memory().setU8(_addrKeyDown, dataStream.readByte());
+		VM::memory().setU8(_addrKeyCode, dataStream.readByte());
+		VM::memory().setU32(_addrCurrentFrame, dataStream.readUint32LE());
 
 		setFPS(_fps);
 	} else if (tp == RESTP_13) {
@@ -633,7 +634,7 @@ bool GamosEngine::loadInitModule() {
 	//DAT_0041723c = -1;
 	_curObjIndex = -1;
 	PTR_00417218 = nullptr;
-    PTR_00417214 = nullptr;
+	PTR_00417214 = nullptr;
 	//DAT_00417238 = 0;
 	_xorSeq[2].clear();
 	_xorSeq[1].clear();
@@ -678,7 +679,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	uint32 dat6xCount = dataStream.readUint32LE(); // 30
 
 	_statesShift = 2;
-	for(int i = 2; i < 9; i++) {
+	for (int i = 2; i < 9; i++) {
 		if (_statesWidth <= (1 << i)) {
 			_statesShift = i;
 			break;
@@ -734,7 +735,7 @@ void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
 	uint32 num = dataStream.readUint32LE();
 	seq.resize(num);
 
-	for(uint i = 0; i < num; ++i) {
+	for (uint i = 0; i < num; ++i) {
 		seq[i].pos = dataStream.readUint32LE();
 		seq[i].len = dataStream.readUint32LE();
 	}
@@ -774,11 +775,11 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 		_sprites[id].sequences.resize(1);
 
 	int32 count = dataSize / 8;
-	_imgSeq.push_back( new ImageSeq(count) );
+	_imgSeq.push_back(new ImageSeq(count));
 	_sprites[id].sequences[p1] = _imgSeq.back();
 
 	Common::MemoryReadStream strm(data, dataSize);
-	for(int i = 0; i < count; ++i) {
+	for (int i = 0; i < count; ++i) {
 		int32 dataz = strm.readSint32LE();
 		if (dataz != 0) {
 			error("42    nut null");
@@ -792,7 +793,7 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 }
 
 bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize) {
-	_images.push_back( new Image() );
+	_images.push_back(new Image());
 	_sprites[id].sequences[p1]->operator[](p2).image = _images.back();
 
 	Image *img = _sprites[id].sequences[p1]->operator[](p2).image;
@@ -846,7 +847,7 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 
 	Common::MemoryReadStream strm(data, dataSize);
 
-	if (_readingBkgMainId == -1 && (strm.readUint32LE() & 0x80000000) )
+	if (_readingBkgMainId == -1 && (strm.readUint32LE() & 0x80000000))
 		_readingBkgMainId = id;
 
 	//warning("res 18 id %d 4: %x", id, strm.readUint32LE());
@@ -929,7 +930,8 @@ void GamosEngine::updateScreen(bool checkers, const Common::Rect &rect) {
 		{0, 0}, {16, 32}, {48, 16}, {16, 48},
 		{0, 32}, {32, 48}, {16, 16}, {48, 0},
 		{32, 32}, {0, 48}, {32, 16}, {16, 0},
-		{48, 32}, {32, 0}, {0, 16}, {48, 48}};
+		{48, 32}, {32, 0}, {0, 16}, {48, 48}
+	};
 
 	/* 0.4sec */
 	const int16 maxDelay = (400 / 16) - 1;
@@ -954,7 +956,7 @@ void GamosEngine::updateScreen(bool checkers, const Common::Rect &rect) {
 
 void GamosEngine::flushDirtyRects(bool apply) {
 	if (apply) {
-		for(const Common::Rect &r : _dirtyRects) {
+		for (const Common::Rect &r : _dirtyRects) {
 			updateScreen(false, r);
 		}
 	}
@@ -974,33 +976,34 @@ void GamosEngine::flushDirtyRects(bool apply) {
 bool GamosEngine::usePalette(byte *pal, int num, int fade, bool winColors) {
 
 	static const byte winColorMap[20][3] = {
-	/* r     g     b */
-	{ 0x00, 0x00, 0x00 },
-	{ 0x80, 0x00, 0x00 },
-	{ 0x00, 0x80, 0x00 },
-	{ 0x80, 0x80, 0x00 },
-	{ 0x00, 0x00, 0x80 },
-	{ 0x80, 0x00, 0x80 },
-	{ 0x00, 0x80, 0x80 },
-	{ 0xc0, 0xc0, 0xc0 },
-	{ 0xc0, 0xdc, 0xc0 },
-	{ 0xa6, 0xca, 0xf0 },
-
-	{ 0xff, 0xfb, 0xf0 },
-	{ 0xa0, 0xa0, 0xa4 },
-	{ 0x80, 0x80, 0x80 },
-	{ 0xff, 0x00, 0x00 },
-	{ 0x00, 0xff, 0x00 },
-	{ 0xff, 0xff, 0x00 },
-	{ 0x00, 0x00, 0xff },
-	{ 0xff, 0x00, 0xff },
-	{ 0x00, 0xff, 0xff },
-	{ 0xff, 0xff, 0xff } };
+		/* r     g     b */
+		{ 0x00, 0x00, 0x00 },
+		{ 0x80, 0x00, 0x00 },
+		{ 0x00, 0x80, 0x00 },
+		{ 0x80, 0x80, 0x00 },
+		{ 0x00, 0x00, 0x80 },
+		{ 0x80, 0x00, 0x80 },
+		{ 0x00, 0x80, 0x80 },
+		{ 0xc0, 0xc0, 0xc0 },
+		{ 0xc0, 0xdc, 0xc0 },
+		{ 0xa6, 0xca, 0xf0 },
+
+		{ 0xff, 0xfb, 0xf0 },
+		{ 0xa0, 0xa0, 0xa4 },
+		{ 0x80, 0x80, 0x80 },
+		{ 0xff, 0x00, 0x00 },
+		{ 0x00, 0xff, 0x00 },
+		{ 0xff, 0xff, 0x00 },
+		{ 0x00, 0x00, 0xff },
+		{ 0xff, 0x00, 0xff },
+		{ 0x00, 0xff, 0xff },
+		{ 0xff, 0xff, 0xff }
+	};
 
 	if (!pal)
 		return false;
 
-	if (_width != 0 && _height !=0) {
+	if (_width != 0 && _height != 0) {
 		if (fade == 0) {
 			uint16 color = _screen->getPalette().findBestColor(0, 0, 0);
 			_screen->fillRect(_screen->getBounds(), color);
@@ -1057,7 +1060,7 @@ bool GamosEngine::setPaletteCurrentGS() {
 	if (curGS == -1)
 		curGS = 0;
 
-	if (!usePalette(_gameScreens[curGS].palette, 256, _currentFade, true) )
+	if (!usePalette(_gameScreens[curGS].palette, 256, _currentFade, true))
 		return false;
 
 	addDirtyRect(Common::Rect(_bkgUpdateSizes.x, _bkgUpdateSizes.y));
@@ -1165,12 +1168,12 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
 
-	if ( FUN_00402bc4() ) {
+	if (FUN_00402bc4()) {
 		bool loop = false;
 		if (!DAT_00417802)
 			loop = FUN_00402fb4();
 		/*else
-			loop = FUN_00403314(_messageProc._act2);*/
+		    loop = FUN_00403314(_messageProc._act2);*/
 
 		if (_needReload)
 			return 2;  // rerun update after loadModule
@@ -1191,7 +1194,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 			if (!DAT_00417802)
 				loop = FUN_00402fb4();
 			/*else
-				loop = FUN_00403314(_messageProc._act2);*/
+			    loop = FUN_00403314(_messageProc._act2);*/
 
 			if (_needReload)
 				return 2; // rerun update after loadModule
@@ -1237,7 +1240,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 
 	if (a.flags & Actions::HAS_ACT2) {
 		bool fastSkipAll = false;
-		for(const ActTypeEntry &ate : a.act_2) {
+		for (const ActTypeEntry &ate : a.act_2) {
 
 			if (ate.t == 4) {
 				spos++;
@@ -1266,7 +1269,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 					Common::Point xy;
 					xy.x = (e.x + DAT_00417220 + _statesWidth) % _statesWidth;
 					xy.y = (e.y + DAT_00417224 + _statesHeight) % _statesHeight;
-					fb = _states.at( xy );
+					fb = _states.at(xy);
 				} else {
 					fb = _states.at(e.x, e.y);
 				}
@@ -1281,7 +1284,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 						cval = 2;
 					}
 				} else if (lb != 0xfe &&
-					       (_thing2[e.value].field_0[(fb & 0xff) >> 3] & (1 << (fb & 7))) != 0) {
+				           (_thing2[e.value].field_0[(fb & 0xff) >> 3] & (1 << (fb & 7))) != 0) {
 
 					if (!_thing2[e.value].field_2.empty()) {
 						e.t = _thing2[e.value].field_2[lb] >> 4;
@@ -1305,7 +1308,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 					}
 					ARR_00412208[ sbuf[ps] ] = Common::Point(e.x, e.y);
 					sbuf[ps]++;
-				} else if ( (ate.entries.size() - i) == 1 && spos > -1 && sbuf[spos * 2] == sbuf[ps]) {
+				} else if ((ate.entries.size() - i) == 1 && spos > -1 && sbuf[spos * 2] == sbuf[ps]) {
 					return 0;
 				}
 			}
@@ -1335,7 +1338,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 		if (_needReload)
 			return 0;
 		if (BYTE_004177fc == 0 && BYTE_00412200 == 0 && PTR_00417218 && PTR_00417218->fld_5 != fldsv && PTR_00417218->y != -1)
-			addDirtRectOnObject( &_objects[PTR_00417218->y] );
+			addDirtRectOnObject(&_objects[PTR_00417218->y]);
 	}
 
 	if (BYTE_004177fc == 0 && BYTE_00412200 != 0)
@@ -1345,9 +1348,8 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 
 	if (a.flags & Actions::HAS_ACT10) {
 		int ivar5 = -1;
-		for(const ActTypeEntry &ate : a.act_10) {
-			switch (ate.t)
-			{
+		for (const ActTypeEntry &ate : a.act_10) {
+			switch (ate.t) {
 			case 0: {
 				uint16 rndval = rndRange16(a.num_act_10e);
 				rnd();
@@ -1356,7 +1358,8 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 					if (_needReload)
 						return 0;
 				}
-			} break;
+			}
+			break;
 
 			case 1: {
 				int32 num = rndRange16(ate.entries.size());
@@ -1370,15 +1373,17 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 					num--;
 				}
 
-			} break;
+			}
+			break;
 
 			case 2: {
 				int32 num = rndRange16(ate.entries.size());
 				ActEntry e = ate.entries[num];
 				retval += processData(e, absolute);
 				if (_needReload)
-						return 0;
-			} break;
+					return 0;
+			}
+			break;
 
 			case 3: {
 				for (int i = 0; i < ate.entries.size(); i++) {
@@ -1391,7 +1396,8 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 							return 0;
 					}
 				}
-			} break;
+			}
+			break;
 
 			default: {
 				ivar5++;
@@ -1404,14 +1410,15 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 				Common::Point point = ARR_00412208[ idx ];
 
 				for (ActEntry e : ate.entries) {
-					if ( Common::Point(e.x, e.y) == point ) {
+					if (Common::Point(e.x, e.y) == point) {
 						retval += processData(e, absolute);
 						if (_needReload)
 							return 0;
 						break;
 					}
 				}
-			} break;
+			}
+			break;
 
 			}
 		}
@@ -1440,7 +1447,8 @@ void GamosEngine::preprocessData(int id, ActEntry *e) {
 		e->y = e->x;
 		e->x = -tmp;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 
 	case 2:
 	case 12: {
@@ -1448,7 +1456,8 @@ void GamosEngine::preprocessData(int id, ActEntry *e) {
 		e->y = -e->y;
 		e->x = -e->x;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 
 	case 3:
 	case 16: {
@@ -1457,13 +1466,15 @@ void GamosEngine::preprocessData(int id, ActEntry *e) {
 		e->x = e->y;
 		e->y = -tmp;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 
 	case 4: {
 		static const uint8 lookup[16] = {0, 1, 8, 9, 4, 5, 12, 13, 2, 3, 10, 11, 6, 7, 14, 15};
 		e->x = -e->x;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 
 	case 5: {
 		static const uint8 lookup[16] = {0, 2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15};
@@ -1471,13 +1482,15 @@ void GamosEngine::preprocessData(int id, ActEntry *e) {
 		e->x = -e->y;
 		e->y = -tmp;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 
 	case 6: {
 		static const uint8 lookup[16] = {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
 		e->y = -e->y;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 
 	case 7: {
 		static const uint8 lookup[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
@@ -1485,78 +1498,90 @@ void GamosEngine::preprocessData(int id, ActEntry *e) {
 		e->x = e->y;
 		e->y = tmp;
 		e->t = lookup[ e->t ];
-	} break;
+	}
+	break;
 	}
 }
 
 void GamosEngine::preprocessDataB1(int id, ActEntry *e) {
 	switch (id) {
 
-		default:
-		case 0:
-			break;
+	default:
+	case 0:
+		break;
 
-		case 1:
-		case 2:
-		case 4:
-		case 8:
-			//e->t = e->t;
-			break;
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		//e->t = e->t;
+		break;
 
-		case 3: {
-			static const uint8 lookup[2] = {1, 2};
-			e->t = lookup[rndRange16(2)];
-		} break;
+	case 3: {
+		static const uint8 lookup[2] = {1, 2};
+		e->t = lookup[rndRange16(2)];
+	}
+	break;
 
-		case 5: {
-			static const uint8 lookup[2] = {1, 4};
-			e->t = lookup[rndRange16(2)];
-		} break;
+	case 5: {
+		static const uint8 lookup[2] = {1, 4};
+		e->t = lookup[rndRange16(2)];
+	}
+	break;
 
-		case 6: {
-			static const uint8 lookup[2] = {2, 4};
-			e->t = lookup[rndRange16(2)];
-		} break;
+	case 6: {
+		static const uint8 lookup[2] = {2, 4};
+		e->t = lookup[rndRange16(2)];
+	}
+	break;
 
-		case 7: {
-			static const uint8 lookup[3] = {1, 2, 4};
-			e->t = lookup[rndRange16(3)];
-		} break;
+	case 7: {
+		static const uint8 lookup[3] = {1, 2, 4};
+		e->t = lookup[rndRange16(3)];
+	}
+	break;
 
-		case 9: {
-			static const uint8 lookup[2] = {1, 8};
-			e->t = lookup[rndRange16(2)];
-		} break;
+	case 9: {
+		static const uint8 lookup[2] = {1, 8};
+		e->t = lookup[rndRange16(2)];
+	}
+	break;
 
-		case 0xa: {
-			static const uint8 lookup[2] = {2, 8};
-			e->t = lookup[rndRange16(2)];
-		} break;
+	case 0xa: {
+		static const uint8 lookup[2] = {2, 8};
+		e->t = lookup[rndRange16(2)];
+	}
+	break;
 
-		case 0xb: {
-			static const uint8 lookup[3] = {1, 2, 8};
-			e->t = lookup[rndRange16(3)];
-		} break;
+	case 0xb: {
+		static const uint8 lookup[3] = {1, 2, 8};
+		e->t = lookup[rndRange16(3)];
+	}
+	break;
 
-		case 0xc: {
-			static const uint8 lookup[2] = {4, 8};
-			e->t = lookup[rndRange16(2)];
-		} break;
+	case 0xc: {
+		static const uint8 lookup[2] = {4, 8};
+		e->t = lookup[rndRange16(2)];
+	}
+	break;
 
-		case 0xd: {
-			static const uint8 lookup[3] = {1, 4, 8};
-			e->t = lookup[rndRange16(3)];
-		} break;
+	case 0xd: {
+		static const uint8 lookup[3] = {1, 4, 8};
+		e->t = lookup[rndRange16(3)];
+	}
+	break;
 
-		case 0xe: {
-			static const uint8 lookup[3] = {2, 4, 8};
-			e->t = lookup[rndRange16(3)];
-		} break;
+	case 0xe: {
+		static const uint8 lookup[3] = {2, 4, 8};
+		e->t = lookup[rndRange16(3)];
+	}
+	break;
 
-		case 0xf: {
-			static const uint8 lookup[4] = {1, 2, 4, 8};
-			e->t = lookup[rndRange16(4)];
-		} break;
+	case 0xf: {
+		static const uint8 lookup[4] = {1, 2, 4, 8};
+		e->t = lookup[rndRange16(4)];
+	}
+	break;
 	}
 }
 
@@ -1564,8 +1589,8 @@ int GamosEngine::processData(ActEntry e, bool absolute) {
 	preprocessData(_preprocDataId, &e);
 	if (!absolute) {
 		FUN_0040283c(e,
-					 (e.x + DAT_00417220 + _statesWidth) % _statesWidth,
-					 (e.y + DAT_00417224 + _statesHeight) % _statesHeight );
+		             (e.x + DAT_00417220 + _statesWidth) % _statesWidth,
+		             (e.y + DAT_00417224 + _statesHeight) % _statesHeight);
 		if (_needReload)
 			return 0;
 		return e.x == 0 && e.y == 0;
@@ -1582,32 +1607,32 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
 
 		uint8 t = PTR_00417218->fld_3;
 
-        _states.at(DAT_00417228, DAT_0041722c) = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
+		_states.at(DAT_00417228, DAT_0041722c) = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
 
-        FUN_00402654(0, DAT_00417224, DAT_00417220);
+		FUN_00402654(0, DAT_00417224, DAT_00417220);
 
-        PTR_00417218->pos = DAT_00417220;
-        PTR_00417218->blk = DAT_00417224;
+		PTR_00417218->pos = DAT_00417220;
+		PTR_00417218->blk = DAT_00417224;
 
-        uint16 &rthing = _states.at(DAT_00417220, DAT_00417224);
+		uint16 &rthing = _states.at(DAT_00417220, DAT_00417224);
 
-        PTR_00417218->fld_2 = rthing & 0xff;
-        PTR_00417218->fld_3 = (t & 0xf) | ((rthing >> 8) & 0xf0);
+		PTR_00417218->fld_2 = rthing & 0xff;
+		PTR_00417218->fld_3 = (t & 0xf) | ((rthing >> 8) & 0xf0);
 
-        rthing = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
+		rthing = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
 
-        BYTE_00412200 = 1;
+		BYTE_00412200 = 1;
 	}
 
 	if (e.t != BYTE_004177f6) {
-        BYTE_004177f6 = e.t;
-        PTR_00417218->flags = (PTR_00417218->flags & 0xf) | (e.t << 4);
+		BYTE_004177f6 = e.t;
+		PTR_00417218->flags = (PTR_00417218->flags & 0xf) | (e.t << 4);
 
 		uint16 &tref = _states.at(DAT_00417220, DAT_00417224);
 		tref = (tref & 0xff) | (BYTE_004177f6 << 12);
 
-        BYTE_00412200 = 1;
-    }
+		BYTE_00412200 = 1;
+	}
 }
 
 void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
@@ -1626,7 +1651,7 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 		}
 	} else {
 		Unknown1 &unk1 = _thing2[ oid ];
-		uint8 index = rndRange16( unk1.field_1[0] );
+		uint8 index = rndRange16(unk1.field_1[0]);
 		oid = unk1.field_1[ index + 1 ];
 		if (!unk1.field_2.empty()) {
 			byte id1 = e.t;
@@ -1667,18 +1692,18 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 		obj->x = -1;
 		obj->y = -1;
 		obj->fld_2 = rthing & 0xff;
-		obj->fld_3 = (rthing >> 8 ) & 0xff;
+		obj->fld_3 = (rthing >> 8) & 0xff;
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
 			obj->fld_3 |= 1;
 
 		int storageSize = ((act.unk1 >> 24) & 0xff) + 1;
 		// if (storageSize < 5) {
-		// 	obj->pImg = nullptr;
-		// 	odat = &obj->pImg;
+		//  obj->pImg = nullptr;
+		//  odat = &obj->pImg;
 		// } else {
-		// 	odat = malloc(storageSize);
-		// 	obj->pImg = (Sprite *)odat;
-		// 	obj->flags |= 8;
+		//  odat = malloc(storageSize);
+		//  obj->pImg = (Sprite *)odat;
+		//  obj->flags |= 8;
 		// }
 		obj->storage.clear();
 		obj->storage.resize(storageSize, 0);
@@ -1710,7 +1735,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	Object *povar4 = nullptr;
 	bool multidel = false;
 
-	for(uint i = 0; i < _objects.size(); i++) {
+	for (uint i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if (obj.flags & 1) {
 			if (obj.flags & 2) {
@@ -1719,7 +1744,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 					if (obj.y != obj.x)
 						removeObjectByIDMarkDirty(obj.x);
 					/* if (obj.flags & 8)
-						obj.storage.clear(); */
+					    obj.storage.clear(); */
 					removeSubtitles(&obj);
 					removeObject(&obj);
 					FUN_0040255c(&obj);
@@ -1731,7 +1756,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 				}
 			} else {
 				if (mode && obj.fld_4 == pos && obj.fld_5 == id &&
-					obj.pos == 0xff && obj.blk == 0xff && (obj.flags & 0x40) == 0) {
+				        obj.pos == 0xff && obj.blk == 0xff && (obj.flags & 0x40) == 0) {
 
 					removeObjectMarkDirty(&obj);
 					if (multidel)
@@ -1753,7 +1778,7 @@ Object *GamosEngine::getFreeObject() {
 	Object *obj = nullptr;
 	for (uint i = 0; i < _objects.size(); i++) {
 		Object &rObj = _objects[i];
-		if ( (rObj.flags & 1) == 0 ) {
+		if ((rObj.flags & 1) == 0) {
 			obj = &rObj;
 			break;
 		}
@@ -1786,14 +1811,14 @@ Object *GamosEngine::getFreeObject() {
 void GamosEngine::removeObject(Object *obj) {
 	obj->flags = 0;
 	/*if (&(_objects.back()) == obj) {
-		int32 lastindex = _objects.size() - 1;
-		for (int32 i = lastindex - 1; i >= 0; i--) {
-			if ( _objects[i].flags & 1 ) {
-				lastindex = i;
-				break;
-			}
-		}
-		_objects.resize(lastindex);
+	    int32 lastindex = _objects.size() - 1;
+	    for (int32 i = lastindex - 1; i >= 0; i--) {
+	        if ( _objects[i].flags & 1 ) {
+	            lastindex = i;
+	            break;
+	        }
+	    }
+	    _objects.resize(lastindex);
 	}*/
 }
 
@@ -1841,8 +1866,7 @@ void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage,
 	PTR_00417214 = sv9;
 }
 
-bool GamosEngine::FUN_00402fb4()
-{
+bool GamosEngine::FUN_00402fb4() {
 	if (_objects.empty())
 		return true;
 
@@ -1854,7 +1878,7 @@ bool GamosEngine::FUN_00402fb4()
 		pobj = &_objects[objIdx];
 
 		if ((pobj->flags & 3) == 3) {
-			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7))) ) {
+			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7)))) {
 				if (pobj->fld_3 & 1) {
 					pobj->fld_3 &= ~1;
 				} else {
@@ -1896,7 +1920,7 @@ bool GamosEngine::FUN_00402fb4()
 					PTR_004173e8 = pobj->storage.data();
 
 					DAT_00417804 = 0;
-					for ( Actions &scr: PTR_00417214->actions ) {
+					for (Actions &scr : PTR_00417214->actions) {
 						BYTE_004177f6 = PTR_00417218->flags >> 4;
 
 						int ivr8 = 0;
@@ -2058,7 +2082,7 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 	}
 
 	bool intersects = 0;
-	for(int i = 0; i < _dirtyRects.size(); i++) {
+	for (int i = 0; i < _dirtyRects.size(); i++) {
 		Common::Rect &r = _dirtyRects[i];
 		if (!rect.intersects(r))
 			continue;
@@ -2074,8 +2098,8 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 		return;
 	}
 
-	rerunCheck:
-	for(int i = _dirtyRects.size() - 2; i > 0; i--) {
+rerunCheck:
+	for (int i = _dirtyRects.size() - 2; i > 0; i--) {
 		for (int j = _dirtyRects.size() - 1; j > i; j--) {
 			Common::Rect &r1 = _dirtyRects[i];
 			Common::Rect &r2 = _dirtyRects[j];
@@ -2099,7 +2123,7 @@ void GamosEngine::doDraw() {
 	if (bkg == -1)
 		bkg = 0;
 
-	Common::Array<Object *> drawList( 1024 );//_drawElements.size(), 1024) );
+	Common::Array<Object *> drawList(1024);  //_drawElements.size(), 1024) );
 
 	int cnt = 0;
 	for (int i = 0; i < _objects.size(); i++) {
@@ -2143,12 +2167,12 @@ void GamosEngine::doDraw() {
 			_screen->addDirtyRect(r);
 	}
 
-	for(Object *o: drawList) {
+	for (Object *o : drawList) {
 		/*if (o->pImg && loadImage(o->pImg->image)) {
-			Common::Rect out(Common::Point(o->x, o->y), o->pImg->image->surface.w, o->pImg->image->surface.h);
-			out.clip(_screen->getBounds());
-			out.translate(-o->x, -o->y);
-			_screen->copyRectToSurfaceWithKey(o->pImg->image->surface, o->x+out.left, o->y+out.top, out, 0);
+		    Common::Rect out(Common::Point(o->x, o->y), o->pImg->image->surface.w, o->pImg->image->surface.h);
+		    out.clip(_screen->getBounds());
+		    out.translate(-o->x, -o->y);
+		    _screen->copyRectToSurfaceWithKey(o->pImg->image->surface, o->x+out.left, o->y+out.top, out, 0);
 		}*/
 		if (o->pImg && loadImage(o->pImg->image)) {
 			uint flip = 0;
@@ -2158,14 +2182,14 @@ void GamosEngine::doDraw() {
 				flip |= Graphics::FLIP_V;
 			if (o->flags & 0x40) {
 				Blitter::blit(&o->pImg->image->surface,
-					Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
-					_screen->surfacePtr(),
-					Common::Rect(o->x - o->pImg->xoffset, o->y - o->pImg->yoffset, _screen->w, _screen->h), flip);
+				              Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
+				              _screen->surfacePtr(),
+				              Common::Rect(o->x - o->pImg->xoffset, o->y - o->pImg->yoffset, _screen->w, _screen->h), flip);
 			} else {
 				Blitter::blit(&o->pImg->image->surface,
-					Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
-					_screen->surfacePtr(),
-					Common::Rect(o->x, o->y, o->x + o->pImg->image->surface.w, o->y + o->pImg->image->surface.h), flip);
+				              Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
+				              _screen->surfacePtr(),
+				              Common::Rect(o->x, o->y, o->x + o->pImg->image->surface.w, o->y + o->pImg->image->surface.h), flip);
 			}
 		}
 	}
@@ -2217,8 +2241,7 @@ uint32 GamosEngine::doScript(uint32 scriptAddress) {
 void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	uint32 arg1 = 0, arg2 = 0, arg3 = 0;
 
-	switch (funcID)
-	{
+	switch (funcID) {
 	case 0:
 		DAT_004177ff = true;
 		vm->EAX.val = 1;
@@ -2293,7 +2316,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			FUN_0040738c(d.sprId, d.x, d.y, true);
 		}
 		vm->EAX.val = savedDoActions(_subtitleActions[arg1]);
-	} break;
+	}
+	break;
 
 	case 24: {
 		VM::Reg regRef = vm->popReg();
@@ -2302,7 +2326,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		addSubtitles(vm, regRef.ref, regRef.val, d.sprId, d.x, d.y);
 
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 25: {
 		arg1 = vm->pop32();
@@ -2319,7 +2344,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			}
 		}
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 26:
 		removeSubtitles(PTR_00417218);
@@ -2338,7 +2364,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			PTR_00417218->y = -1;
 			removeObjectMarkDirty(obj);
 		}
-	} break;
+	}
+	break;
 
 	case 31:
 		arg1 = vm->pop32();
@@ -2360,13 +2387,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		VM::Reg regRef = vm->popReg();
 		vm->setMem8(regRef.ref, regRef.val, PTR_00417218->fld_5);
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 35:
 		arg1 = vm->pop32();
 
-		switch (arg1)
-		{
+		switch (arg1) {
 		case 3:
 			FUN_00408648(0xe, 0xff, 0xff);
 			break;
@@ -2413,8 +2440,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		arg1 = vm->pop32();
 		arg2 = vm->pop32();
 
-		switch (arg1)
-		{
+		switch (arg1) {
 		case 1:
 			FUN_00408648(0, arg2, 0xff);
 			break;
@@ -2506,7 +2532,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			}
 		}
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 43: {
 		arg1 = vm->pop32();
@@ -2518,7 +2545,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 44: {
 		arg1 = vm->pop32();
@@ -2530,7 +2558,8 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 45:
 		arg1 = vm->pop32();
@@ -2564,14 +2593,16 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		default:
 			break;
 		}
-	} break;
+	}
+	break;
 
 	case 49: {
 		arg1 = vm->pop32();
 		arg2 = vm->pop32();
 
 		warning("Do save-load %d %d", arg1, arg2);
-	} break;
+	}
+	break;
 
 	case 54:
 		arg1 = vm->pop32();
@@ -2583,14 +2614,16 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		Common::String str = vm->getString(regRef.ref, regRef.val);
 		warning("PlayMovie 55: %s", str.c_str());
 		vm->EAX.val = 1;
-	} break;
+	}
+	break;
 
 	case 57: {
 		VM::Reg regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef.ref, regRef.val);
 		warning("CallDispatcher 57 keycode %s", str.c_str());
 		vm->EAX.val = 0;
-	} break;
+	}
+	break;
 
 	default:
 		warning("Call Dispatcher %d", funcID);
@@ -2808,7 +2841,7 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 			if (robj.index > objIndex)
 				n++;
 
-			if ( (robj.flags & 3) == 3 && (_objectActions[robj.actID].unk1 & 0xff) == 3 ) {
+			if ((robj.flags & 3) == 3 && (_objectActions[robj.actID].unk1 & 0xff) == 3) {
 				if (n) {
 					PTR_004121b4 = &robj;
 					break;
@@ -2839,10 +2872,10 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 		_cursorObject.pImg = &_sprites[id].sequences[0]->operator[](0);
 
 		_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(),
-								 _cursorObject.pImg->image->surface.w,
-								 _cursorObject.pImg->image->surface.h,
-								 _cursorObject.pImg->xoffset,
-								 _cursorObject.pImg->yoffset, 0);
+		                        _cursorObject.pImg->image->surface.w,
+		                        _cursorObject.pImg->image->surface.h,
+		                        _cursorObject.pImg->xoffset,
+		                        _cursorObject.pImg->yoffset, 0);
 	}
 }
 
@@ -2878,7 +2911,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	uint8 actT = 0;
 	uint8 pobjF5 = 0xff;
 
-	for(int i = 0; i < _objects.size(); i++) {
+	for (int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if ((obj.flags & 3) == 3) {
 			ObjectAction &action = _objectActions[obj.actID];
@@ -3011,7 +3044,7 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 
 					warning("addSubtitles unimplemented part");
 
-					switch( flg & 7 ) {
+					switch (flg & 7) {
 					case 0:
 						break;
 
@@ -3095,8 +3128,7 @@ bool GamosEngine::FUN_00402bc4() {
 	return true;
 }
 
-void GamosEngine::FUN_00407db8(uint8 p)
-{
+void GamosEngine::FUN_00407db8(uint8 p) {
 	if ((p == 0x82) || (p == 0x83)) {
 		DAT_00412c94 = DAT_004173fc;
 		DAT_00412c98 = DAT_004173f8;
@@ -3201,7 +3233,7 @@ void GamosEngine::FUN_004085d8(uint8 p) {
 void GamosEngine::FUN_0040841c(bool p) {
 	_pathMap.at(DAT_00412c8c, DAT_00412c90) = 6;
 
-	while(true) {
+	while (true) {
 		byte res = FUN_004081b8(6, 4);
 		if (res == 0)
 			break;
@@ -3237,8 +3269,7 @@ void GamosEngine::FUN_0040841c(bool p) {
 	}
 }
 
-byte GamosEngine::FUN_00407e2c()
-{
+byte GamosEngine::FUN_00407e2c() {
 	int32 iVar2 = DAT_00412c8c - DAT_00412c94;
 	if (iVar2 < 1)
 		iVar2 = -iVar2;
@@ -3405,19 +3436,19 @@ byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
 	for (int32 y = 0; y < _statesHeight; y++) {
 		for (int32 x = 0; x < _statesWidth; x++) {
 			uint8 &rval = _pathMap.at(x, y);
-			if ( rval == 0) {
-				if ( (x > 0 && _pathMap.at(x - 1, y) == cv) ||
-					(x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
-					(y > 0 && _pathMap.at(x, y - 1) == cv) ||
-					(y < _pathBottom && _pathMap.at(x, y + 1) == cv) ) {
+			if (rval == 0) {
+				if ((x > 0 && _pathMap.at(x - 1, y) == cv) ||
+				        (x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
+				        (y > 0 && _pathMap.at(x, y - 1) == cv) ||
+				        (y < _pathBottom && _pathMap.at(x, y + 1) == cv)) {
 					ret = sv;
 					rval = sv;
 				}
 			} else if (rval == 2) {
-				if ( (x > 0 && _pathMap.at(x - 1, y) == cv) ||
-					(x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
-					(y > 0 && _pathMap.at(x, y - 1) == cv) ||
-					(y < _pathBottom && _pathMap.at(x, y + 1) == cv) ) {
+				if ((x > 0 && _pathMap.at(x - 1, y) == cv) ||
+				        (x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
+				        (y > 0 && _pathMap.at(x, y - 1) == cv) ||
+				        (y < _pathBottom && _pathMap.at(x, y + 1) == cv)) {
 					DAT_00412c94 = x;
 					DAT_00412c98 = y;
 					return 1;
@@ -3541,12 +3572,12 @@ void GamosEngine::FUN_004025d0() {
 		ObjectAction &act = _objectActions[PTR_00417218->fld_2];
 		PTR_00417218->pos;
 
-		for(int i = 0; i < _objects.size(); i++) {
+		for (int i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];
-			if ( (obj.flags & 0xC1) == 0x81 &&
-			     obj.pos == 0xff && obj.blk == 0xff &&
-				 obj.fld_4 == PTR_00417218->pos &&
-				 obj.fld_5 == PTR_00417218->blk ) {
+			if ((obj.flags & 0xC1) == 0x81 &&
+			        obj.pos == 0xff && obj.blk == 0xff &&
+			        obj.fld_4 == PTR_00417218->pos &&
+			        obj.fld_5 == PTR_00417218->blk) {
 
 				removeObjectMarkDirty(&obj);
 				break;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 541aa5b92a2..4994df92ecc 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -240,7 +240,7 @@ struct GameScreen {
 };
 
 class GamosEngine : public Engine {
-friend class MoviePlayer;
+	friend class MoviePlayer;
 
 private:
 	const GamosGameDescription *_gameDescription;
diff --git a/engines/gamos/keycodes.cpp b/engines/gamos/keycodes.cpp
index 58e65b92114..850a4aa48ab 100644
--- a/engines/gamos/keycodes.cpp
+++ b/engines/gamos/keycodes.cpp
@@ -25,272 +25,272 @@ namespace Gamos {
 KeyCodes KeyCodes::_instance;
 
 KeyCodes::KeyCodes() {
-    for (int16 i = 0; i < Common::KEYCODE_LAST; i++) {
-        _winCodes[i] = WIN_INVALID;
-    }
+	for (int16 i = 0; i < Common::KEYCODE_LAST; i++) {
+		_winCodes[i] = WIN_INVALID;
+	}
 
-    for (int i = 0; i < 256; i++) {
-        _scummCodes[i] = Common::KEYCODE_INVALID;
-    }
+	for (int i = 0; i < 256; i++) {
+		_scummCodes[i] = Common::KEYCODE_INVALID;
+	}
 
-    _winCodes[Common::KEYCODE_BACKSPACE] = WIN_BACK;
-    _winCodes[Common::KEYCODE_TAB] = WIN_TAB;
-    _winCodes[Common::KEYCODE_CLEAR] = WIN_CLEAR;
-    _winCodes[Common::KEYCODE_RETURN] = WIN_RETURN;
-    _winCodes[Common::KEYCODE_PAUSE] = WIN_PAUSE;
-    _winCodes[Common::KEYCODE_ESCAPE] = WIN_ESCAPE;
-    _winCodes[Common::KEYCODE_SPACE] = WIN_SPACE;
-    _winCodes[Common::KEYCODE_QUOTE] = WIN_OEM_7;
-    _winCodes[Common::KEYCODE_COMMA] = WIN_OEM_COMMA;
-    _winCodes[Common::KEYCODE_MINUS] = WIN_OEM_MINUS;
-    _winCodes[Common::KEYCODE_PERIOD] = WIN_OEM_PERIOD;
-    _winCodes[Common::KEYCODE_SLASH] = WIN_OEM_2;
-    _winCodes[Common::KEYCODE_0] = WIN_0;
-    _winCodes[Common::KEYCODE_1] = WIN_1;
-    _winCodes[Common::KEYCODE_2] = WIN_2;
-    _winCodes[Common::KEYCODE_3] = WIN_3;
-    _winCodes[Common::KEYCODE_4] = WIN_4;
-    _winCodes[Common::KEYCODE_5] = WIN_5;
-    _winCodes[Common::KEYCODE_6] = WIN_6;
-    _winCodes[Common::KEYCODE_7] = WIN_7;
-    _winCodes[Common::KEYCODE_8] = WIN_8;
-    _winCodes[Common::KEYCODE_9] = WIN_9;
-    _winCodes[Common::KEYCODE_SEMICOLON] = WIN_OEM_1;
-    _winCodes[Common::KEYCODE_EQUALS] = WIN_OEM_PLUS;
-    _winCodes[Common::KEYCODE_LEFTBRACKET] = WIN_OEM_4;
-    _winCodes[Common::KEYCODE_BACKSLASH] = WIN_OEM_5;
-    _winCodes[Common::KEYCODE_RIGHTBRACKET] = WIN_OEM_6;
-    _winCodes[Common::KEYCODE_BACKQUOTE] = WIN_OEM_3;
-    _winCodes[Common::KEYCODE_a] = WIN_A;
-    _winCodes[Common::KEYCODE_b] = WIN_B;
-    _winCodes[Common::KEYCODE_c] = WIN_C;
-    _winCodes[Common::KEYCODE_d] = WIN_D;
-    _winCodes[Common::KEYCODE_e] = WIN_E;
-    _winCodes[Common::KEYCODE_f] = WIN_F;
-    _winCodes[Common::KEYCODE_g] = WIN_G;
-    _winCodes[Common::KEYCODE_h] = WIN_H;
-    _winCodes[Common::KEYCODE_i] = WIN_I;
-    _winCodes[Common::KEYCODE_j] = WIN_J;
-    _winCodes[Common::KEYCODE_k] = WIN_K;
-    _winCodes[Common::KEYCODE_l] = WIN_L;
-    _winCodes[Common::KEYCODE_m] = WIN_M;
-    _winCodes[Common::KEYCODE_n] = WIN_N;
-    _winCodes[Common::KEYCODE_o] = WIN_O;
-    _winCodes[Common::KEYCODE_p] = WIN_P;
-    _winCodes[Common::KEYCODE_q] = WIN_Q;
-    _winCodes[Common::KEYCODE_r] = WIN_R;
-    _winCodes[Common::KEYCODE_s] = WIN_S;
-    _winCodes[Common::KEYCODE_t] = WIN_T;
-    _winCodes[Common::KEYCODE_u] = WIN_U;
-    _winCodes[Common::KEYCODE_v] = WIN_V;
-    _winCodes[Common::KEYCODE_w] = WIN_W;
-    _winCodes[Common::KEYCODE_x] = WIN_X;
-    _winCodes[Common::KEYCODE_y] = WIN_Y;
-    _winCodes[Common::KEYCODE_z] = WIN_Z;
-    _winCodes[Common::KEYCODE_DELETE] = WIN_DELETE;
-    _winCodes[Common::KEYCODE_KP_PERIOD] = WIN_DECIMAL;
-    _winCodes[Common::KEYCODE_KP_DIVIDE] = WIN_DIVIDE;
-    _winCodes[Common::KEYCODE_KP_MULTIPLY] = WIN_MULTIPLY;
-    _winCodes[Common::KEYCODE_KP_MINUS] = WIN_SUBTRACT;
-    _winCodes[Common::KEYCODE_KP_PLUS] = WIN_ADD;
-    _winCodes[Common::KEYCODE_KP_ENTER] = WIN_RETURN;
-    _winCodes[Common::KEYCODE_KP_EQUALS] = WIN_CLEAR;
-    _winCodes[Common::KEYCODE_UP] = WIN_UP;
-    _winCodes[Common::KEYCODE_DOWN] = WIN_DOWN;
-    _winCodes[Common::KEYCODE_RIGHT] = WIN_RIGHT;
-    _winCodes[Common::KEYCODE_LEFT] = WIN_LEFT;
-    _winCodes[Common::KEYCODE_INSERT] = WIN_INSERT;
-    _winCodes[Common::KEYCODE_HOME] = WIN_HOME;
-    _winCodes[Common::KEYCODE_END] = WIN_END;
-    _winCodes[Common::KEYCODE_PAGEUP] = WIN_PRIOR;
-    _winCodes[Common::KEYCODE_PAGEDOWN] = WIN_NEXT;
-    _winCodes[Common::KEYCODE_F1] = WIN_F1;
-    _winCodes[Common::KEYCODE_F2] = WIN_F2;
-    _winCodes[Common::KEYCODE_F3] = WIN_F3;
-    _winCodes[Common::KEYCODE_F4] = WIN_F4;
-    _winCodes[Common::KEYCODE_F5] = WIN_F5;
-    _winCodes[Common::KEYCODE_F6] = WIN_F6;
-    _winCodes[Common::KEYCODE_F7] = WIN_F7;
-    _winCodes[Common::KEYCODE_F8] = WIN_F8;
-    _winCodes[Common::KEYCODE_F9] = WIN_F9;
-    _winCodes[Common::KEYCODE_F10] = WIN_F10;
-    _winCodes[Common::KEYCODE_F11] = WIN_F11;
-    _winCodes[Common::KEYCODE_F12] = WIN_F12;
-    _winCodes[Common::KEYCODE_F13] = WIN_F13;
-    _winCodes[Common::KEYCODE_F14] = WIN_F14;
-    _winCodes[Common::KEYCODE_F15] = WIN_F15;
-    _winCodes[Common::KEYCODE_CAPSLOCK] = WIN_CAPITAL;
-    _winCodes[Common::KEYCODE_RSHIFT] = WIN_RSHIFT;
-    _winCodes[Common::KEYCODE_LSHIFT] = WIN_LSHIFT;
-    _winCodes[Common::KEYCODE_RCTRL] = WIN_RCONTROL;
-    _winCodes[Common::KEYCODE_LCTRL] = WIN_LCONTROL;
-    _winCodes[Common::KEYCODE_RALT] = WIN_RMENU;
-    _winCodes[Common::KEYCODE_LALT] = WIN_LMENU;
-    _winCodes[Common::KEYCODE_SCROLLOCK] = WIN_SCROLL;
-    _winCodes[Common::KEYCODE_NUMLOCK] = WIN_NUMLOCK;
-    _winCodes[Common::KEYCODE_LSUPER] = WIN_LWIN;
-    _winCodes[Common::KEYCODE_RSUPER] = WIN_RWIN;
-    _winCodes[Common::KEYCODE_PRINT] = WIN_SNAPSHOT;
-    _winCodes[Common::KEYCODE_COMPOSE] = WIN_APPS;
-    _winCodes[Common::KEYCODE_KP0] = WIN_NUMPAD0;
-    _winCodes[Common::KEYCODE_KP1] = WIN_NUMPAD1;
-    _winCodes[Common::KEYCODE_KP2] = WIN_NUMPAD2;
-    _winCodes[Common::KEYCODE_KP3] = WIN_NUMPAD3;
-    _winCodes[Common::KEYCODE_KP4] = WIN_NUMPAD4;
-    _winCodes[Common::KEYCODE_KP5] = WIN_NUMPAD5;
-    _winCodes[Common::KEYCODE_KP6] = WIN_NUMPAD6;
-    _winCodes[Common::KEYCODE_KP7] = WIN_NUMPAD7;
-    _winCodes[Common::KEYCODE_KP8] = WIN_NUMPAD8;
-    _winCodes[Common::KEYCODE_KP9] = WIN_NUMPAD9;
-    _winCodes[Common::KEYCODE_TILDE] = WIN_OEM_3;
-    _winCodes[Common::KEYCODE_F16] = WIN_F16;
-    _winCodes[Common::KEYCODE_F17] = WIN_F17;
-    _winCodes[Common::KEYCODE_F18] = WIN_F18;
-    _winCodes[Common::KEYCODE_SLEEP] = WIN_SLEEP;
-    _winCodes[Common::KEYCODE_VOLUMEUP] = WIN_VOLUME_UP;
-    _winCodes[Common::KEYCODE_VOLUMEDOWN] = WIN_VOLUME_DOWN;
-    _winCodes[Common::KEYCODE_AUDIONEXT] = WIN_MEDIA_NEXT_TRACK;
-    _winCodes[Common::KEYCODE_AUDIOPREV] = WIN_MEDIA_PREV_TRACK;
-    _winCodes[Common::KEYCODE_AUDIOSTOP] = WIN_MEDIA_STOP;
-    _winCodes[Common::KEYCODE_AUDIOPLAYPAUSE] = WIN_MEDIA_PLAY_PAUSE;
-    _winCodes[Common::KEYCODE_AUDIOMUTE] = WIN_VOLUME_MUTE;
-    _winCodes[Common::KEYCODE_AC_SEARCH] = WIN_BROWSER_SEARCH;
-    _winCodes[Common::KEYCODE_AC_HOME] = WIN_BROWSER_HOME;
-    _winCodes[Common::KEYCODE_AC_BACK] = WIN_BROWSER_BACK;
-    _winCodes[Common::KEYCODE_AC_FORWARD] = WIN_BROWSER_FORWARD;
-    _winCodes[Common::KEYCODE_AC_STOP] = WIN_BROWSER_STOP;
-    _winCodes[Common::KEYCODE_AC_REFRESH] = WIN_BROWSER_REFRESH;
-    _winCodes[Common::KEYCODE_AC_BOOKMARKS] = WIN_BROWSER_FAVORITES;
+	_winCodes[Common::KEYCODE_BACKSPACE] = WIN_BACK;
+	_winCodes[Common::KEYCODE_TAB] = WIN_TAB;
+	_winCodes[Common::KEYCODE_CLEAR] = WIN_CLEAR;
+	_winCodes[Common::KEYCODE_RETURN] = WIN_RETURN;
+	_winCodes[Common::KEYCODE_PAUSE] = WIN_PAUSE;
+	_winCodes[Common::KEYCODE_ESCAPE] = WIN_ESCAPE;
+	_winCodes[Common::KEYCODE_SPACE] = WIN_SPACE;
+	_winCodes[Common::KEYCODE_QUOTE] = WIN_OEM_7;
+	_winCodes[Common::KEYCODE_COMMA] = WIN_OEM_COMMA;
+	_winCodes[Common::KEYCODE_MINUS] = WIN_OEM_MINUS;
+	_winCodes[Common::KEYCODE_PERIOD] = WIN_OEM_PERIOD;
+	_winCodes[Common::KEYCODE_SLASH] = WIN_OEM_2;
+	_winCodes[Common::KEYCODE_0] = WIN_0;
+	_winCodes[Common::KEYCODE_1] = WIN_1;
+	_winCodes[Common::KEYCODE_2] = WIN_2;
+	_winCodes[Common::KEYCODE_3] = WIN_3;
+	_winCodes[Common::KEYCODE_4] = WIN_4;
+	_winCodes[Common::KEYCODE_5] = WIN_5;
+	_winCodes[Common::KEYCODE_6] = WIN_6;
+	_winCodes[Common::KEYCODE_7] = WIN_7;
+	_winCodes[Common::KEYCODE_8] = WIN_8;
+	_winCodes[Common::KEYCODE_9] = WIN_9;
+	_winCodes[Common::KEYCODE_SEMICOLON] = WIN_OEM_1;
+	_winCodes[Common::KEYCODE_EQUALS] = WIN_OEM_PLUS;
+	_winCodes[Common::KEYCODE_LEFTBRACKET] = WIN_OEM_4;
+	_winCodes[Common::KEYCODE_BACKSLASH] = WIN_OEM_5;
+	_winCodes[Common::KEYCODE_RIGHTBRACKET] = WIN_OEM_6;
+	_winCodes[Common::KEYCODE_BACKQUOTE] = WIN_OEM_3;
+	_winCodes[Common::KEYCODE_a] = WIN_A;
+	_winCodes[Common::KEYCODE_b] = WIN_B;
+	_winCodes[Common::KEYCODE_c] = WIN_C;
+	_winCodes[Common::KEYCODE_d] = WIN_D;
+	_winCodes[Common::KEYCODE_e] = WIN_E;
+	_winCodes[Common::KEYCODE_f] = WIN_F;
+	_winCodes[Common::KEYCODE_g] = WIN_G;
+	_winCodes[Common::KEYCODE_h] = WIN_H;
+	_winCodes[Common::KEYCODE_i] = WIN_I;
+	_winCodes[Common::KEYCODE_j] = WIN_J;
+	_winCodes[Common::KEYCODE_k] = WIN_K;
+	_winCodes[Common::KEYCODE_l] = WIN_L;
+	_winCodes[Common::KEYCODE_m] = WIN_M;
+	_winCodes[Common::KEYCODE_n] = WIN_N;
+	_winCodes[Common::KEYCODE_o] = WIN_O;
+	_winCodes[Common::KEYCODE_p] = WIN_P;
+	_winCodes[Common::KEYCODE_q] = WIN_Q;
+	_winCodes[Common::KEYCODE_r] = WIN_R;
+	_winCodes[Common::KEYCODE_s] = WIN_S;
+	_winCodes[Common::KEYCODE_t] = WIN_T;
+	_winCodes[Common::KEYCODE_u] = WIN_U;
+	_winCodes[Common::KEYCODE_v] = WIN_V;
+	_winCodes[Common::KEYCODE_w] = WIN_W;
+	_winCodes[Common::KEYCODE_x] = WIN_X;
+	_winCodes[Common::KEYCODE_y] = WIN_Y;
+	_winCodes[Common::KEYCODE_z] = WIN_Z;
+	_winCodes[Common::KEYCODE_DELETE] = WIN_DELETE;
+	_winCodes[Common::KEYCODE_KP_PERIOD] = WIN_DECIMAL;
+	_winCodes[Common::KEYCODE_KP_DIVIDE] = WIN_DIVIDE;
+	_winCodes[Common::KEYCODE_KP_MULTIPLY] = WIN_MULTIPLY;
+	_winCodes[Common::KEYCODE_KP_MINUS] = WIN_SUBTRACT;
+	_winCodes[Common::KEYCODE_KP_PLUS] = WIN_ADD;
+	_winCodes[Common::KEYCODE_KP_ENTER] = WIN_RETURN;
+	_winCodes[Common::KEYCODE_KP_EQUALS] = WIN_CLEAR;
+	_winCodes[Common::KEYCODE_UP] = WIN_UP;
+	_winCodes[Common::KEYCODE_DOWN] = WIN_DOWN;
+	_winCodes[Common::KEYCODE_RIGHT] = WIN_RIGHT;
+	_winCodes[Common::KEYCODE_LEFT] = WIN_LEFT;
+	_winCodes[Common::KEYCODE_INSERT] = WIN_INSERT;
+	_winCodes[Common::KEYCODE_HOME] = WIN_HOME;
+	_winCodes[Common::KEYCODE_END] = WIN_END;
+	_winCodes[Common::KEYCODE_PAGEUP] = WIN_PRIOR;
+	_winCodes[Common::KEYCODE_PAGEDOWN] = WIN_NEXT;
+	_winCodes[Common::KEYCODE_F1] = WIN_F1;
+	_winCodes[Common::KEYCODE_F2] = WIN_F2;
+	_winCodes[Common::KEYCODE_F3] = WIN_F3;
+	_winCodes[Common::KEYCODE_F4] = WIN_F4;
+	_winCodes[Common::KEYCODE_F5] = WIN_F5;
+	_winCodes[Common::KEYCODE_F6] = WIN_F6;
+	_winCodes[Common::KEYCODE_F7] = WIN_F7;
+	_winCodes[Common::KEYCODE_F8] = WIN_F8;
+	_winCodes[Common::KEYCODE_F9] = WIN_F9;
+	_winCodes[Common::KEYCODE_F10] = WIN_F10;
+	_winCodes[Common::KEYCODE_F11] = WIN_F11;
+	_winCodes[Common::KEYCODE_F12] = WIN_F12;
+	_winCodes[Common::KEYCODE_F13] = WIN_F13;
+	_winCodes[Common::KEYCODE_F14] = WIN_F14;
+	_winCodes[Common::KEYCODE_F15] = WIN_F15;
+	_winCodes[Common::KEYCODE_CAPSLOCK] = WIN_CAPITAL;
+	_winCodes[Common::KEYCODE_RSHIFT] = WIN_RSHIFT;
+	_winCodes[Common::KEYCODE_LSHIFT] = WIN_LSHIFT;
+	_winCodes[Common::KEYCODE_RCTRL] = WIN_RCONTROL;
+	_winCodes[Common::KEYCODE_LCTRL] = WIN_LCONTROL;
+	_winCodes[Common::KEYCODE_RALT] = WIN_RMENU;
+	_winCodes[Common::KEYCODE_LALT] = WIN_LMENU;
+	_winCodes[Common::KEYCODE_SCROLLOCK] = WIN_SCROLL;
+	_winCodes[Common::KEYCODE_NUMLOCK] = WIN_NUMLOCK;
+	_winCodes[Common::KEYCODE_LSUPER] = WIN_LWIN;
+	_winCodes[Common::KEYCODE_RSUPER] = WIN_RWIN;
+	_winCodes[Common::KEYCODE_PRINT] = WIN_SNAPSHOT;
+	_winCodes[Common::KEYCODE_COMPOSE] = WIN_APPS;
+	_winCodes[Common::KEYCODE_KP0] = WIN_NUMPAD0;
+	_winCodes[Common::KEYCODE_KP1] = WIN_NUMPAD1;
+	_winCodes[Common::KEYCODE_KP2] = WIN_NUMPAD2;
+	_winCodes[Common::KEYCODE_KP3] = WIN_NUMPAD3;
+	_winCodes[Common::KEYCODE_KP4] = WIN_NUMPAD4;
+	_winCodes[Common::KEYCODE_KP5] = WIN_NUMPAD5;
+	_winCodes[Common::KEYCODE_KP6] = WIN_NUMPAD6;
+	_winCodes[Common::KEYCODE_KP7] = WIN_NUMPAD7;
+	_winCodes[Common::KEYCODE_KP8] = WIN_NUMPAD8;
+	_winCodes[Common::KEYCODE_KP9] = WIN_NUMPAD9;
+	_winCodes[Common::KEYCODE_TILDE] = WIN_OEM_3;
+	_winCodes[Common::KEYCODE_F16] = WIN_F16;
+	_winCodes[Common::KEYCODE_F17] = WIN_F17;
+	_winCodes[Common::KEYCODE_F18] = WIN_F18;
+	_winCodes[Common::KEYCODE_SLEEP] = WIN_SLEEP;
+	_winCodes[Common::KEYCODE_VOLUMEUP] = WIN_VOLUME_UP;
+	_winCodes[Common::KEYCODE_VOLUMEDOWN] = WIN_VOLUME_DOWN;
+	_winCodes[Common::KEYCODE_AUDIONEXT] = WIN_MEDIA_NEXT_TRACK;
+	_winCodes[Common::KEYCODE_AUDIOPREV] = WIN_MEDIA_PREV_TRACK;
+	_winCodes[Common::KEYCODE_AUDIOSTOP] = WIN_MEDIA_STOP;
+	_winCodes[Common::KEYCODE_AUDIOPLAYPAUSE] = WIN_MEDIA_PLAY_PAUSE;
+	_winCodes[Common::KEYCODE_AUDIOMUTE] = WIN_VOLUME_MUTE;
+	_winCodes[Common::KEYCODE_AC_SEARCH] = WIN_BROWSER_SEARCH;
+	_winCodes[Common::KEYCODE_AC_HOME] = WIN_BROWSER_HOME;
+	_winCodes[Common::KEYCODE_AC_BACK] = WIN_BROWSER_BACK;
+	_winCodes[Common::KEYCODE_AC_FORWARD] = WIN_BROWSER_FORWARD;
+	_winCodes[Common::KEYCODE_AC_STOP] = WIN_BROWSER_STOP;
+	_winCodes[Common::KEYCODE_AC_REFRESH] = WIN_BROWSER_REFRESH;
+	_winCodes[Common::KEYCODE_AC_BOOKMARKS] = WIN_BROWSER_FAVORITES;
 
 
-    _scummCodes[WIN_BACK] = Common::KEYCODE_BACKSPACE;
-    _scummCodes[WIN_TAB] = Common::KEYCODE_TAB;
-    _scummCodes[WIN_CLEAR] = Common::KEYCODE_CLEAR;
-    _scummCodes[WIN_RETURN] = Common::KEYCODE_RETURN;
-    _scummCodes[WIN_PAUSE] = Common::KEYCODE_PAUSE;
-    _scummCodes[WIN_ESCAPE] = Common::KEYCODE_ESCAPE;
-    _scummCodes[WIN_SPACE] = Common::KEYCODE_SPACE;
-    _scummCodes[WIN_OEM_7] = Common::KEYCODE_QUOTE;
-    _scummCodes[WIN_OEM_COMMA] = Common::KEYCODE_COMMA;
-    _scummCodes[WIN_OEM_MINUS] = Common::KEYCODE_MINUS;
-    _scummCodes[WIN_OEM_PERIOD] = Common::KEYCODE_PERIOD;
-    _scummCodes[WIN_OEM_2] = Common::KEYCODE_SLASH;
-    _scummCodes[WIN_0] = Common::KEYCODE_0;
-    _scummCodes[WIN_1] = Common::KEYCODE_1;
-    _scummCodes[WIN_2] = Common::KEYCODE_2;
-    _scummCodes[WIN_3] = Common::KEYCODE_3;
-    _scummCodes[WIN_4] = Common::KEYCODE_4;
-    _scummCodes[WIN_5] = Common::KEYCODE_5;
-    _scummCodes[WIN_6] = Common::KEYCODE_6;
-    _scummCodes[WIN_7] = Common::KEYCODE_7;
-    _scummCodes[WIN_8] = Common::KEYCODE_8;
-    _scummCodes[WIN_9] = Common::KEYCODE_9;
-    _scummCodes[WIN_OEM_1] = Common::KEYCODE_SEMICOLON;
-    _scummCodes[WIN_OEM_PLUS] = Common::KEYCODE_EQUALS;
-    _scummCodes[WIN_OEM_4] = Common::KEYCODE_LEFTBRACKET;
-    _scummCodes[WIN_OEM_5] = Common::KEYCODE_BACKSLASH;
-    _scummCodes[WIN_OEM_6] = Common::KEYCODE_RIGHTBRACKET;
-    _scummCodes[WIN_OEM_3] = Common::KEYCODE_BACKQUOTE;
-    _scummCodes[WIN_A] = Common::KEYCODE_a;
-    _scummCodes[WIN_B] = Common::KEYCODE_b;
-    _scummCodes[WIN_C] = Common::KEYCODE_c;
-    _scummCodes[WIN_D] = Common::KEYCODE_d;
-    _scummCodes[WIN_E] = Common::KEYCODE_e;
-    _scummCodes[WIN_F] = Common::KEYCODE_f;
-    _scummCodes[WIN_G] = Common::KEYCODE_g;
-    _scummCodes[WIN_H] = Common::KEYCODE_h;
-    _scummCodes[WIN_I] = Common::KEYCODE_i;
-    _scummCodes[WIN_J] = Common::KEYCODE_j;
-    _scummCodes[WIN_K] = Common::KEYCODE_k;
-    _scummCodes[WIN_L] = Common::KEYCODE_l;
-    _scummCodes[WIN_M] = Common::KEYCODE_m;
-    _scummCodes[WIN_N] = Common::KEYCODE_n;
-    _scummCodes[WIN_O] = Common::KEYCODE_o;
-    _scummCodes[WIN_P] = Common::KEYCODE_p;
-    _scummCodes[WIN_Q] = Common::KEYCODE_q;
-    _scummCodes[WIN_R] = Common::KEYCODE_r;
-    _scummCodes[WIN_S] = Common::KEYCODE_s;
-    _scummCodes[WIN_T] = Common::KEYCODE_t;
-    _scummCodes[WIN_U] = Common::KEYCODE_u;
-    _scummCodes[WIN_V] = Common::KEYCODE_v;
-    _scummCodes[WIN_W] = Common::KEYCODE_w;
-    _scummCodes[WIN_X] = Common::KEYCODE_x;
-    _scummCodes[WIN_Y] = Common::KEYCODE_y;
-    _scummCodes[WIN_Z] = Common::KEYCODE_z;
-    _scummCodes[WIN_DELETE] = Common::KEYCODE_DELETE;
-    _scummCodes[WIN_DECIMAL] = Common::KEYCODE_KP_PERIOD;
-    _scummCodes[WIN_DIVIDE] = Common::KEYCODE_KP_DIVIDE;
-    _scummCodes[WIN_MULTIPLY] = Common::KEYCODE_KP_MULTIPLY;
-    _scummCodes[WIN_SUBTRACT] = Common::KEYCODE_KP_MINUS;
-    _scummCodes[WIN_ADD] = Common::KEYCODE_KP_PLUS;
-    _scummCodes[WIN_RETURN] = Common::KEYCODE_KP_ENTER;
-    _scummCodes[WIN_CLEAR] = Common::KEYCODE_KP_EQUALS;
-    _scummCodes[WIN_UP] = Common::KEYCODE_UP;
-    _scummCodes[WIN_DOWN] = Common::KEYCODE_DOWN;
-    _scummCodes[WIN_RIGHT] = Common::KEYCODE_RIGHT;
-    _scummCodes[WIN_LEFT] = Common::KEYCODE_LEFT;
-    _scummCodes[WIN_INSERT] = Common::KEYCODE_INSERT;
-    _scummCodes[WIN_HOME] = Common::KEYCODE_HOME;
-    _scummCodes[WIN_END] = Common::KEYCODE_END;
-    _scummCodes[WIN_PRIOR] = Common::KEYCODE_PAGEUP;
-    _scummCodes[WIN_NEXT] = Common::KEYCODE_PAGEDOWN;
-    _scummCodes[WIN_F1] = Common::KEYCODE_F1;
-    _scummCodes[WIN_F2] = Common::KEYCODE_F2;
-    _scummCodes[WIN_F3] = Common::KEYCODE_F3;
-    _scummCodes[WIN_F4] = Common::KEYCODE_F4;
-    _scummCodes[WIN_F5] = Common::KEYCODE_F5;
-    _scummCodes[WIN_F6] = Common::KEYCODE_F6;
-    _scummCodes[WIN_F7] = Common::KEYCODE_F7;
-    _scummCodes[WIN_F8] = Common::KEYCODE_F8;
-    _scummCodes[WIN_F9] = Common::KEYCODE_F9;
-    _scummCodes[WIN_F10] = Common::KEYCODE_F10;
-    _scummCodes[WIN_F11] = Common::KEYCODE_F11;
-    _scummCodes[WIN_F12] = Common::KEYCODE_F12;
-    _scummCodes[WIN_F13] = Common::KEYCODE_F13;
-    _scummCodes[WIN_F14] = Common::KEYCODE_F14;
-    _scummCodes[WIN_F15] = Common::KEYCODE_F15;
-    _scummCodes[WIN_CAPITAL] = Common::KEYCODE_CAPSLOCK;
-    _scummCodes[WIN_RSHIFT] = Common::KEYCODE_RSHIFT;
-    _scummCodes[WIN_LSHIFT] = Common::KEYCODE_LSHIFT;
-    _scummCodes[WIN_RCONTROL] = Common::KEYCODE_RCTRL;
-    _scummCodes[WIN_LCONTROL] = Common::KEYCODE_LCTRL;
-    _scummCodes[WIN_RMENU] = Common::KEYCODE_RALT;
-    _scummCodes[WIN_LMENU] = Common::KEYCODE_LALT;
-    _scummCodes[WIN_SCROLL] = Common::KEYCODE_SCROLLOCK;
-    _scummCodes[WIN_NUMLOCK] = Common::KEYCODE_NUMLOCK;
-    _scummCodes[WIN_LWIN] = Common::KEYCODE_LSUPER;
-    _scummCodes[WIN_RWIN] = Common::KEYCODE_RSUPER;
-    _scummCodes[WIN_SNAPSHOT] = Common::KEYCODE_PRINT;
-    _scummCodes[WIN_APPS] = Common::KEYCODE_COMPOSE;
-    _scummCodes[WIN_NUMPAD0] = Common::KEYCODE_KP0;
-    _scummCodes[WIN_NUMPAD1] = Common::KEYCODE_KP1;
-    _scummCodes[WIN_NUMPAD2] = Common::KEYCODE_KP2;
-    _scummCodes[WIN_NUMPAD3] = Common::KEYCODE_KP3;
-    _scummCodes[WIN_NUMPAD4] = Common::KEYCODE_KP4;
-    _scummCodes[WIN_NUMPAD5] = Common::KEYCODE_KP5;
-    _scummCodes[WIN_NUMPAD6] = Common::KEYCODE_KP6;
-    _scummCodes[WIN_NUMPAD7] = Common::KEYCODE_KP7;
-    _scummCodes[WIN_NUMPAD8] = Common::KEYCODE_KP8;
-    _scummCodes[WIN_NUMPAD9] = Common::KEYCODE_KP9;
-    _scummCodes[WIN_OEM_3] = Common::KEYCODE_TILDE;
-    _scummCodes[WIN_F16] = Common::KEYCODE_F16;
-    _scummCodes[WIN_F17] = Common::KEYCODE_F17;
-    _scummCodes[WIN_F18] = Common::KEYCODE_F18;
-    _scummCodes[WIN_SLEEP] = Common::KEYCODE_SLEEP;
-    _scummCodes[WIN_VOLUME_UP] = Common::KEYCODE_VOLUMEUP;
-    _scummCodes[WIN_VOLUME_DOWN] = Common::KEYCODE_VOLUMEDOWN;
-    _scummCodes[WIN_MEDIA_NEXT_TRACK] = Common::KEYCODE_AUDIONEXT;
-    _scummCodes[WIN_MEDIA_PREV_TRACK] = Common::KEYCODE_AUDIOPREV;
-    _scummCodes[WIN_MEDIA_STOP] = Common::KEYCODE_AUDIOSTOP;
-    _scummCodes[WIN_MEDIA_PLAY_PAUSE] = Common::KEYCODE_AUDIOPLAYPAUSE;
-    _scummCodes[WIN_VOLUME_MUTE] = Common::KEYCODE_AUDIOMUTE;
-    _scummCodes[WIN_BROWSER_SEARCH] = Common::KEYCODE_AC_SEARCH;
-    _scummCodes[WIN_BROWSER_HOME] = Common::KEYCODE_AC_HOME;
-    _scummCodes[WIN_BROWSER_BACK] = Common::KEYCODE_AC_BACK;
-    _scummCodes[WIN_BROWSER_FORWARD] = Common::KEYCODE_AC_FORWARD;
-    _scummCodes[WIN_BROWSER_STOP] = Common::KEYCODE_AC_STOP;
-    _scummCodes[WIN_BROWSER_REFRESH] = Common::KEYCODE_AC_REFRESH;
-    _scummCodes[WIN_BROWSER_FAVORITES] = Common::KEYCODE_AC_BOOKMARKS;
+	_scummCodes[WIN_BACK] = Common::KEYCODE_BACKSPACE;
+	_scummCodes[WIN_TAB] = Common::KEYCODE_TAB;
+	_scummCodes[WIN_CLEAR] = Common::KEYCODE_CLEAR;
+	_scummCodes[WIN_RETURN] = Common::KEYCODE_RETURN;
+	_scummCodes[WIN_PAUSE] = Common::KEYCODE_PAUSE;
+	_scummCodes[WIN_ESCAPE] = Common::KEYCODE_ESCAPE;
+	_scummCodes[WIN_SPACE] = Common::KEYCODE_SPACE;
+	_scummCodes[WIN_OEM_7] = Common::KEYCODE_QUOTE;
+	_scummCodes[WIN_OEM_COMMA] = Common::KEYCODE_COMMA;
+	_scummCodes[WIN_OEM_MINUS] = Common::KEYCODE_MINUS;
+	_scummCodes[WIN_OEM_PERIOD] = Common::KEYCODE_PERIOD;
+	_scummCodes[WIN_OEM_2] = Common::KEYCODE_SLASH;
+	_scummCodes[WIN_0] = Common::KEYCODE_0;
+	_scummCodes[WIN_1] = Common::KEYCODE_1;
+	_scummCodes[WIN_2] = Common::KEYCODE_2;
+	_scummCodes[WIN_3] = Common::KEYCODE_3;
+	_scummCodes[WIN_4] = Common::KEYCODE_4;
+	_scummCodes[WIN_5] = Common::KEYCODE_5;
+	_scummCodes[WIN_6] = Common::KEYCODE_6;
+	_scummCodes[WIN_7] = Common::KEYCODE_7;
+	_scummCodes[WIN_8] = Common::KEYCODE_8;
+	_scummCodes[WIN_9] = Common::KEYCODE_9;
+	_scummCodes[WIN_OEM_1] = Common::KEYCODE_SEMICOLON;
+	_scummCodes[WIN_OEM_PLUS] = Common::KEYCODE_EQUALS;
+	_scummCodes[WIN_OEM_4] = Common::KEYCODE_LEFTBRACKET;
+	_scummCodes[WIN_OEM_5] = Common::KEYCODE_BACKSLASH;
+	_scummCodes[WIN_OEM_6] = Common::KEYCODE_RIGHTBRACKET;
+	_scummCodes[WIN_OEM_3] = Common::KEYCODE_BACKQUOTE;
+	_scummCodes[WIN_A] = Common::KEYCODE_a;
+	_scummCodes[WIN_B] = Common::KEYCODE_b;
+	_scummCodes[WIN_C] = Common::KEYCODE_c;
+	_scummCodes[WIN_D] = Common::KEYCODE_d;
+	_scummCodes[WIN_E] = Common::KEYCODE_e;
+	_scummCodes[WIN_F] = Common::KEYCODE_f;
+	_scummCodes[WIN_G] = Common::KEYCODE_g;
+	_scummCodes[WIN_H] = Common::KEYCODE_h;
+	_scummCodes[WIN_I] = Common::KEYCODE_i;
+	_scummCodes[WIN_J] = Common::KEYCODE_j;
+	_scummCodes[WIN_K] = Common::KEYCODE_k;
+	_scummCodes[WIN_L] = Common::KEYCODE_l;
+	_scummCodes[WIN_M] = Common::KEYCODE_m;
+	_scummCodes[WIN_N] = Common::KEYCODE_n;
+	_scummCodes[WIN_O] = Common::KEYCODE_o;
+	_scummCodes[WIN_P] = Common::KEYCODE_p;
+	_scummCodes[WIN_Q] = Common::KEYCODE_q;
+	_scummCodes[WIN_R] = Common::KEYCODE_r;
+	_scummCodes[WIN_S] = Common::KEYCODE_s;
+	_scummCodes[WIN_T] = Common::KEYCODE_t;
+	_scummCodes[WIN_U] = Common::KEYCODE_u;
+	_scummCodes[WIN_V] = Common::KEYCODE_v;
+	_scummCodes[WIN_W] = Common::KEYCODE_w;
+	_scummCodes[WIN_X] = Common::KEYCODE_x;
+	_scummCodes[WIN_Y] = Common::KEYCODE_y;
+	_scummCodes[WIN_Z] = Common::KEYCODE_z;
+	_scummCodes[WIN_DELETE] = Common::KEYCODE_DELETE;
+	_scummCodes[WIN_DECIMAL] = Common::KEYCODE_KP_PERIOD;
+	_scummCodes[WIN_DIVIDE] = Common::KEYCODE_KP_DIVIDE;
+	_scummCodes[WIN_MULTIPLY] = Common::KEYCODE_KP_MULTIPLY;
+	_scummCodes[WIN_SUBTRACT] = Common::KEYCODE_KP_MINUS;
+	_scummCodes[WIN_ADD] = Common::KEYCODE_KP_PLUS;
+	_scummCodes[WIN_RETURN] = Common::KEYCODE_KP_ENTER;
+	_scummCodes[WIN_CLEAR] = Common::KEYCODE_KP_EQUALS;
+	_scummCodes[WIN_UP] = Common::KEYCODE_UP;
+	_scummCodes[WIN_DOWN] = Common::KEYCODE_DOWN;
+	_scummCodes[WIN_RIGHT] = Common::KEYCODE_RIGHT;
+	_scummCodes[WIN_LEFT] = Common::KEYCODE_LEFT;
+	_scummCodes[WIN_INSERT] = Common::KEYCODE_INSERT;
+	_scummCodes[WIN_HOME] = Common::KEYCODE_HOME;
+	_scummCodes[WIN_END] = Common::KEYCODE_END;
+	_scummCodes[WIN_PRIOR] = Common::KEYCODE_PAGEUP;
+	_scummCodes[WIN_NEXT] = Common::KEYCODE_PAGEDOWN;
+	_scummCodes[WIN_F1] = Common::KEYCODE_F1;
+	_scummCodes[WIN_F2] = Common::KEYCODE_F2;
+	_scummCodes[WIN_F3] = Common::KEYCODE_F3;
+	_scummCodes[WIN_F4] = Common::KEYCODE_F4;
+	_scummCodes[WIN_F5] = Common::KEYCODE_F5;
+	_scummCodes[WIN_F6] = Common::KEYCODE_F6;
+	_scummCodes[WIN_F7] = Common::KEYCODE_F7;
+	_scummCodes[WIN_F8] = Common::KEYCODE_F8;
+	_scummCodes[WIN_F9] = Common::KEYCODE_F9;
+	_scummCodes[WIN_F10] = Common::KEYCODE_F10;
+	_scummCodes[WIN_F11] = Common::KEYCODE_F11;
+	_scummCodes[WIN_F12] = Common::KEYCODE_F12;
+	_scummCodes[WIN_F13] = Common::KEYCODE_F13;
+	_scummCodes[WIN_F14] = Common::KEYCODE_F14;
+	_scummCodes[WIN_F15] = Common::KEYCODE_F15;
+	_scummCodes[WIN_CAPITAL] = Common::KEYCODE_CAPSLOCK;
+	_scummCodes[WIN_RSHIFT] = Common::KEYCODE_RSHIFT;
+	_scummCodes[WIN_LSHIFT] = Common::KEYCODE_LSHIFT;
+	_scummCodes[WIN_RCONTROL] = Common::KEYCODE_RCTRL;
+	_scummCodes[WIN_LCONTROL] = Common::KEYCODE_LCTRL;
+	_scummCodes[WIN_RMENU] = Common::KEYCODE_RALT;
+	_scummCodes[WIN_LMENU] = Common::KEYCODE_LALT;
+	_scummCodes[WIN_SCROLL] = Common::KEYCODE_SCROLLOCK;
+	_scummCodes[WIN_NUMLOCK] = Common::KEYCODE_NUMLOCK;
+	_scummCodes[WIN_LWIN] = Common::KEYCODE_LSUPER;
+	_scummCodes[WIN_RWIN] = Common::KEYCODE_RSUPER;
+	_scummCodes[WIN_SNAPSHOT] = Common::KEYCODE_PRINT;
+	_scummCodes[WIN_APPS] = Common::KEYCODE_COMPOSE;
+	_scummCodes[WIN_NUMPAD0] = Common::KEYCODE_KP0;
+	_scummCodes[WIN_NUMPAD1] = Common::KEYCODE_KP1;
+	_scummCodes[WIN_NUMPAD2] = Common::KEYCODE_KP2;
+	_scummCodes[WIN_NUMPAD3] = Common::KEYCODE_KP3;
+	_scummCodes[WIN_NUMPAD4] = Common::KEYCODE_KP4;
+	_scummCodes[WIN_NUMPAD5] = Common::KEYCODE_KP5;
+	_scummCodes[WIN_NUMPAD6] = Common::KEYCODE_KP6;
+	_scummCodes[WIN_NUMPAD7] = Common::KEYCODE_KP7;
+	_scummCodes[WIN_NUMPAD8] = Common::KEYCODE_KP8;
+	_scummCodes[WIN_NUMPAD9] = Common::KEYCODE_KP9;
+	_scummCodes[WIN_OEM_3] = Common::KEYCODE_TILDE;
+	_scummCodes[WIN_F16] = Common::KEYCODE_F16;
+	_scummCodes[WIN_F17] = Common::KEYCODE_F17;
+	_scummCodes[WIN_F18] = Common::KEYCODE_F18;
+	_scummCodes[WIN_SLEEP] = Common::KEYCODE_SLEEP;
+	_scummCodes[WIN_VOLUME_UP] = Common::KEYCODE_VOLUMEUP;
+	_scummCodes[WIN_VOLUME_DOWN] = Common::KEYCODE_VOLUMEDOWN;
+	_scummCodes[WIN_MEDIA_NEXT_TRACK] = Common::KEYCODE_AUDIONEXT;
+	_scummCodes[WIN_MEDIA_PREV_TRACK] = Common::KEYCODE_AUDIOPREV;
+	_scummCodes[WIN_MEDIA_STOP] = Common::KEYCODE_AUDIOSTOP;
+	_scummCodes[WIN_MEDIA_PLAY_PAUSE] = Common::KEYCODE_AUDIOPLAYPAUSE;
+	_scummCodes[WIN_VOLUME_MUTE] = Common::KEYCODE_AUDIOMUTE;
+	_scummCodes[WIN_BROWSER_SEARCH] = Common::KEYCODE_AC_SEARCH;
+	_scummCodes[WIN_BROWSER_HOME] = Common::KEYCODE_AC_HOME;
+	_scummCodes[WIN_BROWSER_BACK] = Common::KEYCODE_AC_BACK;
+	_scummCodes[WIN_BROWSER_FORWARD] = Common::KEYCODE_AC_FORWARD;
+	_scummCodes[WIN_BROWSER_STOP] = Common::KEYCODE_AC_STOP;
+	_scummCodes[WIN_BROWSER_REFRESH] = Common::KEYCODE_AC_REFRESH;
+	_scummCodes[WIN_BROWSER_FAVORITES] = Common::KEYCODE_AC_BOOKMARKS;
 }
 
 }
diff --git a/engines/gamos/keycodes.h b/engines/gamos/keycodes.h
index a4ad1a73936..0745004afe9 100644
--- a/engines/gamos/keycodes.h
+++ b/engines/gamos/keycodes.h
@@ -29,252 +29,256 @@ namespace Gamos {
 class KeyCodes {
 
 public:
-    enum {
-        WIN_INVALID = 0,
+	enum {
+		WIN_INVALID = 0,
 
-        WIN_LBUTTON = 0x01,
-        WIN_RBUTTON = 0x02,
-        WIN_CANCEL = 0x03,
-        WIN_MBUTTON = 0x04,
-        WIN_XBUTTON1 = 0x05,
-        WIN_XBUTTON2 = 0x06,
-        WIN_BACK = 0x08,
-        WIN_TAB = 0x09,
-        WIN_CLEAR = 0x0C,
-        WIN_RETURN = 0x0D,
-        WIN_SHIFT = 0x10,
-        WIN_CONTROL = 0x11,
-        WIN_MENU = 0x12,
-        WIN_PAUSE = 0x13,
-        WIN_CAPITAL = 0x14,
-        WIN_KANA = 0x15,
-        WIN_JUNJA = 0x17,
-        WIN_FINAL = 0x18,
-        WIN_KANJI = 0x19,
-        WIN_ESCAPE = 0x1B,
-        WIN_CONVERT = 0x1C,
-        WIN_NONCONVERT = 0x1D,
-        WIN_ACCEPT = 0x1E,
-        WIN_MODECHANGE = 0x1F,
-        WIN_SPACE = 0x20,
-        WIN_PRIOR = 0x21,
-        WIN_NEXT = 0x22,
-        WIN_END = 0x23,
-        WIN_HOME = 0x24,
-        WIN_LEFT = 0x25,
-        WIN_UP = 0x26,
-        WIN_RIGHT = 0x27,
-        WIN_DOWN = 0x28,
-        WIN_SELECT = 0x29,
-        WIN_PRINT = 0x2A,
-        WIN_EXECUTE = 0x2B,
-        WIN_SNAPSHOT = 0x2C,
-        WIN_INSERT = 0x2D,
-        WIN_DELETE = 0x2E,
-        WIN_HELP = 0x2F,
-        WIN_0 = 0x30,
-        WIN_1 = 0x31,
-        WIN_2 = 0x32,
-        WIN_3 = 0x33,
-        WIN_4 = 0x34,
-        WIN_5 = 0x35,
-        WIN_6 = 0x36,
-        WIN_7 = 0x37,
-        WIN_8 = 0x38,
-        WIN_9 = 0x39,
-        WIN_A = 0x41,
-        WIN_B = 0x42,
-        WIN_C = 0x43,
-        WIN_D = 0x44,
-        WIN_E = 0x45,
-        WIN_F = 0x46,
-        WIN_G = 0x47,
-        WIN_H = 0x48,
-        WIN_I = 0x49,
-        WIN_J = 0x4A,
-        WIN_K = 0x4B,
-        WIN_L = 0x4C,
-        WIN_M = 0x4D,
-        WIN_N = 0x4E,
-        WIN_O = 0x4F,
-        WIN_P = 0x50,
-        WIN_Q = 0x51,
-        WIN_R = 0x52,
-        WIN_S = 0x53,
-        WIN_T = 0x54,
-        WIN_U = 0x55,
-        WIN_V = 0x56,
-        WIN_W = 0x57,
-        WIN_X = 0x58,
-        WIN_Y = 0x59,
-        WIN_Z = 0x5A,
-        WIN_LWIN = 0x5B,
-        WIN_RWIN = 0x5C,
-        WIN_APPS = 0x5D,
-        WIN_SLEEP = 0x5F,
-        WIN_NUMPAD0 = 0x60,
-        WIN_NUMPAD1 = 0x61,
-        WIN_NUMPAD2 = 0x62,
-        WIN_NUMPAD3 = 0x63,
-        WIN_NUMPAD4 = 0x64,
-        WIN_NUMPAD5 = 0x65,
-        WIN_NUMPAD6 = 0x66,
-        WIN_NUMPAD7 = 0x67,
-        WIN_NUMPAD8 = 0x68,
-        WIN_NUMPAD9 = 0x69,
-        WIN_MULTIPLY = 0x6A,
-        WIN_ADD = 0x6B,
-        WIN_SEPARATOR = 0x6C,
-        WIN_SUBTRACT = 0x6D,
-        WIN_DECIMAL = 0x6E,
-        WIN_DIVIDE = 0x6F,
-        WIN_F1 = 0x70,
-        WIN_F2 = 0x71,
-        WIN_F3 = 0x72,
-        WIN_F4 = 0x73,
-        WIN_F5 = 0x74,
-        WIN_F6 = 0x75,
-        WIN_F7 = 0x76,
-        WIN_F8 = 0x77,
-        WIN_F9 = 0x78,
-        WIN_F10 = 0x79,
-        WIN_F11 = 0x7A,
-        WIN_F12 = 0x7B,
-        WIN_F13 = 0x7C,
-        WIN_F14 = 0x7D,
-        WIN_F15 = 0x7E,
-        WIN_F16 = 0x7F,
-        WIN_F17 = 0x80,
-        WIN_F18 = 0x81,
-        WIN_F19 = 0x82,
-        WIN_F20 = 0x83,
-        WIN_F21 = 0x84,
-        WIN_F22 = 0x85,
-        WIN_F23 = 0x86,
-        WIN_F24 = 0x87,
-        WIN_NAVIGATION_VIEW = 0x88,
-        WIN_NAVIGATION_MENU = 0x89,
-        WIN_NAVIGATION_UP = 0x8A,
-        WIN_NAVIGATION_DOWN = 0x8B,
-        WIN_NAVIGATION_LEFT = 0x8C,
-        WIN_NAVIGATION_RIGHT = 0x8D,
-        WIN_NAVIGATION_ACCEPT = 0x8E,
-        WIN_NAVIGATION_CANCEL = 0x8F,
-        WIN_NUMLOCK = 0x90,
-        WIN_SCROLL = 0x91,
-        WIN_OEM_NEC_EQUAL = 0x92,
-        WIN_OEM_FJ_JISHO = 0x92,
-        WIN_OEM_FJ_MASSHOU = 0x93,
-        WIN_OEM_FJ_TOUROKU = 0x94,
-        WIN_OEM_FJ_LOYA = 0x95,
-        WIN_OEM_FJ_ROYA = 0x96,
-        WIN_LSHIFT = 0xA0,
-        WIN_RSHIFT = 0xA1,
-        WIN_LCONTROL = 0xA2,
-        WIN_RCONTROL = 0xA3,
-        WIN_LMENU = 0xA4,
-        WIN_RMENU = 0xA5,
-        WIN_BROWSER_BACK = 0xA6,
-        WIN_BROWSER_FORWARD = 0xA7,
-        WIN_BROWSER_REFRESH = 0xA8,
-        WIN_BROWSER_STOP = 0xA9,
-        WIN_BROWSER_SEARCH = 0xAA,
-        WIN_BROWSER_FAVORITES = 0xAB,
-        WIN_BROWSER_HOME = 0xAC,
-        WIN_VOLUME_MUTE = 0xAD,
-        WIN_VOLUME_DOWN = 0xAE,
-        WIN_VOLUME_UP = 0xAF,
-        WIN_MEDIA_NEXT_TRACK = 0xB0,
-        WIN_MEDIA_PREV_TRACK = 0xB1,
-        WIN_MEDIA_STOP = 0xB2,
-        WIN_MEDIA_PLAY_PAUSE = 0xB3,
-        WIN_LAUNCH_MAIL = 0xB4,
-        WIN_LAUNCH_MEDIA_SELECT = 0xB5,
-        WIN_LAUNCH_APP1 = 0xB6,
-        WIN_LAUNCH_APP2 = 0xB7,
-        WIN_OEM_1 = 0xBA,
-        WIN_OEM_PLUS = 0xBB,
-        WIN_OEM_COMMA = 0xBC,
-        WIN_OEM_MINUS = 0xBD,
-        WIN_OEM_PERIOD = 0xBE,
-        WIN_OEM_2 = 0xBF,
-        WIN_OEM_3 = 0xC0,
-        WIN_GAMEPAD_A = 0xC3,
-        WIN_GAMEPAD_B = 0xC4,
-        WIN_GAMEPAD_X = 0xC5,
-        WIN_GAMEPAD_Y = 0xC6,
-        WIN_GAMEPAD_RIGHT_SHOULDER = 0xC7,
-        WIN_GAMEPAD_LEFT_SHOULDER = 0xC8,
-        WIN_GAMEPAD_LEFT_TRIGGER = 0xC9,
-        WIN_GAMEPAD_RIGHT_TRIGGER = 0xCA,
-        WIN_GAMEPAD_DPAD_UP = 0xCB,
-        WIN_GAMEPAD_DPAD_DOWN = 0xCC,
-        WIN_GAMEPAD_DPAD_LEFT = 0xCD,
-        WIN_GAMEPAD_DPAD_RIGHT = 0xCE,
-        WIN_GAMEPAD_MENU = 0xCF,
-        WIN_GAMEPAD_VIEW = 0xD0,
-        WIN_GAMEPAD_LEFT_THUMBSTICK_BUTTON = 0xD1,
-        WIN_GAMEPAD_RIGHT_THUMBSTICK_BUTTON = 0xD2,
-        WIN_GAMEPAD_LEFT_THUMBSTICK_UP = 0xD3,
-        WIN_GAMEPAD_LEFT_THUMBSTICK_DOWN = 0xD4,
-        WIN_GAMEPAD_LEFT_THUMBSTICK_RIGHT = 0xD5,
-        WIN_GAMEPAD_LEFT_THUMBSTICK_LEFT = 0xD6,
-        WIN_GAMEPAD_RIGHT_THUMBSTICK_UP = 0xD7,
-        WIN_GAMEPAD_RIGHT_THUMBSTICK_DOWN = 0xD8,
-        WIN_GAMEPAD_RIGHT_THUMBSTICK_RIGHT = 0xD9,
-        WIN_GAMEPAD_RIGHT_THUMBSTICK_LEFT = 0xDA,
-        WIN_OEM_4 = 0xDB,
-        WIN_OEM_5 = 0xDC,
-        WIN_OEM_6 = 0xDD,
-        WIN_OEM_7 = 0xDE,
-        WIN_OEM_8 = 0xDF,
-        WIN_OEM_AX = 0xE1,
-        WIN_OEM_102 = 0xE2,
-        WIN_ICO_HELP = 0xE3,
-        WIN_ICO_00 = 0xE4,
-        WIN_PROCESSKEY = 0xE5,
-        WIN_ICO_CLEAR = 0xE6,
-        WIN_PACKET = 0xE7,
-        WIN_OEM_RESET = 0xE9,
-        WIN_OEM_JUMP = 0xEA,
-        WIN_OEM_PA1 = 0xEB,
-        WIN_OEM_PA2 = 0xEC,
-        WIN_OEM_PA3 = 0xED,
-        WIN_OEM_WSCTRL = 0xEE,
-        WIN_OEM_CUSEL = 0xEF,
-        WIN_OEM_ATTN = 0xF0,
-        WIN_OEM_FINISH = 0xF1,
-        WIN_OEM_COPY = 0xF2,
-        WIN_OEM_AUTO = 0xF3,
-        WIN_OEM_ENLW = 0xF4,
-        WIN_OEM_BACKTAB = 0xF5,
-        WIN_ATTN = 0xF6,
-        WIN_CRSEL = 0xF7,
-        WIN_EXSEL = 0xF8,
-        WIN_EREOF = 0xF9,
-        WIN_PLAY = 0xFA,
-        WIN_ZOOM = 0xFB,
-        WIN_NONAME = 0xFC,
-        WIN_PA1 = 0xFD,
-        WIN_OEM_CLEAR = 0xFE
-    };
+		WIN_LBUTTON = 0x01,
+		WIN_RBUTTON = 0x02,
+		WIN_CANCEL = 0x03,
+		WIN_MBUTTON = 0x04,
+		WIN_XBUTTON1 = 0x05,
+		WIN_XBUTTON2 = 0x06,
+		WIN_BACK = 0x08,
+		WIN_TAB = 0x09,
+		WIN_CLEAR = 0x0C,
+		WIN_RETURN = 0x0D,
+		WIN_SHIFT = 0x10,
+		WIN_CONTROL = 0x11,
+		WIN_MENU = 0x12,
+		WIN_PAUSE = 0x13,
+		WIN_CAPITAL = 0x14,
+		WIN_KANA = 0x15,
+		WIN_JUNJA = 0x17,
+		WIN_FINAL = 0x18,
+		WIN_KANJI = 0x19,
+		WIN_ESCAPE = 0x1B,
+		WIN_CONVERT = 0x1C,
+		WIN_NONCONVERT = 0x1D,
+		WIN_ACCEPT = 0x1E,
+		WIN_MODECHANGE = 0x1F,
+		WIN_SPACE = 0x20,
+		WIN_PRIOR = 0x21,
+		WIN_NEXT = 0x22,
+		WIN_END = 0x23,
+		WIN_HOME = 0x24,
+		WIN_LEFT = 0x25,
+		WIN_UP = 0x26,
+		WIN_RIGHT = 0x27,
+		WIN_DOWN = 0x28,
+		WIN_SELECT = 0x29,
+		WIN_PRINT = 0x2A,
+		WIN_EXECUTE = 0x2B,
+		WIN_SNAPSHOT = 0x2C,
+		WIN_INSERT = 0x2D,
+		WIN_DELETE = 0x2E,
+		WIN_HELP = 0x2F,
+		WIN_0 = 0x30,
+		WIN_1 = 0x31,
+		WIN_2 = 0x32,
+		WIN_3 = 0x33,
+		WIN_4 = 0x34,
+		WIN_5 = 0x35,
+		WIN_6 = 0x36,
+		WIN_7 = 0x37,
+		WIN_8 = 0x38,
+		WIN_9 = 0x39,
+		WIN_A = 0x41,
+		WIN_B = 0x42,
+		WIN_C = 0x43,
+		WIN_D = 0x44,
+		WIN_E = 0x45,
+		WIN_F = 0x46,
+		WIN_G = 0x47,
+		WIN_H = 0x48,
+		WIN_I = 0x49,
+		WIN_J = 0x4A,
+		WIN_K = 0x4B,
+		WIN_L = 0x4C,
+		WIN_M = 0x4D,
+		WIN_N = 0x4E,
+		WIN_O = 0x4F,
+		WIN_P = 0x50,
+		WIN_Q = 0x51,
+		WIN_R = 0x52,
+		WIN_S = 0x53,
+		WIN_T = 0x54,
+		WIN_U = 0x55,
+		WIN_V = 0x56,
+		WIN_W = 0x57,
+		WIN_X = 0x58,
+		WIN_Y = 0x59,
+		WIN_Z = 0x5A,
+		WIN_LWIN = 0x5B,
+		WIN_RWIN = 0x5C,
+		WIN_APPS = 0x5D,
+		WIN_SLEEP = 0x5F,
+		WIN_NUMPAD0 = 0x60,
+		WIN_NUMPAD1 = 0x61,
+		WIN_NUMPAD2 = 0x62,
+		WIN_NUMPAD3 = 0x63,
+		WIN_NUMPAD4 = 0x64,
+		WIN_NUMPAD5 = 0x65,
+		WIN_NUMPAD6 = 0x66,
+		WIN_NUMPAD7 = 0x67,
+		WIN_NUMPAD8 = 0x68,
+		WIN_NUMPAD9 = 0x69,
+		WIN_MULTIPLY = 0x6A,
+		WIN_ADD = 0x6B,
+		WIN_SEPARATOR = 0x6C,
+		WIN_SUBTRACT = 0x6D,
+		WIN_DECIMAL = 0x6E,
+		WIN_DIVIDE = 0x6F,
+		WIN_F1 = 0x70,
+		WIN_F2 = 0x71,
+		WIN_F3 = 0x72,
+		WIN_F4 = 0x73,
+		WIN_F5 = 0x74,
+		WIN_F6 = 0x75,
+		WIN_F7 = 0x76,
+		WIN_F8 = 0x77,
+		WIN_F9 = 0x78,
+		WIN_F10 = 0x79,
+		WIN_F11 = 0x7A,
+		WIN_F12 = 0x7B,
+		WIN_F13 = 0x7C,
+		WIN_F14 = 0x7D,
+		WIN_F15 = 0x7E,
+		WIN_F16 = 0x7F,
+		WIN_F17 = 0x80,
+		WIN_F18 = 0x81,
+		WIN_F19 = 0x82,
+		WIN_F20 = 0x83,
+		WIN_F21 = 0x84,
+		WIN_F22 = 0x85,
+		WIN_F23 = 0x86,
+		WIN_F24 = 0x87,
+		WIN_NAVIGATION_VIEW = 0x88,
+		WIN_NAVIGATION_MENU = 0x89,
+		WIN_NAVIGATION_UP = 0x8A,
+		WIN_NAVIGATION_DOWN = 0x8B,
+		WIN_NAVIGATION_LEFT = 0x8C,
+		WIN_NAVIGATION_RIGHT = 0x8D,
+		WIN_NAVIGATION_ACCEPT = 0x8E,
+		WIN_NAVIGATION_CANCEL = 0x8F,
+		WIN_NUMLOCK = 0x90,
+		WIN_SCROLL = 0x91,
+		WIN_OEM_NEC_EQUAL = 0x92,
+		WIN_OEM_FJ_JISHO = 0x92,
+		WIN_OEM_FJ_MASSHOU = 0x93,
+		WIN_OEM_FJ_TOUROKU = 0x94,
+		WIN_OEM_FJ_LOYA = 0x95,
+		WIN_OEM_FJ_ROYA = 0x96,
+		WIN_LSHIFT = 0xA0,
+		WIN_RSHIFT = 0xA1,
+		WIN_LCONTROL = 0xA2,
+		WIN_RCONTROL = 0xA3,
+		WIN_LMENU = 0xA4,
+		WIN_RMENU = 0xA5,
+		WIN_BROWSER_BACK = 0xA6,
+		WIN_BROWSER_FORWARD = 0xA7,
+		WIN_BROWSER_REFRESH = 0xA8,
+		WIN_BROWSER_STOP = 0xA9,
+		WIN_BROWSER_SEARCH = 0xAA,
+		WIN_BROWSER_FAVORITES = 0xAB,
+		WIN_BROWSER_HOME = 0xAC,
+		WIN_VOLUME_MUTE = 0xAD,
+		WIN_VOLUME_DOWN = 0xAE,
+		WIN_VOLUME_UP = 0xAF,
+		WIN_MEDIA_NEXT_TRACK = 0xB0,
+		WIN_MEDIA_PREV_TRACK = 0xB1,
+		WIN_MEDIA_STOP = 0xB2,
+		WIN_MEDIA_PLAY_PAUSE = 0xB3,
+		WIN_LAUNCH_MAIL = 0xB4,
+		WIN_LAUNCH_MEDIA_SELECT = 0xB5,
+		WIN_LAUNCH_APP1 = 0xB6,
+		WIN_LAUNCH_APP2 = 0xB7,
+		WIN_OEM_1 = 0xBA,
+		WIN_OEM_PLUS = 0xBB,
+		WIN_OEM_COMMA = 0xBC,
+		WIN_OEM_MINUS = 0xBD,
+		WIN_OEM_PERIOD = 0xBE,
+		WIN_OEM_2 = 0xBF,
+		WIN_OEM_3 = 0xC0,
+		WIN_GAMEPAD_A = 0xC3,
+		WIN_GAMEPAD_B = 0xC4,
+		WIN_GAMEPAD_X = 0xC5,
+		WIN_GAMEPAD_Y = 0xC6,
+		WIN_GAMEPAD_RIGHT_SHOULDER = 0xC7,
+		WIN_GAMEPAD_LEFT_SHOULDER = 0xC8,
+		WIN_GAMEPAD_LEFT_TRIGGER = 0xC9,
+		WIN_GAMEPAD_RIGHT_TRIGGER = 0xCA,
+		WIN_GAMEPAD_DPAD_UP = 0xCB,
+		WIN_GAMEPAD_DPAD_DOWN = 0xCC,
+		WIN_GAMEPAD_DPAD_LEFT = 0xCD,
+		WIN_GAMEPAD_DPAD_RIGHT = 0xCE,
+		WIN_GAMEPAD_MENU = 0xCF,
+		WIN_GAMEPAD_VIEW = 0xD0,
+		WIN_GAMEPAD_LEFT_THUMBSTICK_BUTTON = 0xD1,
+		WIN_GAMEPAD_RIGHT_THUMBSTICK_BUTTON = 0xD2,
+		WIN_GAMEPAD_LEFT_THUMBSTICK_UP = 0xD3,
+		WIN_GAMEPAD_LEFT_THUMBSTICK_DOWN = 0xD4,
+		WIN_GAMEPAD_LEFT_THUMBSTICK_RIGHT = 0xD5,
+		WIN_GAMEPAD_LEFT_THUMBSTICK_LEFT = 0xD6,
+		WIN_GAMEPAD_RIGHT_THUMBSTICK_UP = 0xD7,
+		WIN_GAMEPAD_RIGHT_THUMBSTICK_DOWN = 0xD8,
+		WIN_GAMEPAD_RIGHT_THUMBSTICK_RIGHT = 0xD9,
+		WIN_GAMEPAD_RIGHT_THUMBSTICK_LEFT = 0xDA,
+		WIN_OEM_4 = 0xDB,
+		WIN_OEM_5 = 0xDC,
+		WIN_OEM_6 = 0xDD,
+		WIN_OEM_7 = 0xDE,
+		WIN_OEM_8 = 0xDF,
+		WIN_OEM_AX = 0xE1,
+		WIN_OEM_102 = 0xE2,
+		WIN_ICO_HELP = 0xE3,
+		WIN_ICO_00 = 0xE4,
+		WIN_PROCESSKEY = 0xE5,
+		WIN_ICO_CLEAR = 0xE6,
+		WIN_PACKET = 0xE7,
+		WIN_OEM_RESET = 0xE9,
+		WIN_OEM_JUMP = 0xEA,
+		WIN_OEM_PA1 = 0xEB,
+		WIN_OEM_PA2 = 0xEC,
+		WIN_OEM_PA3 = 0xED,
+		WIN_OEM_WSCTRL = 0xEE,
+		WIN_OEM_CUSEL = 0xEF,
+		WIN_OEM_ATTN = 0xF0,
+		WIN_OEM_FINISH = 0xF1,
+		WIN_OEM_COPY = 0xF2,
+		WIN_OEM_AUTO = 0xF3,
+		WIN_OEM_ENLW = 0xF4,
+		WIN_OEM_BACKTAB = 0xF5,
+		WIN_ATTN = 0xF6,
+		WIN_CRSEL = 0xF7,
+		WIN_EXSEL = 0xF8,
+		WIN_EREOF = 0xF9,
+		WIN_PLAY = 0xFA,
+		WIN_ZOOM = 0xFB,
+		WIN_NONAME = 0xFC,
+		WIN_PA1 = 0xFD,
+		WIN_OEM_CLEAR = 0xFE
+	};
 
 private:
-    static KeyCodes _instance;
+	static KeyCodes _instance;
 
-    uint8 _winCodes[Common::KEYCODE_LAST];
-    uint16 _scummCodes[256];
+	uint8 _winCodes[Common::KEYCODE_LAST];
+	uint16 _scummCodes[256];
 
 private:
-    KeyCodes();
+	KeyCodes();
 
 public:
-    static uint8 GetWinCode(uint16 code) { return _instance._winCodes[code]; };
-    static uint16 GetScummCode(uint8 code) {return _instance._scummCodes[code]; };
+	static uint8 GetWinCode(uint16 code) {
+		return _instance._winCodes[code];
+	};
+	static uint16 GetScummCode(uint8 code) {
+		return _instance._scummCodes[code];
+	};
 };
 
 
 };
 
 
- #endif
+#endif
diff --git a/engines/gamos/metaengine.cpp b/engines/gamos/metaengine.cpp
index 2e785232a41..97ab6298757 100644
--- a/engines/gamos/metaengine.cpp
+++ b/engines/gamos/metaengine.cpp
@@ -36,7 +36,7 @@ Common::Error GamosMetaEngine::createInstance(OSystem *syst, Engine **engine, co
 
 bool GamosMetaEngine::hasFeature(MetaEngineFeature f) const {
 	return checkExtendedSaves(f) ||
-		(f == kSupportsLoadingDuringStartup);
+	       (f == kSupportsLoadingDuringStartup);
 }
 
 #if PLUGIN_ENABLED_DYNAMIC(GAMOS)
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index e37c9b2305e..b14204758bc 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -24,576 +24,573 @@
 namespace Gamos {
 
 bool MoviePlayer::init(Common::File *file, uint32 offset, GamosEngine *gamos) {
-    _gamos = gamos;
-    _screen = _gamos->_screen;
-    _messageProc = &_gamos->_messageProc;
-
-
-    _loopCount = 1;
-    _pos = Common::Point();
-    _midiBufferSize = 0;
-    _soundBufferSize = 0;
-    _paletteBufferSize = 0;
-    _bufferSize = 0;
-    _packedBufferSize = 0;
-    _frameTime = 0;
-    _loopPoint = 0;
-    _midiBuffer.clear();
-    _soundBuffer.clear();
-    _paletteBuffer.clear();
-    _buffer.clear();
-    _packedBuffer.clear();
-    _midiStarted = false;
-    _soundPlaying = false;
-    _frameSize = Common::Point(_screen->w, _screen->h);
-
-    _gamos->stopMidi();
-    _gamos->stopMCI();
-
-    _file = file;
-    return _file->seek(offset, SEEK_SET);
+	_gamos = gamos;
+	_screen = _gamos->_screen;
+	_messageProc = &_gamos->_messageProc;
+
+
+	_loopCount = 1;
+	_pos = Common::Point();
+	_midiBufferSize = 0;
+	_soundBufferSize = 0;
+	_paletteBufferSize = 0;
+	_bufferSize = 0;
+	_packedBufferSize = 0;
+	_frameTime = 0;
+	_loopPoint = 0;
+	_midiBuffer.clear();
+	_soundBuffer.clear();
+	_paletteBuffer.clear();
+	_buffer.clear();
+	_packedBuffer.clear();
+	_midiStarted = false;
+	_soundPlaying = false;
+	_frameSize = Common::Point(_screen->w, _screen->h);
+
+	_gamos->stopMidi();
+	_gamos->stopMCI();
+
+	_file = file;
+	return _file->seek(offset, SEEK_SET);
 }
 
 bool MoviePlayer::deinit() {
-    if (_soundPlaying)
-        _gamos->stopSounds();
+	if (_soundPlaying)
+		_gamos->stopSounds();
 
-    _gamos->stopMidi();
-    _gamos->stopMCI();
+	_gamos->stopMidi();
+	_gamos->stopMCI();
 
-    _gamos->setPaletteCurrentGS();
+	_gamos->setPaletteCurrentGS();
 
-    _file = nullptr;
-    return true;
+	_file = nullptr;
+	return true;
 }
 
 bool MoviePlayer::playMovie(Common::File *file, uint32 offset, GamosEngine *gamos) {
-    if (!init(file, offset, gamos))
-        return error();
-
-    while (true) {
-        int status = 0;
-
-        readHdr();
-
-        switch(_hdrBytes[0]) {
-            case 0:
-            status = processControlChunk();
-            break;
-
-            case 1:
-            status = processImageChunk();
-            break;
-
-            case 2:
-            status = processPaletteChunk();
-            break;
-
-            case 3:
-            status = processSoundChunk();
-            break;
-
-            case 4:
-            status = proccessMidiChunk();
-            break;
-
-            default:
-            break;
-        }
-
-        while(true)
-        {
-            if (status == 2) {
-                while(true) {
-                    if ( !readHdr() )
-                        return error();
-                    if (_hdrBytes[0] == 0) {
-                        if (_hdrBytes[1] == 0 || _hdrBytes[1] == 1)
-                            break;
-                    } else {
-                        if (!_file->seek(_hdrValue1, SEEK_CUR))
-                            return error();
-                    }
-                }
-                status = processControlChunk();
-            } else if (status == 0) {
-                return error();
-            } else if (status == 3) {
-                return deinit();
-            } else {
-                break;
-            }
-        }
-    }
-
-    return deinit();
+	if (!init(file, offset, gamos))
+		return error();
+
+	while (true) {
+		int status = 0;
+
+		readHdr();
+
+		switch (_hdrBytes[0]) {
+		case 0:
+			status = processControlChunk();
+			break;
+
+		case 1:
+			status = processImageChunk();
+			break;
+
+		case 2:
+			status = processPaletteChunk();
+			break;
+
+		case 3:
+			status = processSoundChunk();
+			break;
+
+		case 4:
+			status = proccessMidiChunk();
+			break;
+
+		default:
+			break;
+		}
+
+		while (true) {
+			if (status == 2) {
+				while (true) {
+					if (!readHdr())
+						return error();
+					if (_hdrBytes[0] == 0) {
+						if (_hdrBytes[1] == 0 || _hdrBytes[1] == 1)
+							break;
+					} else {
+						if (!_file->seek(_hdrValue1, SEEK_CUR))
+							return error();
+					}
+				}
+				status = processControlChunk();
+			} else if (status == 0) {
+				return error();
+			} else if (status == 3) {
+				return deinit();
+			} else {
+				break;
+			}
+		}
+	}
+
+	return deinit();
 }
 
 bool MoviePlayer::error() {
-    deinit();
-    _gamos->setErrMessage("Movie playback error.");
-    return false;
+	deinit();
+	_gamos->setErrMessage("Movie playback error.");
+	return false;
 }
 
 int MoviePlayer::processControlChunk() {
-    warning("%x movieProcessControl %d", (uint32)_file->pos(), _hdrBytes[1]);
-
-    switch(_hdrBytes[1]) {
-    case 0:
-        if ((uint32_t)_hdrValue1 != 0x563d2d5b || (uint32_t)_hdrValue2 != 0x5d2d3d53) {
-            error();
-            return 0;
-        }
-        return 3;
-
-    case 1:
-        _loopCount = 1;
-        _loopPoint = 0;
-
-        if (_hdrBytes[2] != 0)
-            _loopCount = _hdrValue1;
-
-        if (_hdrBytes[3] != 0)
-            _frameTime = _hdrValue2;
-        break;
-
-    case 2:
-        if (_hdrBytes[2] != 0) {
-            _packedBufferSize = _hdrValue1;
-            _packedBuffer.resize(_hdrValue1);
-        }
-        break;
-
-    case 3:
-        if (_hdrBytes[2] != 0) {
-            _bufferSize = _hdrValue1;
-            _buffer.resize(_hdrValue1);
-        }
-        if (_hdrBytes[3] != 0) {
-            _paletteBufferSize = _hdrValue2;
-            _paletteBuffer.resize(_hdrValue2);
-        }
-        break;
-
-    case 4:
-        if (_hdrBytes[2] != 0) {
-            _soundBufferSize = _hdrValue1;
-            _soundBuffer.resize(_hdrValue1);
-        }
-        if (_hdrBytes[3] != 0) {
-            _midiBufferSize = _hdrValue2;
-            _midiBuffer.resize(_hdrValue2);
-        }
-        break;
-
-    case 5:
-        if (_hdrBytes[2] != 0) {
-            _pos.x = _hdrValue1;
-        }
-        if (_hdrBytes[3] != 0) {
-            _pos.y = _hdrValue2; /* BUG? Originally here same _pos.x */
-        }
-        break;
-
-    case 6:
-        if (_hdrBytes[2] != 0) {
-            _frameSize.x = _hdrValue1;
-        }
-        if (_hdrBytes[3] != 0) {
-            _frameSize.y = _hdrValue2;
-        }
-        break;
-
-    }
-    return 1;
+	warning("%x movieProcessControl %d", (uint32)_file->pos(), _hdrBytes[1]);
+
+	switch (_hdrBytes[1]) {
+	case 0:
+		if ((uint32_t)_hdrValue1 != 0x563d2d5b || (uint32_t)_hdrValue2 != 0x5d2d3d53) {
+			error();
+			return 0;
+		}
+		return 3;
+
+	case 1:
+		_loopCount = 1;
+		_loopPoint = 0;
+
+		if (_hdrBytes[2] != 0)
+			_loopCount = _hdrValue1;
+
+		if (_hdrBytes[3] != 0)
+			_frameTime = _hdrValue2;
+		break;
+
+	case 2:
+		if (_hdrBytes[2] != 0) {
+			_packedBufferSize = _hdrValue1;
+			_packedBuffer.resize(_hdrValue1);
+		}
+		break;
+
+	case 3:
+		if (_hdrBytes[2] != 0) {
+			_bufferSize = _hdrValue1;
+			_buffer.resize(_hdrValue1);
+		}
+		if (_hdrBytes[3] != 0) {
+			_paletteBufferSize = _hdrValue2;
+			_paletteBuffer.resize(_hdrValue2);
+		}
+		break;
+
+	case 4:
+		if (_hdrBytes[2] != 0) {
+			_soundBufferSize = _hdrValue1;
+			_soundBuffer.resize(_hdrValue1);
+		}
+		if (_hdrBytes[3] != 0) {
+			_midiBufferSize = _hdrValue2;
+			_midiBuffer.resize(_hdrValue2);
+		}
+		break;
+
+	case 5:
+		if (_hdrBytes[2] != 0) {
+			_pos.x = _hdrValue1;
+		}
+		if (_hdrBytes[3] != 0) {
+			_pos.y = _hdrValue2; /* BUG? Originally here same _pos.x */
+		}
+		break;
+
+	case 6:
+		if (_hdrBytes[2] != 0) {
+			_frameSize.x = _hdrValue1;
+		}
+		if (_hdrBytes[3] != 0) {
+			_frameSize.y = _hdrValue2;
+		}
+		break;
+
+	}
+	return 1;
 }
 
 int MoviePlayer::processImageChunk() {
-    warning("%x movieProcessImageChunk %d", (uint32)_file->pos(), _hdrValue1);
-    if (!readCompressed(_bufferSize, &_buffer))
-        return 0;
-
-    bool keepAct = true;
-
-    if (_hdrBytes[1] == 1) {
-        _forceStopMidi = false;
-        //waveoutrestart()
-        _screen->fillRect(_screen->getBounds(), _hdrBytes[3]);
-        if (_loopCount > 1)
-            _loopPoint = _file->pos();
-        keepAct = false;
-        _doUpdateScreen = false;
-    }
-    else if (_hdrBytes[1] == 2) {
-        _forceStopMidi = true;
-        _loopCount--;
-        if (_loopCount != 0)
-            _file->seek(_loopPoint, 0);
-    }
-
-    if (_hdrValue1 != 0) {
-        byte *pdata = _buffer.data();
-        Common::Point xy;
-        Common::Point wh;
-
-        while (true) {
-            byte val = *pdata;
-            pdata++;
-            if ( (val & 0x40) == 0 ) {
-                xy.x = _pos.x + *pdata;
-                pdata++;
-
-                if ( (val & 4) != 0 ) {
-                    xy.x += *pdata * 256;
-                    pdata++;
-                }
-
-                xy.y = _pos.y + *pdata;
-                pdata++;
-
-                if ( (val & 8) != 0 ) {
-                    xy.y += *pdata * 256;
-                    pdata++;
-                }
-
-                wh.x = *pdata;
-                pdata++;
-
-                if ( (val & 0x10) != 0 ) {
-                    wh.x += *pdata * 256;
-                    pdata++;
-                }
-
-                wh.y = *pdata;
-                pdata++;
-
-                if ( (val & 0x20) != 0 ) {
-                    wh.y += *pdata * 256;
-                    pdata++;
-                }
-            } else {
-                xy = _pos;
-                wh = _frameSize;
-            }
-
-            warning("movie blit%d %d %d %d %d", val & 3, xy.x, xy.y, wh.x, wh.y);
-            static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) =
-               {&blit0,
-                &blit1,
-                &blit2,
-                &blit3};
-
-            pdata = blitters[val & 3](Common::Rect(xy, xy + wh), pdata, _screen->surfacePtr());
-
-            if (_doUpdateScreen) {
-                _gamos->updateScreen(false, Common::Rect(xy, xy + wh));
-            }
-
-            if (val & 0x80)
-                break;
-        }
-
-    }
-
-    if (_doUpdateScreen)
-        _gamos->flushDirtyRects(true);
-
-    uint32 tstamp = 0;
-    uint8 act = processMessages(keepAct, &tstamp);
-
-    if (act == ACT2_82)
-        return 2;
-
-    if (act == ACT2_83)
-        return 3;
-
-    if (_hdrBytes[1] == 1) {
-        _gamos->updateScreen(_gamos->_fadeEffectID != 0, Common::Rect(_pos, _pos + _frameSize));
-
-        _firstFrameTime = g_system->getMillis();
-        _currentFrame = 0;
-        _skippedFrames = 0;
-        _doUpdateScreen = true;
-    } else if (_frameTime == 0) {
-        _doUpdateScreen = true;
-    } else {
-        int32 dtime = (tstamp - _firstFrameTime) / _currentFrame;
-        if (dtime > _frameTime) {
-            if (_soundBufferSize) {
-                _skippedFrames++;
-                if (_skippedFrames != 8)
-                    _doUpdateScreen = false;
-            }
-        }
-        else if (dtime < _frameTime) {
-            while (true) {
-                act = processMessages(false, &tstamp);
-                if (act == ACT2_82)
-                    return 2;
-
-                if (act == ACT2_83)
-                    return 3;
-
-                if ((tstamp - _firstFrameTime) / _currentFrame >= _frameTime)
-                    break;
-
-                g_system->delayMillis(1);
-            }
-        }
-
-        _skippedFrames = 0;
-        _doUpdateScreen = true;
-    }
-
-    _screen->update();
-    _currentFrame++;
-
-    return 1;
+	warning("%x movieProcessImageChunk %d", (uint32)_file->pos(), _hdrValue1);
+	if (!readCompressed(_bufferSize, &_buffer))
+		return 0;
+
+	bool keepAct = true;
+
+	if (_hdrBytes[1] == 1) {
+		_forceStopMidi = false;
+		//waveoutrestart()
+		_screen->fillRect(_screen->getBounds(), _hdrBytes[3]);
+		if (_loopCount > 1)
+			_loopPoint = _file->pos();
+		keepAct = false;
+		_doUpdateScreen = false;
+	} else if (_hdrBytes[1] == 2) {
+		_forceStopMidi = true;
+		_loopCount--;
+		if (_loopCount != 0)
+			_file->seek(_loopPoint, 0);
+	}
+
+	if (_hdrValue1 != 0) {
+		byte *pdata = _buffer.data();
+		Common::Point xy;
+		Common::Point wh;
+
+		while (true) {
+			byte val = *pdata;
+			pdata++;
+			if ((val & 0x40) == 0) {
+				xy.x = _pos.x + *pdata;
+				pdata++;
+
+				if ((val & 4) != 0) {
+					xy.x += *pdata * 256;
+					pdata++;
+				}
+
+				xy.y = _pos.y + *pdata;
+				pdata++;
+
+				if ((val & 8) != 0) {
+					xy.y += *pdata * 256;
+					pdata++;
+				}
+
+				wh.x = *pdata;
+				pdata++;
+
+				if ((val & 0x10) != 0) {
+					wh.x += *pdata * 256;
+					pdata++;
+				}
+
+				wh.y = *pdata;
+				pdata++;
+
+				if ((val & 0x20) != 0) {
+					wh.y += *pdata * 256;
+					pdata++;
+				}
+			} else {
+				xy = _pos;
+				wh = _frameSize;
+			}
+
+			warning("movie blit%d %d %d %d %d", val & 3, xy.x, xy.y, wh.x, wh.y);
+			static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) = {
+				&blit0,
+				&blit1,
+				&blit2,
+				&blit3
+			};
+
+			pdata = blitters[val & 3](Common::Rect(xy, xy + wh), pdata, _screen->surfacePtr());
+
+			if (_doUpdateScreen) {
+				_gamos->updateScreen(false, Common::Rect(xy, xy + wh));
+			}
+
+			if (val & 0x80)
+				break;
+		}
+
+	}
+
+	if (_doUpdateScreen)
+		_gamos->flushDirtyRects(true);
+
+	uint32 tstamp = 0;
+	uint8 act = processMessages(keepAct, &tstamp);
+
+	if (act == ACT2_82)
+		return 2;
+
+	if (act == ACT2_83)
+		return 3;
+
+	if (_hdrBytes[1] == 1) {
+		_gamos->updateScreen(_gamos->_fadeEffectID != 0, Common::Rect(_pos, _pos + _frameSize));
+
+		_firstFrameTime = g_system->getMillis();
+		_currentFrame = 0;
+		_skippedFrames = 0;
+		_doUpdateScreen = true;
+	} else if (_frameTime == 0) {
+		_doUpdateScreen = true;
+	} else {
+		int32 dtime = (tstamp - _firstFrameTime) / _currentFrame;
+		if (dtime > _frameTime) {
+			if (_soundBufferSize) {
+				_skippedFrames++;
+				if (_skippedFrames != 8)
+					_doUpdateScreen = false;
+			}
+		} else if (dtime < _frameTime) {
+			while (true) {
+				act = processMessages(false, &tstamp);
+				if (act == ACT2_82)
+					return 2;
+
+				if (act == ACT2_83)
+					return 3;
+
+				if ((tstamp - _firstFrameTime) / _currentFrame >= _frameTime)
+					break;
+
+				g_system->delayMillis(1);
+			}
+		}
+
+		_skippedFrames = 0;
+		_doUpdateScreen = true;
+	}
+
+	_screen->update();
+	_currentFrame++;
+
+	return 1;
 }
 
 int MoviePlayer::processPaletteChunk() {
-    warning("%x movieProcessPaletteChunk", (uint32)_file->pos());
-    if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
-        return 0;
+	warning("%x movieProcessPaletteChunk", (uint32)_file->pos());
+	if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
+		return 0;
 
-    if (!_gamos->usePalette(_paletteBuffer.data(), 256,  _gamos->_fadeEffectID, false))
-        return 0;
+	if (!_gamos->usePalette(_paletteBuffer.data(), 256,  _gamos->_fadeEffectID, false))
+		return 0;
 
-    return 1;
+	return 1;
 }
 
 int MoviePlayer::processSoundChunk() {
-    warning("%x movieProcessSoundChunk", (uint32)_file->pos());
-    if (!readCompressed(_soundBufferSize, &_soundBuffer))
-        return 0;
-    return 1;
+	warning("%x movieProcessSoundChunk", (uint32)_file->pos());
+	if (!readCompressed(_soundBufferSize, &_soundBuffer))
+		return 0;
+	return 1;
 }
 
 int MoviePlayer::proccessMidiChunk() {
-    warning("%x movieProcessMidiChunk", (uint32)_file->pos());
+	warning("%x movieProcessMidiChunk", (uint32)_file->pos());
 
-    if (_midiStarted && (_forceStopMidi == false || _hdrBytes[1] != 0)) {
-        _gamos->stopMidi();
-        _midiStarted = false;
-    }
+	if (_midiStarted && (_forceStopMidi == false || _hdrBytes[1] != 0)) {
+		_gamos->stopMidi();
+		_midiStarted = false;
+	}
 
-    if (_hdrValue1 == 0)
-        return 1;
+	if (_hdrValue1 == 0)
+		return 1;
 
-    if (_midiStarted) {
-        if ( !_file->seek(_hdrValue1, SEEK_CUR) )
-            return 0;
-        return 1;
-    }
+	if (_midiStarted) {
+		if (!_file->seek(_hdrValue1, SEEK_CUR))
+			return 0;
+		return 1;
+	}
 
-    if (!readCompressed(_midiBufferSize, &_midiBuffer)) {
-        _midiStarted = false;
-        return 0;
-    }
+	if (!readCompressed(_midiBufferSize, &_midiBuffer)) {
+		_midiStarted = false;
+		return 0;
+	}
 
-    _midiStarted = _gamos->playMidi(&_midiBuffer);
+	_midiStarted = _gamos->playMidi(&_midiBuffer);
 
-    return 1;
+	return 1;
 }
 
 bool MoviePlayer::readHdr() {
-    _file->read(_hdrBytes, 4);
-    _hdrValue1 = _file->readSint32LE();
-    _hdrValue2 = _file->readSint32LE();
-    return true;
+	_file->read(_hdrBytes, 4);
+	_hdrValue1 = _file->readSint32LE();
+	_hdrValue2 = _file->readSint32LE();
+	return true;
 }
 
 bool MoviePlayer::readCompressed(int32_t count, Common::Array<byte> *buf) {
-    if (_hdrValue1 == 0)
-        return true;
-
-    if (_hdrValue1 != _hdrValue2) {
-        _packedBuffer.resize(_hdrValue1);
-        _file->read(_packedBuffer.data(), _hdrValue1);
-        buf->resize(_hdrValue2);
-        Archive::decompress(&_packedBuffer, buf);
-    }
-    else {
-        buf->resize(_hdrValue1);
-        _file->read(buf->data(), _hdrValue1);
-    }
-    return true;
+	if (_hdrValue1 == 0)
+		return true;
+
+	if (_hdrValue1 != _hdrValue2) {
+		_packedBuffer.resize(_hdrValue1);
+		_file->read(_packedBuffer.data(), _hdrValue1);
+		buf->resize(_hdrValue2);
+		Archive::decompress(&_packedBuffer, buf);
+	} else {
+		buf->resize(_hdrValue1);
+		_file->read(buf->data(), _hdrValue1);
+	}
+	return true;
 }
 
-byte* MoviePlayer::blit0(Common::Rect rect, byte *in, Graphics::Surface *surface) {
-    int16 y = rect.top;
-    while (y < rect.bottom) {
-        const int count = rect.width();
-        byte *out = (byte *)surface->getBasePtr(rect.left, y);
-        for (int i = 0; i < count; i++) {
-            *out += *in;
-            in++;
-            out++;
-        }
-        y++;
-    }
-    return in;
+byte *MoviePlayer::blit0(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+	int16 y = rect.top;
+	while (y < rect.bottom) {
+		const int count = rect.width();
+		byte *out = (byte *)surface->getBasePtr(rect.left, y);
+		for (int i = 0; i < count; i++) {
+			*out += *in;
+			in++;
+			out++;
+		}
+		y++;
+	}
+	return in;
 }
 
-byte* MoviePlayer::blit1(Common::Rect rect, byte *in, Graphics::Surface *surface) {
-    int16 y = rect.top;
-    int16 x = rect.left;
-    while (y < rect.bottom) {
-
-        byte b = *in;
-        in++;
-        if (b & 0x80) {
-            if ((b & 0x40) == 0) {
-                int count = (b & 0x3f) + 1;
-                byte *out = (byte *)surface->getBasePtr(x, y);
-                for (int i = 0; i < count; i++) {
-                    *out += *in;
-                    in++;
-                    out++;
-                }
-                x += count;
-            } else {
-                if ((b & 0x3f) == 0)
-                    x = rect.right;
-                else {
-                    if ((b & 0x3f) != 1) {
-                        int count = (b & 0x3f) + 1;
-                        byte val = *in;
-                        in++;
-                        byte *out = (byte *)surface->getBasePtr(x, y);
-                        for (int i = 0; i < count; i++) {
-                            *out += val;
-                            out++;
-                        }
-                        x += count;
-                    } else {
-                        int count = rect.right - x;
-                        byte *out = (byte *)surface->getBasePtr(x, y);
-                        for (int i = 0; i < count; i++) {
-                            *out += *in;
-                            in++;
-                            out++;
-                        }
-                        x = rect.right;
-                    }
-                }
-            }
-        } else {
-            x += b + 1;
-        }
-
-        if (x >= rect.right) {
-            y++;
-            x = rect.left;
-        }
-    }
-    return in;
+byte *MoviePlayer::blit1(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+	int16 y = rect.top;
+	int16 x = rect.left;
+	while (y < rect.bottom) {
+
+		byte b = *in;
+		in++;
+		if (b & 0x80) {
+			if ((b & 0x40) == 0) {
+				int count = (b & 0x3f) + 1;
+				byte *out = (byte *)surface->getBasePtr(x, y);
+				for (int i = 0; i < count; i++) {
+					*out += *in;
+					in++;
+					out++;
+				}
+				x += count;
+			} else {
+				if ((b & 0x3f) == 0)
+					x = rect.right;
+				else {
+					if ((b & 0x3f) != 1) {
+						int count = (b & 0x3f) + 1;
+						byte val = *in;
+						in++;
+						byte *out = (byte *)surface->getBasePtr(x, y);
+						for (int i = 0; i < count; i++) {
+							*out += val;
+							out++;
+						}
+						x += count;
+					} else {
+						int count = rect.right - x;
+						byte *out = (byte *)surface->getBasePtr(x, y);
+						for (int i = 0; i < count; i++) {
+							*out += *in;
+							in++;
+							out++;
+						}
+						x = rect.right;
+					}
+				}
+			}
+		} else {
+			x += b + 1;
+		}
+
+		if (x >= rect.right) {
+			y++;
+			x = rect.left;
+		}
+	}
+	return in;
 }
 
-byte* MoviePlayer::blit2(Common::Rect rect, byte *in, Graphics::Surface *surface) {
-    int16 y = rect.top;
-    int16 x = rect.left;
-    while (y < rect.bottom) {
-
-        byte b = *in;
-        in++;
-        if (b & 0x80) {
-            if ((b & 0x40) == 0) {
-                x += (b & 0x3f) + 1;
-            } else {
-                int count = (b & 0x3f) + 1;
-                byte *out = (byte *)surface->getBasePtr(x, y);
-                for (int i = 0; i < count; i++) {
-                    *out += *in;
-                    in++;
-                    out++;
-                }
-                x += count;
-            }
-        } else if (b == 0) {
-            x += b + 1;
-        } else if (b != 1) {
-            int count = b + 1;
-            byte val = *in;
-            in++;
-            byte *out = (byte *)surface->getBasePtr(x, y);
-            for (int i = 0; i < count; i++) {
-                *out += val;
-                out++;
-            }
-            x += count;
-        } else {
-            int count = rect.right - x;
-            byte *out = (byte *)surface->getBasePtr(x, y);
-            for (int i = 0; i < count; i++) {
-                *out += *in;
-                in++;
-                out++;
-            }
-            x = rect.right;
-        }
-
-        if (x >= rect.right) {
-            y++;
-            x = rect.left;
-        }
-    }
-    return in;
+byte *MoviePlayer::blit2(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+	int16 y = rect.top;
+	int16 x = rect.left;
+	while (y < rect.bottom) {
+
+		byte b = *in;
+		in++;
+		if (b & 0x80) {
+			if ((b & 0x40) == 0) {
+				x += (b & 0x3f) + 1;
+			} else {
+				int count = (b & 0x3f) + 1;
+				byte *out = (byte *)surface->getBasePtr(x, y);
+				for (int i = 0; i < count; i++) {
+					*out += *in;
+					in++;
+					out++;
+				}
+				x += count;
+			}
+		} else if (b == 0) {
+			x += b + 1;
+		} else if (b != 1) {
+			int count = b + 1;
+			byte val = *in;
+			in++;
+			byte *out = (byte *)surface->getBasePtr(x, y);
+			for (int i = 0; i < count; i++) {
+				*out += val;
+				out++;
+			}
+			x += count;
+		} else {
+			int count = rect.right - x;
+			byte *out = (byte *)surface->getBasePtr(x, y);
+			for (int i = 0; i < count; i++) {
+				*out += *in;
+				in++;
+				out++;
+			}
+			x = rect.right;
+		}
+
+		if (x >= rect.right) {
+			y++;
+			x = rect.left;
+		}
+	}
+	return in;
 }
 
-byte* MoviePlayer::blit3(Common::Rect rect, byte *in, Graphics::Surface *surface) {
-    int16 y = rect.top;
-    int16 x = rect.left;
-    while (y < rect.bottom) {
-
-        byte b = *in;
-        in++;
-        if (b & 0x80) {
-            if ((b & 0x40) == 0) {
-                x += (b & 0x3f) + 1;
-            } else {
-                if ((b & 0x3f) == 0)
-                    x = rect.right;
-                else {
-                    if ((b & 0x3f) != 1) {
-                        int count = (b & 0x3f) + 1;
-                        byte val = *in;
-                        in++;
-                        byte *out = (byte *)surface->getBasePtr(x, y);
-                        for (int i = 0; i < count; i++) {
-                            *out += val;
-                            out++;
-                        }
-                        x += count;
-                    } else {
-                        int count = rect.right - x;
-                        byte *out = (byte *)surface->getBasePtr(x, y);
-                        for (int i = 0; i < count; i++) {
-                            *out += *in;
-                            in++;
-                            out++;
-                        }
-                        x = rect.right;
-                    }
-                }
-            }
-        } else {
-            int count = b + 1;
-            byte *out = (byte *)surface->getBasePtr(x, y);
-            for (int i = 0; i < count; i++) {
-                *out += *in;
-                in++;
-                out++;
-            }
-            x += count;
-        }
-
-        if (x >= rect.right) {
-            y++;
-            x = rect.left;
-        }
-    }
-    return in;
+byte *MoviePlayer::blit3(Common::Rect rect, byte *in, Graphics::Surface *surface) {
+	int16 y = rect.top;
+	int16 x = rect.left;
+	while (y < rect.bottom) {
+
+		byte b = *in;
+		in++;
+		if (b & 0x80) {
+			if ((b & 0x40) == 0) {
+				x += (b & 0x3f) + 1;
+			} else {
+				if ((b & 0x3f) == 0)
+					x = rect.right;
+				else {
+					if ((b & 0x3f) != 1) {
+						int count = (b & 0x3f) + 1;
+						byte val = *in;
+						in++;
+						byte *out = (byte *)surface->getBasePtr(x, y);
+						for (int i = 0; i < count; i++) {
+							*out += val;
+							out++;
+						}
+						x += count;
+					} else {
+						int count = rect.right - x;
+						byte *out = (byte *)surface->getBasePtr(x, y);
+						for (int i = 0; i < count; i++) {
+							*out += *in;
+							in++;
+							out++;
+						}
+						x = rect.right;
+					}
+				}
+			}
+		} else {
+			int count = b + 1;
+			byte *out = (byte *)surface->getBasePtr(x, y);
+			for (int i = 0; i < count; i++) {
+				*out += *in;
+				in++;
+				out++;
+			}
+			x += count;
+		}
+
+		if (x >= rect.right) {
+			y++;
+			x = rect.left;
+		}
+	}
+	return in;
 }
 
 
diff --git a/engines/gamos/movie.h b/engines/gamos/movie.h
index 339a40fd5be..f2f3d5b2387 100644
--- a/engines/gamos/movie.h
+++ b/engines/gamos/movie.h
@@ -25,20 +25,19 @@
 
 #include "common/file.h"
 
-namespace Gamos
-{
+namespace Gamos {
 
 class GamosEngine;
 
 class MoviePlayer {
-    public:
+public:
 
-    bool playMovie(Common::File *file, uint32 offset, GamosEngine *gamos);
+	bool playMovie(Common::File *file, uint32 offset, GamosEngine *gamos);
 
 
-    private:
+private:
 
-    bool init(Common::File *file, uint32 offset, GamosEngine *gamos);
+	bool init(Common::File *file, uint32 offset, GamosEngine *gamos);
 	bool deinit();
 	bool error();
 
@@ -53,21 +52,21 @@ class MoviePlayer {
 
 	uint8 processMessages(bool keepAct, uint32 *msecs);
 
-	static byte* blit0(Common::Rect rect, byte *in, Graphics::Surface *surface);
-	static byte* blit1(Common::Rect rect, byte *in, Graphics::Surface *surface);
-	static byte* blit2(Common::Rect rect, byte *in, Graphics::Surface *surface);
-	static byte* blit3(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte *blit0(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte *blit1(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte *blit2(Common::Rect rect, byte *in, Graphics::Surface *surface);
+	static byte *blit3(Common::Rect rect, byte *in, Graphics::Surface *surface);
 
 
 
-    private:
+private:
 
-    GamosEngine *_gamos = nullptr;
-    Graphics::Screen *_screen = nullptr;
-    SystemProc *_messageProc = nullptr;
+	GamosEngine *_gamos = nullptr;
+	Graphics::Screen *_screen = nullptr;
+	SystemProc *_messageProc = nullptr;
 
 
-    bool _doUpdateScreen = false;
+	bool _doUpdateScreen = false;
 	uint32 _skippedFrames = 0;
 	uint32 _currentFrame = 0;
 	uint32 _firstFrameTime = 0;
@@ -75,26 +74,26 @@ class MoviePlayer {
 	bool _forceStopMidi = false;
 
 	int _loopCount = 1;
-    int _loopPoint = 0;
+	int _loopPoint = 0;
 
 	Common::Point _pos; /* Movie frame leftup corner */
 	Common::Point _frameSize; /* Sizes of movie frame */
 
-    int _midiBufferSize = 0;
-    int _soundBufferSize = 0;
-    int _paletteBufferSize = 0;
-    int _bufferSize = 0;
-    int _packedBufferSize = 0;
-    int _frameTime = 0;
-
-    Common::Array<byte> _midiBuffer;
-    Common::Array<byte> _soundBuffer;
-    Common::Array<byte> _paletteBuffer;
-    Common::Array<byte> _buffer;
-    Common::Array<byte> _packedBuffer;
-
-    bool _midiStarted = false;
-    bool _soundPlaying = false;
+	int _midiBufferSize = 0;
+	int _soundBufferSize = 0;
+	int _paletteBufferSize = 0;
+	int _bufferSize = 0;
+	int _packedBufferSize = 0;
+	int _frameTime = 0;
+
+	Common::Array<byte> _midiBuffer;
+	Common::Array<byte> _soundBuffer;
+	Common::Array<byte> _paletteBuffer;
+	Common::Array<byte> _buffer;
+	Common::Array<byte> _packedBuffer;
+
+	bool _midiStarted = false;
+	bool _soundPlaying = false;
 
 	Common::File *_file = nullptr;
 
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index 0c837e83610..813dc40bd29 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -25,166 +25,166 @@
 namespace Gamos {
 
 MidiMusic::MidiMusic() {
-    MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_GM);
+	MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_GM);
 
-    _driver = MidiDriver::createMidi(dev);
-    _driver->open();
-    _driver->sendGMReset();
+	_driver = MidiDriver::createMidi(dev);
+	_driver->open();
+	_driver->sendGMReset();
 }
 
 MidiMusic::~MidiMusic() {
-    g_system->getTimerManager()->removeTimerProc(_timerProc);
+	g_system->getTimerManager()->removeTimerProc(_timerProc);
 
-    if (_driver) {
-        _driver->stopAllNotes(true);
-        _driver->close();
-        delete _driver;
-    }
+	if (_driver) {
+		_driver->stopAllNotes(true);
+		_driver->close();
+		delete _driver;
+	}
 }
 
 void MidiMusic::stopMusic() {
-    g_system->getTimerManager()->removeTimerProc(_timerProc);
+	g_system->getTimerManager()->removeTimerProc(_timerProc);
 
-    if (_mutex.lock()) {
-        _driver->stopAllNotes(true);
+	if (_mutex.lock()) {
+		_driver->stopAllNotes(true);
 
-        _mutex.unlock();
-    }
+		_mutex.unlock();
+	}
 }
 
 bool MidiMusic::playMusic(Common::Array<byte> *midiData) {
-    stopMusic();
+	stopMusic();
 
-    if (!midiData || midiData->size() <= 4)
-        return false;
+	if (!midiData || midiData->size() <= 4)
+		return false;
 
-    if (!_mutex.lock())
-        return false;
+	if (!_mutex.lock())
+		return false;
 
-    _pMidiData.clear();
-    _pMidiData.swap(*midiData);
+	_pMidiData.clear();
+	_pMidiData.swap(*midiData);
 
-    _dataStart = 4;
-    _dataPos = _dataStart;
-    _midiDelayTicks = 1;
-    _midiDelayCount = 1;
+	_dataStart = 4;
+	_dataPos = _dataStart;
+	_midiDelayTicks = 1;
+	_midiDelayCount = 1;
 
-    if (_pMidiData[_dataPos] == 0xf8) {
-        _dataPos++;
-        midi2low();
-        _dataPos++;
-    }
+	if (_pMidiData[_dataPos] == 0xf8) {
+		_dataPos++;
+		midi2low();
+		_dataPos++;
+	}
 
-    g_system->getTimerManager()->installTimerProc(_timerProc, 10 * 1000, this, "Gamos::Music");
+	g_system->getTimerManager()->installTimerProc(_timerProc, 10 * 1000, this, "Gamos::Music");
 
-    _mutex.unlock();
-    return true;
+	_mutex.unlock();
+	return true;
 }
 
 void MidiMusic::update() {
-    while (true) {
-        if (_dataPos >= _pMidiData.size())
-            return;
-
-        uint8 b = _pMidiData[_dataPos];
-
-        if (b > 0x7f) {
-            /* only if new event type then update _midiOp */
-            _midiOp = b;
-            _dataPos++;
-        }
-
-        bool doDelay = true;
-
-        if (_midiOp == 0xf0 || _midiOp == 0xf7) {
-            int16 skipLen = midi2low();
-            if (skipLen >= 0)
-                _dataPos += skipLen;
-        } else if (_midiOp == 0xff) {
-            if (_midiDelayTicks != -1) {
-                _midiDelayCount = _midiDelayTicks;
-                _dataPos = _dataStart;
-            } else {
-                g_system->getTimerManager()->removeTimerProc(_timerProc);
-                _driver->stopAllNotes(true);
-            }
-            break;
-        } else {
-            uint8 param1 = _pMidiData[_dataPos];
-            uint8 param2 = 0;
-            _dataPos++;
-
-            bool doSend = true;
-
-            uint8 cmd = _midiOp & 0xf0;
-            if (cmd != MidiDriver_BASE::MIDI_COMMAND_PROGRAM_CHANGE &&
-                cmd != MidiDriver_BASE::MIDI_COMMAND_CHANNEL_AFTERTOUCH) {
-                if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_OFF ||
-                    cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_ON) {
-                    if (_midiMute)
-                        doSend = false;
-                }
-
-                b = _pMidiData[_dataPos];
-                _dataPos++;
-
-                doDelay = (b & 0x80) == 0;
-                param2 = b & 0x7f;
-            }
-
-            if (doSend)
-                _driver->send(_midiOp, param1, param2);
-        }
-
-        if (doDelay) {
-            int16 ln = midi2low();
-            if (ln > 0) {
-                _midiTimeStamp += ln * 10;
-                if (g_system->getMillis() < _midiTimeStamp)
-                    break;
-            }
-        }
-    }
+	while (true) {
+		if (_dataPos >= _pMidiData.size())
+			return;
+
+		uint8 b = _pMidiData[_dataPos];
+
+		if (b > 0x7f) {
+			/* only if new event type then update _midiOp */
+			_midiOp = b;
+			_dataPos++;
+		}
+
+		bool doDelay = true;
+
+		if (_midiOp == 0xf0 || _midiOp == 0xf7) {
+			int16 skipLen = midi2low();
+			if (skipLen >= 0)
+				_dataPos += skipLen;
+		} else if (_midiOp == 0xff) {
+			if (_midiDelayTicks != -1) {
+				_midiDelayCount = _midiDelayTicks;
+				_dataPos = _dataStart;
+			} else {
+				g_system->getTimerManager()->removeTimerProc(_timerProc);
+				_driver->stopAllNotes(true);
+			}
+			break;
+		} else {
+			uint8 param1 = _pMidiData[_dataPos];
+			uint8 param2 = 0;
+			_dataPos++;
+
+			bool doSend = true;
+
+			uint8 cmd = _midiOp & 0xf0;
+			if (cmd != MidiDriver_BASE::MIDI_COMMAND_PROGRAM_CHANGE &&
+			        cmd != MidiDriver_BASE::MIDI_COMMAND_CHANNEL_AFTERTOUCH) {
+				if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_OFF ||
+				        cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_ON) {
+					if (_midiMute)
+						doSend = false;
+				}
+
+				b = _pMidiData[_dataPos];
+				_dataPos++;
+
+				doDelay = (b & 0x80) == 0;
+				param2 = b & 0x7f;
+			}
+
+			if (doSend)
+				_driver->send(_midiOp, param1, param2);
+		}
+
+		if (doDelay) {
+			int16 ln = midi2low();
+			if (ln > 0) {
+				_midiTimeStamp += ln * 10;
+				if (g_system->getMillis() < _midiTimeStamp)
+					break;
+			}
+		}
+	}
 }
 
 int16 MidiMusic::midi2low() {
-    if (_dataPos >= _pMidiData.size())
-        return -1;
+	if (_dataPos >= _pMidiData.size())
+		return -1;
 
-    int16 dat = _pMidiData[_dataPos];
-    _dataPos++;
+	int16 dat = _pMidiData[_dataPos];
+	_dataPos++;
 
-    if (dat & 0x80) {
-        if (_dataPos >= _pMidiData.size())
-            return -1;
+	if (dat & 0x80) {
+		if (_dataPos >= _pMidiData.size())
+			return -1;
 
-        dat &= 0x7f;
-        dat |= _pMidiData[_dataPos] << 7;
+		dat &= 0x7f;
+		dat |= _pMidiData[_dataPos] << 7;
 
-        _dataPos++;
-    }
-    return dat;
+		_dataPos++;
+	}
+	return dat;
 }
 
 
 void MidiMusic::_timerProc(void *data) {
-    if (!data)
-        return;
+	if (!data)
+		return;
 
-    MidiMusic *_this = (MidiMusic *)data;
+	MidiMusic *_this = (MidiMusic *)data;
 
-    if (_this->_midiDelayCount != 0) {
-        _this->_midiDelayCount--;
-        if (_this->_midiDelayCount != 0)
-            return;
+	if (_this->_midiDelayCount != 0) {
+		_this->_midiDelayCount--;
+		if (_this->_midiDelayCount != 0)
+			return;
 
-        _this->_midiTimeStamp = g_system->getMillis();
-    }
+		_this->_midiTimeStamp = g_system->getMillis();
+	}
 
-    if (_this->_midiTimeStamp <= g_system->getMillis() && _this->_mutex.lock()) {
-        _this->update();
-        _this->_mutex.unlock();
-    }
+	if (_this->_midiTimeStamp <= g_system->getMillis() && _this->_mutex.lock()) {
+		_this->update();
+		_this->_mutex.unlock();
+	}
 }
 
 };
diff --git a/engines/gamos/music.h b/engines/gamos/music.h
index 5a6fbbb3722..2cf482add7b 100644
--- a/engines/gamos/music.h
+++ b/engines/gamos/music.h
@@ -37,29 +37,29 @@ namespace Gamos {
 class MidiMusic {
 private:
 	MidiDriver *_driver = nullptr;
-    Common::Array<byte> _pMidiData;
+	Common::Array<byte> _pMidiData;
 
-    Common::Mutex _mutex;
+	Common::Mutex _mutex;
 
-    uint32 _dataPos = 0;
-    uint32 _dataStart = 0;
-    int32 _midiDelayTicks = 0;
-    int32 _midiDelayCount = 0;
-    uint32 _midiTimeStamp = 0;
-    uint32 _midiOp = 0; /* save midi event type between update cycles */
-    bool _midiMute = false;
+	uint32 _dataPos = 0;
+	uint32 _dataStart = 0;
+	int32 _midiDelayTicks = 0;
+	int32 _midiDelayCount = 0;
+	uint32 _midiTimeStamp = 0;
+	uint32 _midiOp = 0; /* save midi event type between update cycles */
+	bool _midiMute = false;
 
 public:
 
 	MidiMusic();
-  ~MidiMusic();
+	~MidiMusic();
 
-  void stopMusic();
-  bool playMusic(Common::Array<byte> *midiData);
-  void update();
-  int16 midi2low();
+	void stopMusic();
+	bool playMusic(Common::Array<byte> *midiData);
+	void update();
+	int16 midi2low();
 
-  static void _timerProc(void *data);
+	static void _timerProc(void *data);
 };
 
 };
diff --git a/engines/gamos/pool.h b/engines/gamos/pool.h
index 403b334fe38..be3a0fb55c3 100644
--- a/engines/gamos/pool.h
+++ b/engines/gamos/pool.h
@@ -29,44 +29,44 @@ namespace Gamos {
 template<class T, int shift = 6>
 class Pool {
 public:
-    typedef uint size_type; /*!< Size type of the array. */
+	typedef uint size_type; /*!< Size type of the array. */
 
-    const size_type _blockSize = (1 << shift);
-    const size_type _blockMask = _blockSize - 1;
+	const size_type _blockSize = (1 << shift);
+	const size_type _blockMask = _blockSize - 1;
 
 public:
 
-    constexpr Pool() : _size(0) {}
+	constexpr Pool() : _size(0) {}
 
-    explicit Pool(size_type count) : _size(count) {
-        alloc(count);
+	explicit Pool(size_type count) : _size(count) {
+		alloc(count);
 
-        size_type n = _size;
-        for (T* blk : _blocks) {
-            for (size_type i = 0; n > 0 && i < _blockSize; i++) {
-                n--;
-                new (blk + i) T();
-            }
-        }
-    }
+		size_type n = _size;
+		for (T * blk : _blocks) {
+			for (size_type i = 0; n > 0 && i < _blockSize; i++) {
+				n--;
+				new (blk + i) T();
+			}
+		}
+	}
 
-    ~Pool() {
+	~Pool() {
 		free();
 	}
 
-    template<class... TArgs>
+	template<class... TArgs>
 	void emplace_back(TArgs &&...args) {
 		alloc(_size + 1);
 
-        const size_type blid = _size >> shift;
-        const size_type elid = _size & _blockMask;
+		const size_type blid = _size >> shift;
+		const size_type elid = _size & _blockMask;
 
-        new (_blocks[blid] + elid)T(Common::forward<TArgs>(args)...);
+		new (_blocks[blid] + elid)T(Common::forward<TArgs>(args)...);
 
-        _size++;
+		_size++;
 	}
 
-    void push_back(const T &element) {
+	void push_back(const T &element) {
 		emplace_back(element);
 	}
 
@@ -77,8 +77,8 @@ public:
 	T &operator[](size_type idx) {
 		assert(idx < _size);
 
-        const size_type blid = idx >> shift;
-        const size_type elid = idx & _blockMask;
+		const size_type blid = idx >> shift;
+		const size_type elid = idx & _blockMask;
 
 		return _blocks[blid][elid];
 	}
@@ -87,7 +87,7 @@ public:
 		assert(idx < _size);
 
 		const size_type blid = idx >> shift;
-        const size_type elid = idx & _blockMask;
+		const size_type elid = idx & _blockMask;
 
 		return _blocks[blid][elid];
 	}
@@ -96,15 +96,15 @@ public:
 		return _size;
 	}
 
-    bool empty() const {
+	bool empty() const {
 		return (_size == 0);
 	}
 
 	void clear() {
-        free();
+		free();
 	}
 
-    T &front() {
+	T &front() {
 		assert(_size > 0);
 		return _blocks[0][0];
 	}
@@ -125,34 +125,34 @@ public:
 	}
 
 protected:
-    void alloc(size_type count) {
-        size_type blockCount = (count + _blockSize - 1) >> shift;
-        if (_blocks.size() < blockCount) {
-            size_type oldsz = _blocks.size();
-            _blocks.resize(blockCount);
-            for (size_type i = oldsz; i < blockCount; i++) {
-                _blocks[i] = (T*)malloc(sizeof(T) * _blockSize);
-            }
-        }
-    }
-
-    void free() {
-        size_type n = _size;
-        for (T* blk : _blocks) {
-            for (size_type i = 0; n > 0 && i < _blockSize; i++) {
-                n--;
-                blk[i].~T();
-            }
-            ::free(blk);
-        }
-        _blocks.clear();
-
-        _size = 0;
-    }
+	void alloc(size_type count) {
+		size_type blockCount = (count + _blockSize - 1) >> shift;
+		if (_blocks.size() < blockCount) {
+			size_type oldsz = _blocks.size();
+			_blocks.resize(blockCount);
+			for (size_type i = oldsz; i < blockCount; i++) {
+				_blocks[i] = (T*)malloc(sizeof(T) * _blockSize);
+			}
+		}
+	}
+
+	void free() {
+		size_type n = _size;
+		for (T * blk : _blocks) {
+			for (size_type i = 0; n > 0 && i < _blockSize; i++) {
+				n--;
+				blk[i].~T();
+			}
+			::free(blk);
+		}
+		_blocks.clear();
+
+		_size = 0;
+	}
 
 protected:
-    Common::Array<T*> _blocks;
-    size_type _size = 0;
+	Common::Array<T *> _blocks;
+	size_type _size = 0;
 };
 
 };
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index a570988393b..a8274242855 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -26,7 +26,7 @@ namespace Gamos {
 void SystemProc::processMessage(const Common::Event &ev) {
 	uint8 winKey;
 
-	switch(ev.type) {
+	switch (ev.type) {
 	case Common::EVENT_KEYDOWN:
 		if ((_gd2flags & 1) == 0)
 			return;
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index 9035ffcd361..14de8f6aea4 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -28,32 +28,32 @@
 namespace Gamos {
 
 enum ACT2 {
-    ACT_NONE = 0xe,
-    ACT2_81 = 0x81,
-    ACT2_82 = 0x82,
-    ACT2_83 = 0x83,
-    ACT2_84 = 0x84,
-    ACT2_8f = 0x8f,
+	ACT_NONE = 0xe,
+	ACT2_81 = 0x81,
+	ACT2_82 = 0x82,
+	ACT2_83 = 0x83,
+	ACT2_84 = 0x84,
+	ACT2_8f = 0x8f,
 };
 
 class SystemProc {
 public:
 
-    void processMessage(const Common::Event &ev);
+	void processMessage(const Common::Event &ev);
 
 public:
-    uint8 _act1 = 0;
-    uint8 _act2 = 0;
+	uint8 _act1 = 0;
+	uint8 _act2 = 0;
 
-    uint8 _rawKeyCode = 0;
-    uint16 _ascii = 0;
+	uint8 _rawKeyCode = 0;
+	uint16 _ascii = 0;
 
 
-    Common::Point _mouseReportedPos;
-    Common::Point _mouseActPos;
+	Common::Point _mouseReportedPos;
+	Common::Point _mouseActPos;
 
-    uint8 _gd2flags = 0; /* 0x4 */
-    uint8 _keyCodes[12]; /* 0x40 */
+	uint8 _gd2flags = 0; /* 0x4 */
+	uint8 _keyCodes[12]; /* 0x40 */
 
 };
 
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 39fa70ac789..f409b1c59f7 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -25,284 +25,284 @@
 namespace Gamos {
 
 void GamosEngine::storeToGameScreen(int id) {
-    GameScreen &gs = _gameScreens[id];
-    gs._savedObjects.clear();
-
-    gs._savedStates = _states;
-
-    int objCount = 0;
-    for (int i = 0; i < _objects.size(); i++) {
-        const Object &obj = _objects[i];
-        if ((obj.flags & 3) == 3 || (obj.flags & 7) == 1)
-            objCount++;
-    }
-
-    int idx = 0;
-    gs._savedObjects.resize(objCount);
-    for (int i = 0; i < _objects.size(); i++) {
-        Object &obj = _objects[i];
-
-        if ( (obj.flags & 3) == 3 ) {
-            const int refObjIdx = idx;
-            if (obj.x == -1) {
-                gs._savedObjects[idx] = obj;
-                gs._savedObjects[idx].index = idx;
-                obj.flags = 0;
-                idx++;
-            } else {
-                Object &drawObj = _objects[ obj.x ];
-                gs._savedObjects[idx] = obj;
-                gs._savedObjects[idx].index = idx;
-                gs._savedObjects[idx].x = idx + 1;
-                gs._savedObjects[idx].y = idx + 1;
-                gs._savedObjects[idx + 1] = drawObj;
-                gs._savedObjects[idx + 1].index = idx + 1;
-                gs._savedObjects[idx + 1].pos = idx & 0xff;
-                gs._savedObjects[idx + 1].blk = (idx >> 8) & 0xff;
-                obj.flags = 0;
-                drawObj.flags = 0;
-                idx += 2;
-            }
-
-            for (int j = 0; j < _objects.size(); j++) {
-                Object &lobj = _objects[ j ];
-                if ((lobj.flags & 7) == 1 && ((lobj.blk << 8) | lobj.pos) == obj.index) {
-                    gs._savedObjects[idx] = lobj;
-                    gs._savedObjects[idx].index = idx;
-                    gs._savedObjects[idx].pos = refObjIdx & 0xff;
-                    gs._savedObjects[idx].blk = (refObjIdx >> 8) & 0xff;
-                    lobj.flags = 0;
-                    idx++;
-                }
-            }
-        } else if ( (obj.flags & 7) == 1 && obj.pos == 0xff && obj.blk == 0xff ) {
-            gs._savedObjects[idx] = obj;
-            gs._savedObjects[idx].index = idx;
-            obj.flags = 0;
-            idx++;
-        }
-    }
-
-    _objects.clear();
+	GameScreen &gs = _gameScreens[id];
+	gs._savedObjects.clear();
+
+	gs._savedStates = _states;
+
+	int objCount = 0;
+	for (int i = 0; i < _objects.size(); i++) {
+		const Object &obj = _objects[i];
+		if ((obj.flags & 3) == 3 || (obj.flags & 7) == 1)
+			objCount++;
+	}
+
+	int idx = 0;
+	gs._savedObjects.resize(objCount);
+	for (int i = 0; i < _objects.size(); i++) {
+		Object &obj = _objects[i];
+
+		if ((obj.flags & 3) == 3) {
+			const int refObjIdx = idx;
+			if (obj.x == -1) {
+				gs._savedObjects[idx] = obj;
+				gs._savedObjects[idx].index = idx;
+				obj.flags = 0;
+				idx++;
+			} else {
+				Object &drawObj = _objects[ obj.x ];
+				gs._savedObjects[idx] = obj;
+				gs._savedObjects[idx].index = idx;
+				gs._savedObjects[idx].x = idx + 1;
+				gs._savedObjects[idx].y = idx + 1;
+				gs._savedObjects[idx + 1] = drawObj;
+				gs._savedObjects[idx + 1].index = idx + 1;
+				gs._savedObjects[idx + 1].pos = idx & 0xff;
+				gs._savedObjects[idx + 1].blk = (idx >> 8) & 0xff;
+				obj.flags = 0;
+				drawObj.flags = 0;
+				idx += 2;
+			}
+
+			for (int j = 0; j < _objects.size(); j++) {
+				Object &lobj = _objects[ j ];
+				if ((lobj.flags & 7) == 1 && ((lobj.blk << 8) | lobj.pos) == obj.index) {
+					gs._savedObjects[idx] = lobj;
+					gs._savedObjects[idx].index = idx;
+					gs._savedObjects[idx].pos = refObjIdx & 0xff;
+					gs._savedObjects[idx].blk = (refObjIdx >> 8) & 0xff;
+					lobj.flags = 0;
+					idx++;
+				}
+			}
+		} else if ((obj.flags & 7) == 1 && obj.pos == 0xff && obj.blk == 0xff) {
+			gs._savedObjects[idx] = obj;
+			gs._savedObjects[idx].index = idx;
+			obj.flags = 0;
+			idx++;
+		}
+	}
+
+	_objects.clear();
 }
 
 
 bool GamosEngine::switchToGameScreen(int id, bool doNotStore) {
-    if (_currentGameScreen != -1 && doNotStore == false)
-        storeToGameScreen(_currentGameScreen);
+	if (_currentGameScreen != -1 && doNotStore == false)
+		storeToGameScreen(_currentGameScreen);
 
-    _currentGameScreen = id;
-    GameScreen &gs = _gameScreens[id];
+	_currentGameScreen = id;
+	GameScreen &gs = _gameScreens[id];
 
-    addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes ));
+	addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes));
 
-    _states = gs._savedStates;
+	_states = gs._savedStates;
 
-    for(const Object &obj : gs._savedObjects) {
-        Object *nobj = getFreeObject();
-        if (nobj->index != obj.index) {
-            warning("Error!  nobj->index != obj.index");
-            return false;
-        }
+	for (const Object &obj : gs._savedObjects) {
+		Object *nobj = getFreeObject();
+		if (nobj->index != obj.index) {
+			warning("Error!  nobj->index != obj.index");
+			return false;
+		}
 
-        *nobj = obj;
-    }
+		*nobj = obj;
+	}
 
-    gs._savedObjects.clear();
-    gs._savedStates.clear();
+	gs._savedObjects.clear();
+	gs._savedStates.clear();
 
-    flushDirtyRects(false);
+	flushDirtyRects(false);
 
-    if (doNotStore == false && !setPaletteCurrentGS())
-        return false;
+	if (doNotStore == false && !setPaletteCurrentGS())
+		return false;
 
-    return true;
+	return true;
 }
 
 Common::String GamosEngine::makeSaveName(const Common::String &main, int id, const Common::String &ext) const {
-    Common::String tmp = main;
-    tmp.toUppercase();
-    uint32 idx = tmp.find(".EXE");
-    if (idx != Common::String::npos)
-        tmp.erase(idx);
-    return Common::String::format("%s%d.%s", tmp.c_str(), id, ext.c_str());
+	Common::String tmp = main;
+	tmp.toUppercase();
+	uint32 idx = tmp.find(".EXE");
+	if (idx != Common::String::npos)
+		tmp.erase(idx);
+	return Common::String::format("%s%d.%s", tmp.c_str(), id, ext.c_str());
 }
 
 
 bool GamosEngine::writeStateFile() {
 	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
-    Common::SaveFileManager *sm = _system->getSavefileManager();
-
-    if (!_runReadDataMod) {
-        if (sm->exists(fname)) {
-            Common::InSaveFile *rsv = sm->openForLoading(fname);
-            byte svdata[0x4c];
-            rsv->read(svdata, 0x4c);
-            delete rsv;
-
-            Common::OutSaveFile *osv = sm->openForSaving(fname);
-            osv->write(svdata, 0x4c);
-
-            writeVMData(osv, _xorSeq[0]);
-            writeVMData(osv, _xorSeq[1]);
-
-            osv->finalize();
-            delete osv;
-        }
-    } else {
-        _d2_fld10 = 0;
-        Common::OutSaveFile *osv = sm->openForSaving(fname);
-
-        writeStateData(osv);
-        writeVMData(osv, _xorSeq[0]);
-        writeVMData(osv, _xorSeq[1]);
-
-        osv->finalize();
-        delete osv;
-    }
-    return true;
+	Common::SaveFileManager *sm = _system->getSavefileManager();
+
+	if (!_runReadDataMod) {
+		if (sm->exists(fname)) {
+			Common::InSaveFile *rsv = sm->openForLoading(fname);
+			byte svdata[0x4c];
+			rsv->read(svdata, 0x4c);
+			delete rsv;
+
+			Common::OutSaveFile *osv = sm->openForSaving(fname);
+			osv->write(svdata, 0x4c);
+
+			writeVMData(osv, _xorSeq[0]);
+			writeVMData(osv, _xorSeq[1]);
+
+			osv->finalize();
+			delete osv;
+		}
+	} else {
+		_d2_fld10 = 0;
+		Common::OutSaveFile *osv = sm->openForSaving(fname);
+
+		writeStateData(osv);
+		writeVMData(osv, _xorSeq[0]);
+		writeVMData(osv, _xorSeq[1]);
+
+		osv->finalize();
+		delete osv;
+	}
+	return true;
 }
 
 bool GamosEngine::loadStateFile() {
-    Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
-    Common::SaveFileManager *sm = _system->getSavefileManager();
-
-    if (!_runReadDataMod) {
-        if (sm->exists(fname)) {
-            Common::SeekableReadStream *rs = sm->openForLoading(fname);
-            rs->seek(0x4c);
-            readVMData(rs, _xorSeq[0]);
-            readVMData(rs, _xorSeq[1]);
-        }
-    } else {
-        if (!sm->exists(fname))
-            writeStateFile();
-        else {
-            Common::SeekableReadStream *rs = sm->openForLoading(fname);
-
-            loadStateData(rs);
-            readVMData(rs, _xorSeq[0]);
-            readVMData(rs, _xorSeq[1]);
-
-            zeroVMData(_xorSeq[1]);
-
-            _runReadDataMod = false;
-
-            delete rs;
-        }
-    }
-    return true;
+	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
+	Common::SaveFileManager *sm = _system->getSavefileManager();
+
+	if (!_runReadDataMod) {
+		if (sm->exists(fname)) {
+			Common::SeekableReadStream *rs = sm->openForLoading(fname);
+			rs->seek(0x4c);
+			readVMData(rs, _xorSeq[0]);
+			readVMData(rs, _xorSeq[1]);
+		}
+	} else {
+		if (!sm->exists(fname))
+			writeStateFile();
+		else {
+			Common::SeekableReadStream *rs = sm->openForLoading(fname);
+
+			loadStateData(rs);
+			readVMData(rs, _xorSeq[0]);
+			readVMData(rs, _xorSeq[1]);
+
+			zeroVMData(_xorSeq[1]);
+
+			_runReadDataMod = false;
+
+			delete rs;
+		}
+	}
+	return true;
 }
 
 void GamosEngine::writeStateData(Common::SeekableWriteStream *stream) {
-    byte buf[4] = {0, 0, 0, 0};
-    memcpy(buf, _stateExt.c_str(), _stateExt.size() > 4 ? 4 : _stateExt.size());
-
-    stream->write(buf, 4); // 0
-    stream->writeByte(_messageProc._gd2flags);  // 4
-    stream->writeByte(0);  // 5
-    stream->writeByte(0);  // 6
-    stream->writeByte(0);  // 7
-    stream->writeSint32LE(_svModuleId); // 8
+	byte buf[4] = {0, 0, 0, 0};
+	memcpy(buf, _stateExt.c_str(), _stateExt.size() > 4 ? 4 : _stateExt.size());
+
+	stream->write(buf, 4); // 0
+	stream->writeByte(_messageProc._gd2flags);  // 4
+	stream->writeByte(0);  // 5
+	stream->writeByte(0);  // 6
+	stream->writeByte(0);  // 7
+	stream->writeSint32LE(_svModuleId); // 8
 	stream->writeSint32LE(_svGameScreen); // 0xc
-    stream->writeUint32LE(_d2_fld10); // 0x10
-    stream->writeByte(_d2_fld14); // 0x14
-    stream->writeByte(_enableMidi ? 1 : 0); // 0x15
-    stream->writeByte(_d2_fld16); // 0x16
-    stream->writeByte(_d2_fld17); // 0x17
-    stream->writeByte(_d2_fld18); // 0x18
-    stream->writeByte(_d2_fld19); // 0x19
-    stream->writeByte(0); // 0x1a
-    stream->writeByte(0); // 0x1b
-    stream->writeSint32LE(_d2_outLeft); // 0x1c
-    stream->writeSint32LE(_d2_outTop); // 0x20
-    stream->writeSint16LE(_d2_index); // 0x24
-    stream->writeSint16LE(_d2_fld26); // 0x26
-    stream->writeSint16LE(_d2_fld28); // 0x28
-    stream->writeSint16LE(_d2_fld2a); // 0x2a
-    stream->writeByte(_d2_fld2c); // 0x2c
-    stream->writeByte(_d2_fld2d); // 0x2d
-    stream->writeByte(_d2_fld2e); // 0x2e
-    stream->writeByte(_d2_fld2f); // 0x2f
-    stream->writeByte(_sndChannels); // 0x30
-    stream->writeByte(_sndVolume); // 0x31
-    stream->writeByte(_midiVolume); // 0x32
-    stream->writeByte(_svFps); // 0x33
-    stream->writeSint32LE(_svFrame); // 0x34
-    stream->writeUint32LE(_midiTrack); // 0x38
-    stream->writeUint32LE(_mouseCursorImgId); // 0x3c
-    // 0x40
-    for (int i = 0; i < 12; i++)
-        stream->writeByte(_messageProc._keyCodes[i]);
+	stream->writeUint32LE(_d2_fld10); // 0x10
+	stream->writeByte(_d2_fld14); // 0x14
+	stream->writeByte(_enableMidi ? 1 : 0); // 0x15
+	stream->writeByte(_d2_fld16); // 0x16
+	stream->writeByte(_d2_fld17); // 0x17
+	stream->writeByte(_d2_fld18); // 0x18
+	stream->writeByte(_d2_fld19); // 0x19
+	stream->writeByte(0); // 0x1a
+	stream->writeByte(0); // 0x1b
+	stream->writeSint32LE(_d2_outLeft); // 0x1c
+	stream->writeSint32LE(_d2_outTop); // 0x20
+	stream->writeSint16LE(_d2_index); // 0x24
+	stream->writeSint16LE(_d2_fld26); // 0x26
+	stream->writeSint16LE(_d2_fld28); // 0x28
+	stream->writeSint16LE(_d2_fld2a); // 0x2a
+	stream->writeByte(_d2_fld2c); // 0x2c
+	stream->writeByte(_d2_fld2d); // 0x2d
+	stream->writeByte(_d2_fld2e); // 0x2e
+	stream->writeByte(_d2_fld2f); // 0x2f
+	stream->writeByte(_sndChannels); // 0x30
+	stream->writeByte(_sndVolume); // 0x31
+	stream->writeByte(_midiVolume); // 0x32
+	stream->writeByte(_svFps); // 0x33
+	stream->writeSint32LE(_svFrame); // 0x34
+	stream->writeUint32LE(_midiTrack); // 0x38
+	stream->writeUint32LE(_mouseCursorImgId); // 0x3c
+	// 0x40
+	for (int i = 0; i < 12; i++)
+		stream->writeByte(_messageProc._keyCodes[i]);
 }
 
 void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
-    _stateExt = dataStream->readString(0, 4); // FIX ME
+	_stateExt = dataStream->readString(0, 4); // FIX ME
 	dataStream->seek(4);
-    _messageProc._gd2flags = dataStream->readByte(); //4
-    dataStream->seek(8);
-    _svModuleId = dataStream->readSint32LE(); // 8
-    _svGameScreen = dataStream->readSint32LE(); // c
-    _d2_fld10 = dataStream->readUint32LE(); // x10
-    _d2_fld14 = dataStream->readByte(); // x14
-    _enableMidi = dataStream->readByte() != 0 ? true : false; //x15
-    _d2_fld16 = dataStream->readByte(); // x16
-    _d2_fld17 = dataStream->readByte(); // x17
-    _d2_fld18 = dataStream->readByte(); // x18
-    _d2_fld19 = dataStream->readByte(); // x19
-    dataStream->seek(0x1c);
-    _d2_outLeft = dataStream->readSint32LE(); // x1c
-    _d2_outTop = dataStream->readSint32LE(); // x20
-    _d2_index = dataStream->readSint16LE(); // x24
-    _d2_fld26 = dataStream->readSint16LE(); // x26
-    _d2_fld28 = dataStream->readSint16LE(); // x28
-    _d2_fld2a = dataStream->readSint16LE(); // x2a
-    _d2_fld2c = dataStream->readByte(); // x2c
-    _d2_fld2d = dataStream->readByte(); // x2d
-    _d2_fld2e = dataStream->readByte(); // x2e
-    _d2_fld2f = dataStream->readByte(); // x2f
-    _sndChannels = dataStream->readByte(); // x30
-    _sndVolume = dataStream->readByte(); // x34
-    _midiVolume = dataStream->readByte(); // x1a
-    _svFps = dataStream->readByte(); // x1b
-    _svFrame = dataStream->readSint32LE(); // x1c
-    _midiTrack = dataStream->readUint32LE(); //0x38
-    _mouseCursorImgId = dataStream->readUint32LE(); //0x3c
-
-    for (int i = 0; i < 12; i++)
-        _messageProc._keyCodes[i] = dataStream->readByte();
+	_messageProc._gd2flags = dataStream->readByte(); //4
+	dataStream->seek(8);
+	_svModuleId = dataStream->readSint32LE(); // 8
+	_svGameScreen = dataStream->readSint32LE(); // c
+	_d2_fld10 = dataStream->readUint32LE(); // x10
+	_d2_fld14 = dataStream->readByte(); // x14
+	_enableMidi = dataStream->readByte() != 0 ? true : false; //x15
+	_d2_fld16 = dataStream->readByte(); // x16
+	_d2_fld17 = dataStream->readByte(); // x17
+	_d2_fld18 = dataStream->readByte(); // x18
+	_d2_fld19 = dataStream->readByte(); // x19
+	dataStream->seek(0x1c);
+	_d2_outLeft = dataStream->readSint32LE(); // x1c
+	_d2_outTop = dataStream->readSint32LE(); // x20
+	_d2_index = dataStream->readSint16LE(); // x24
+	_d2_fld26 = dataStream->readSint16LE(); // x26
+	_d2_fld28 = dataStream->readSint16LE(); // x28
+	_d2_fld2a = dataStream->readSint16LE(); // x2a
+	_d2_fld2c = dataStream->readByte(); // x2c
+	_d2_fld2d = dataStream->readByte(); // x2d
+	_d2_fld2e = dataStream->readByte(); // x2e
+	_d2_fld2f = dataStream->readByte(); // x2f
+	_sndChannels = dataStream->readByte(); // x30
+	_sndVolume = dataStream->readByte(); // x34
+	_midiVolume = dataStream->readByte(); // x1a
+	_svFps = dataStream->readByte(); // x1b
+	_svFrame = dataStream->readSint32LE(); // x1c
+	_midiTrack = dataStream->readUint32LE(); //0x38
+	_mouseCursorImgId = dataStream->readUint32LE(); //0x3c
+
+	for (int i = 0; i < 12; i++)
+		_messageProc._keyCodes[i] = dataStream->readByte();
 }
 
 
 void GamosEngine::writeVMData(Common::SeekableWriteStream *stream, const Common::Array<XorArg> &seq) {
-    for (const XorArg &xarg : seq) {
-        Common::Array<byte> tmp = VM::readMemBlocks(xarg.pos, xarg.len);
+	for (const XorArg &xarg : seq) {
+		Common::Array<byte> tmp = VM::readMemBlocks(xarg.pos, xarg.len);
 
-        //xor data in tmp
-        //...
+		//xor data in tmp
+		//...
 
-        // and write it
-        stream->write(tmp.data(), xarg.len);
-    }
+		// and write it
+		stream->write(tmp.data(), xarg.len);
+	}
 }
 
 void GamosEngine::readVMData(Common::SeekableReadStream *stream, const Common::Array<XorArg> &seq) {
-    Common::Array<byte> buf;
-    for (const XorArg &xarg : seq) {
-        if (buf.size() < xarg.len)
-            buf.resize(xarg.len);
-        stream->read(buf.data(), xarg.len);
-        //xor data in buf
-        //...
-
-        // and write it
-        VM::writeMemory(xarg.pos, buf.data(), xarg.len);
-    }
+	Common::Array<byte> buf;
+	for (const XorArg &xarg : seq) {
+		if (buf.size() < xarg.len)
+			buf.resize(xarg.len);
+		stream->read(buf.data(), xarg.len);
+		//xor data in buf
+		//...
+
+		// and write it
+		VM::writeMemory(xarg.pos, buf.data(), xarg.len);
+	}
 }
 
 void GamosEngine::zeroVMData(const Common::Array<XorArg> &seq) {
-    for (const XorArg &xarg : seq)
-        VM::zeroMemory(xarg.pos, xarg.len);
+	for (const XorArg &xarg : seq)
+		VM::zeroMemory(xarg.pos, xarg.len);
 }
 
 }
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index c014153afd7..fb8a51721f5 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -38,80 +38,80 @@ VM::MemAccess VM::_memAccess;
 
 
 uint8 VM::MemAccess::getU8(uint32 address) {
-    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-        _currentBlock = findMemoryBlock(address);
+	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+		_currentBlock = findMemoryBlock(address);
 
-    if (!_currentBlock)
-        return 0; // ERROR!
+	if (!_currentBlock)
+		return 0; // ERROR!
 
-    return _currentBlock->data[ address - _currentBlock->address ];
+	return _currentBlock->data[ address - _currentBlock->address ];
 }
 
 uint32 VM::MemAccess::getU32(uint32 address) {
-    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-        _currentBlock = findMemoryBlock(address);
-
-    if (!_currentBlock)
-        return 0; // ERROR!
-
-    uint32 pos = address - _currentBlock->address;
-    if ((int32)0x100 - (int32)pos >= 4)
-        return VM::getU32(_currentBlock->data + pos); //easy
-
-    MemoryBlock *block = _currentBlock;
-    uint32 val = block->data[ pos ];
-    for (int i = 1; i < 4; i++) {
-        pos++;
-        if (pos >= 0x100) {
-            block = findMemoryBlock(address + i);
-            if (!block)
-                break;
-            pos = 0;
-        }
-        val |= block->data[ pos ] << (i * 8);
-    }
-
-    return val;
+	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+		_currentBlock = findMemoryBlock(address);
+
+	if (!_currentBlock)
+		return 0; // ERROR!
+
+	uint32 pos = address - _currentBlock->address;
+	if ((int32)0x100 - (int32)pos >= 4)
+		return VM::getU32(_currentBlock->data + pos); //easy
+
+	MemoryBlock *block = _currentBlock;
+	uint32 val = block->data[ pos ];
+	for (int i = 1; i < 4; i++) {
+		pos++;
+		if (pos >= 0x100) {
+			block = findMemoryBlock(address + i);
+			if (!block)
+				break;
+			pos = 0;
+		}
+		val |= block->data[ pos ] << (i * 8);
+	}
+
+	return val;
 }
 
 void VM::MemAccess::setU8(uint32 address, uint8 val) {
-    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-        _currentBlock = findMemoryBlock(address);
+	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+		_currentBlock = findMemoryBlock(address);
 
-    if (!_currentBlock)
-        _currentBlock = createBlock(address);
+	if (!_currentBlock)
+		_currentBlock = createBlock(address);
 
-    _currentBlock->data[ address - _currentBlock->address ] = val;
+	_currentBlock->data[ address - _currentBlock->address ] = val;
 }
 
 void VM::MemAccess::setU32(uint32 address, uint32 val) {
-    if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-        _currentBlock = findMemoryBlock(address);
+	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
+		_currentBlock = findMemoryBlock(address);
 
-    if (!_currentBlock)
-        _currentBlock = createBlock(address);
+	if (!_currentBlock)
+		_currentBlock = createBlock(address);
 
-    uint32 pos = address - _currentBlock->address;
+	uint32 pos = address - _currentBlock->address;
 
-    if (address + 4 <= _currentBlock->address + 0x100) {
-        VM::setU32(_currentBlock->data + pos, val);
-        return;
-    }
+	if (address + 4 <= _currentBlock->address + 0x100) {
+		VM::setU32(_currentBlock->data + pos, val);
+		return;
+	}
 
-    MemoryBlock *block = _currentBlock;
+	MemoryBlock *block = _currentBlock;
 
-    _currentBlock->data[ pos ] = val & 0xff;
+	_currentBlock->data[ pos ] = val & 0xff;
 
-    for (int i = 1; i < 4; i++) {
-        pos++;
-        if (pos >= 0x100) {
-            block = createBlock(address + i);
-            if (!block)
-                break;
-            pos = 0;
-        }
-        block->data[ pos ] = (val >> (i * 8)) & 0xff;
-    }
+	for (int i = 1; i < 4; i++) {
+		pos++;
+		if (pos >= 0x100) {
+			block = createBlock(address + i);
+			if (!block)
+				break;
+			pos = 0;
+		}
+		block->data[ pos ] = (val >> (i * 8)) & 0xff;
+	}
 }
 
 
@@ -119,925 +119,925 @@ void VM::MemAccess::setU32(uint32 address, uint32 val) {
 
 
 uint32 VM::execute(uint32 scriptAddress, byte *storage) {
-    //Common::String disasm = disassembly(scriptAddress);
-
-    ESI = scriptAddress;
-    EBX = storage;
-
-    _readAccess.reset();
-    _writeAccess.reset();
-
-    SP = STACK_POS;
-
-    //Common::Array<OpLog> cmdlog;
-
-    bool loop = true;
-    while (loop) {
-        if (_interrupt)
-            return 0;
-
-        byte op = _readAccess.getU8(ESI);
-        //cmdlog.push_back({ESI, (OP)op, SP});
-        ESI++;
-
-        switch (op) {
-        default:
-        case OP_EXIT:
-            loop = false;
-            break;
-
-        case OP_CMP_EQ:
-            if (EDX.val == EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_NE:
-            if (EDX.val != EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_LE:
-            if ((int32)EDX.val < (int32)EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_LEQ:
-            if ((int32)EDX.val <= (int32)EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_GR:
-            if ((int32)EDX.val > (int32)EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_GREQ:
-            if ((int32)EDX.val >= (int32)EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_NAE:
-            if (EDX.val < EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_NA:
-            if (EDX.val <= EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_A:
-            if (EDX.val > EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_CMP_AE:
-            if (EDX.val >= EAX.val)
-                EAX.val = 1;
-            else
-                EAX.val = 0;
-            break;
-
-        case OP_BRANCH:
-            if (EAX.val != 0)
-                ESI += 4;
-            else
-                ESI += (int32)_readAccess.getU32(ESI);
-            break;
-
-        case OP_JMP:
-            ESI += (int32)_readAccess.getU32(ESI);
-            break;
-
-        case OP_SP_ADD:
-            SP += (int32)_readAccess.getU32(ESI);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EDI_ECX_AL:
-            ECX.val = _readAccess.getU32(ESI);
-            setMem8(REF_EDI, ECX.val, EAX.val & 0xff);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EBX_ECX_AL:
-            ECX.val = _readAccess.getU32(ESI);
-            setMem8(REF_EBX, ECX.val, EAX.val & 0xff);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EDI_ECX_EAX:
-            ECX.val = _readAccess.getU32(ESI);
-            setMem32(REF_EDI, ECX.val, EAX.val);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EBX_ECX_EAX:
-            ECX.val = _readAccess.getU32(ESI);
-            setMem32(REF_EBX, ECX.val, EAX.val);
-            ESI += 4;
-            break;
-
-        case OP_RET:
-            ESI = pop32();
-            ESI += 4;
-            break;
-
-        case OP_RETX:
-            ECX = popReg();
-            SP += _readAccess.getU32(ESI);
-            ESI = ECX.val;
-            ESI += 4;
-            break;
-
-        case OP_MOV_EDX_EAX:
-            EDX = EAX;
-            break;
-
-        case OP_ADD_EAX_EDX:
-            EAX.val += EDX.val;
-            if (EAX.ref == REF_UNK && EDX.ref != REF_UNK)
-                EAX.ref = EDX.ref;
-            break;
-
-        case OP_MUL:
-            EAX.val *= EDX.val;
-            break;
-
-        case OP_OR:
-            EAX.val |= EDX.val;
-            break;
-
-        case OP_XOR:
-            EAX.val ^= EDX.val;
-            break;
-
-        case OP_AND:
-            EAX.val &= EDX.val;
-            break;
-
-        case OP_NEG:
-            EAX.val = (uint32)(-((int32)EAX.val));
-            break;
-
-        case OP_SAR:
-            EAX.val = (uint32)(((int32)EDX.val) >> (EAX.val & 0xff)); /* must be arythmetic shift! */
-            break;
-
-        case OP_SHL:
-            EAX.val = EDX.val << (EAX.val & 0xff);
-            break;
-
-        case OP_LOAD:
-            EAX.val = _readAccess.getU32(ESI);
-            EAX.ref = REF_UNK;
-            ESI += 4;
-            break;
-
-        case OP_INC:
-            EAX.val += 1;
-            break;
-
-        case OP_DEC:
-            EAX.val -= 1;
-            break;
-
-        case OP_XCHG:
-            ECX = EAX;
-            EAX = EDX;
-            EDX = ECX;
-            break;
-
-        case OP_PUSH_EAX:
-            pushReg(EAX);
-            break;
-
-        case OP_POP_EDX:
-            EDX = popReg();
-            break;
-
-        case OP_LOAD_OFFSET_EDI:
-        case OP_LOAD_OFFSET_EDI2:
-            EAX.val = _readAccess.getU32(ESI);
-            EAX.ref = REF_EDI;
-            ESI += 4;
-            break;
-
-        case OP_LOAD_OFFSET_EBX:
-            EAX.val = _readAccess.getU32(ESI);
-            EAX.ref = REF_EBX;
-            ESI += 4;
-            break;
-
-        case OP_LOAD_OFFSET_ESP:
-            EAX.val = _readAccess.getU32(ESI) + SP;
-            EAX.ref = REF_STACK;
-            ESI += 4;
-            break;
-
-        case OP_MOV_PTR_EDX_AL:
-            setMem8(EDX.ref, EDX.val, EAX.val & 0xff);
-            break;
-
-        case OP_MOV_PTR_EDX_EAX:
-            setMem32(EDX.ref, EDX.val, EAX.val);
-            break;
-
-        case OP_SHL_2:
-            EAX.val <<= 2;
-            break;
-
-        case OP_ADD_4:
-            EAX.val += 4;
-            break;
-
-        case OP_SUB_4:
-            EAX.val -= 4;
-            break;
-
-        case OP_XCHG_ESP:
-            ECX = popReg();
-            pushReg(EAX);
-            EAX = ECX;
-            break;
-
-        case OP_NEG_ADD:
-            EAX.val = (uint32)(-((int32)EAX.val)) + EDX.val;
-            break;
-
-        case OP_DIV:
-            ECX = EAX;
-            EAX.val = (int32)EDX.val / (int32)ECX.val;
-            EDX.val = (int32)EDX.val % (int32)ECX.val;
-            break;
-
-        case OP_MOV_EAX_BPTR_EDI:
-            ECX.val = _readAccess.getU32(ESI);
-            EAX.val = (int8)getMem8(REF_EDI, ECX.val);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EAX_BPTR_EBX:
-            ECX.val = _readAccess.getU32(ESI);
-            EAX.val = (int8)getMem8(REF_EBX, ECX.val);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EAX_DPTR_EDI:
-            ECX.val = _readAccess.getU32(ESI);
-            EAX.val = getMem32(REF_EDI, ECX.val);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EAX_DPTR_EBX:
-            ECX.val = _readAccess.getU32(ESI);
-            EAX.val = getMem32(REF_EBX, ECX.val);
-            ESI += 4;
-            break;
-
-        case OP_MOV_EAX_BPTR_EAX:
-            EAX.val = (int8)getMem8(EAX.ref, EAX.val);
-            EAX.ref = REF_UNK;
-            break;
-
-        case OP_MOV_EAX_DPTR_EAX:
-            EAX.val = getMem32(EAX.ref, EAX.val);
-            EAX.ref = REF_UNK;
-            break;
-
-        case OP_PUSH_ESI_ADD_EDI:
-            push32(ESI);
-            ESI = _readAccess.getU32(ESI);
-            break;
-
-        case OP_CALL_FUNC:
-            EAX.val = _readAccess.getU32(ESI);
-            ESI += 4;
-            if (_callFuncs)
-                _callFuncs(_callingObject, this, EAX.val);
-            break;
-
-        case OP_PUSH_ESI_SET_EDX_EDI:
-            push32(ESI);
-            ESI = EDX.val;
-            break;
-        }
-    }
-
-    return EAX.val;
+	//Common::String disasm = disassembly(scriptAddress);
+
+	ESI = scriptAddress;
+	EBX = storage;
+
+	_readAccess.reset();
+	_writeAccess.reset();
+
+	SP = STACK_POS;
+
+	//Common::Array<OpLog> cmdlog;
+
+	bool loop = true;
+	while (loop) {
+		if (_interrupt)
+			return 0;
+
+		byte op = _readAccess.getU8(ESI);
+		//cmdlog.push_back({ESI, (OP)op, SP});
+		ESI++;
+
+		switch (op) {
+		default:
+		case OP_EXIT:
+			loop = false;
+			break;
+
+		case OP_CMP_EQ:
+			if (EDX.val == EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_NE:
+			if (EDX.val != EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_LE:
+			if ((int32)EDX.val < (int32)EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_LEQ:
+			if ((int32)EDX.val <= (int32)EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_GR:
+			if ((int32)EDX.val > (int32)EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_GREQ:
+			if ((int32)EDX.val >= (int32)EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_NAE:
+			if (EDX.val < EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_NA:
+			if (EDX.val <= EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_A:
+			if (EDX.val > EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_CMP_AE:
+			if (EDX.val >= EAX.val)
+				EAX.val = 1;
+			else
+				EAX.val = 0;
+			break;
+
+		case OP_BRANCH:
+			if (EAX.val != 0)
+				ESI += 4;
+			else
+				ESI += (int32)_readAccess.getU32(ESI);
+			break;
+
+		case OP_JMP:
+			ESI += (int32)_readAccess.getU32(ESI);
+			break;
+
+		case OP_SP_ADD:
+			SP += (int32)_readAccess.getU32(ESI);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EDI_ECX_AL:
+			ECX.val = _readAccess.getU32(ESI);
+			setMem8(REF_EDI, ECX.val, EAX.val & 0xff);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EBX_ECX_AL:
+			ECX.val = _readAccess.getU32(ESI);
+			setMem8(REF_EBX, ECX.val, EAX.val & 0xff);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EDI_ECX_EAX:
+			ECX.val = _readAccess.getU32(ESI);
+			setMem32(REF_EDI, ECX.val, EAX.val);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EBX_ECX_EAX:
+			ECX.val = _readAccess.getU32(ESI);
+			setMem32(REF_EBX, ECX.val, EAX.val);
+			ESI += 4;
+			break;
+
+		case OP_RET:
+			ESI = pop32();
+			ESI += 4;
+			break;
+
+		case OP_RETX:
+			ECX = popReg();
+			SP += _readAccess.getU32(ESI);
+			ESI = ECX.val;
+			ESI += 4;
+			break;
+
+		case OP_MOV_EDX_EAX:
+			EDX = EAX;
+			break;
+
+		case OP_ADD_EAX_EDX:
+			EAX.val += EDX.val;
+			if (EAX.ref == REF_UNK && EDX.ref != REF_UNK)
+				EAX.ref = EDX.ref;
+			break;
+
+		case OP_MUL:
+			EAX.val *= EDX.val;
+			break;
+
+		case OP_OR:
+			EAX.val |= EDX.val;
+			break;
+
+		case OP_XOR:
+			EAX.val ^= EDX.val;
+			break;
+
+		case OP_AND:
+			EAX.val &= EDX.val;
+			break;
+
+		case OP_NEG:
+			EAX.val = (uint32)(-((int32)EAX.val));
+			break;
+
+		case OP_SAR:
+			EAX.val = (uint32)(((int32)EDX.val) >> (EAX.val & 0xff)); /* must be arythmetic shift! */
+			break;
+
+		case OP_SHL:
+			EAX.val = EDX.val << (EAX.val & 0xff);
+			break;
+
+		case OP_LOAD:
+			EAX.val = _readAccess.getU32(ESI);
+			EAX.ref = REF_UNK;
+			ESI += 4;
+			break;
+
+		case OP_INC:
+			EAX.val += 1;
+			break;
+
+		case OP_DEC:
+			EAX.val -= 1;
+			break;
+
+		case OP_XCHG:
+			ECX = EAX;
+			EAX = EDX;
+			EDX = ECX;
+			break;
+
+		case OP_PUSH_EAX:
+			pushReg(EAX);
+			break;
+
+		case OP_POP_EDX:
+			EDX = popReg();
+			break;
+
+		case OP_LOAD_OFFSET_EDI:
+		case OP_LOAD_OFFSET_EDI2:
+			EAX.val = _readAccess.getU32(ESI);
+			EAX.ref = REF_EDI;
+			ESI += 4;
+			break;
+
+		case OP_LOAD_OFFSET_EBX:
+			EAX.val = _readAccess.getU32(ESI);
+			EAX.ref = REF_EBX;
+			ESI += 4;
+			break;
+
+		case OP_LOAD_OFFSET_ESP:
+			EAX.val = _readAccess.getU32(ESI) + SP;
+			EAX.ref = REF_STACK;
+			ESI += 4;
+			break;
+
+		case OP_MOV_PTR_EDX_AL:
+			setMem8(EDX.ref, EDX.val, EAX.val & 0xff);
+			break;
+
+		case OP_MOV_PTR_EDX_EAX:
+			setMem32(EDX.ref, EDX.val, EAX.val);
+			break;
+
+		case OP_SHL_2:
+			EAX.val <<= 2;
+			break;
+
+		case OP_ADD_4:
+			EAX.val += 4;
+			break;
+
+		case OP_SUB_4:
+			EAX.val -= 4;
+			break;
+
+		case OP_XCHG_ESP:
+			ECX = popReg();
+			pushReg(EAX);
+			EAX = ECX;
+			break;
+
+		case OP_NEG_ADD:
+			EAX.val = (uint32)(-((int32)EAX.val)) + EDX.val;
+			break;
+
+		case OP_DIV:
+			ECX = EAX;
+			EAX.val = (int32)EDX.val / (int32)ECX.val;
+			EDX.val = (int32)EDX.val % (int32)ECX.val;
+			break;
+
+		case OP_MOV_EAX_BPTR_EDI:
+			ECX.val = _readAccess.getU32(ESI);
+			EAX.val = (int8)getMem8(REF_EDI, ECX.val);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EAX_BPTR_EBX:
+			ECX.val = _readAccess.getU32(ESI);
+			EAX.val = (int8)getMem8(REF_EBX, ECX.val);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EAX_DPTR_EDI:
+			ECX.val = _readAccess.getU32(ESI);
+			EAX.val = getMem32(REF_EDI, ECX.val);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EAX_DPTR_EBX:
+			ECX.val = _readAccess.getU32(ESI);
+			EAX.val = getMem32(REF_EBX, ECX.val);
+			ESI += 4;
+			break;
+
+		case OP_MOV_EAX_BPTR_EAX:
+			EAX.val = (int8)getMem8(EAX.ref, EAX.val);
+			EAX.ref = REF_UNK;
+			break;
+
+		case OP_MOV_EAX_DPTR_EAX:
+			EAX.val = getMem32(EAX.ref, EAX.val);
+			EAX.ref = REF_UNK;
+			break;
+
+		case OP_PUSH_ESI_ADD_EDI:
+			push32(ESI);
+			ESI = _readAccess.getU32(ESI);
+			break;
+
+		case OP_CALL_FUNC:
+			EAX.val = _readAccess.getU32(ESI);
+			ESI += 4;
+			if (_callFuncs)
+				_callFuncs(_callingObject, this, EAX.val);
+			break;
+
+		case OP_PUSH_ESI_SET_EDX_EDI:
+			push32(ESI);
+			ESI = EDX.val;
+			break;
+		}
+	}
+
+	return EAX.val;
 }
 
 
 uint32 VM::doScript(uint32 scriptAddress, byte *storage) {
-    if (_interrupt)
-        return 0;
-
-    for (int i = 0; i < THREADS_COUNT; i++) {
-        if (!_threads[i]._inUse) {
-            _threads[i]._inUse = true;
-            uint32 res = _threads[i].execute(scriptAddress, storage);
-            _threads[i]._inUse = false;
-            return res;
-        }
-    }
-
-    VM *tmpcontext = new VM();
-    uint32 res = tmpcontext->execute(scriptAddress, storage);
-    delete tmpcontext;
-    return res;
+	if (_interrupt)
+		return 0;
+
+	for (int i = 0; i < THREADS_COUNT; i++) {
+		if (!_threads[i]._inUse) {
+			_threads[i]._inUse = true;
+			uint32 res = _threads[i].execute(scriptAddress, storage);
+			_threads[i]._inUse = false;
+			return res;
+		}
+	}
+
+	VM *tmpcontext = new VM();
+	uint32 res = tmpcontext->execute(scriptAddress, storage);
+	delete tmpcontext;
+	return res;
 }
 
 
 
 int32 VM::getS32(const void *mem) {
-    const uint8 *mem8 = (const uint8 *)mem;
-    return (int32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
+	const uint8 *mem8 = (const uint8 *)mem;
+	return (int32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
 }
 
 uint32 VM::getU32(const void *mem) {
-    const uint8 *mem8 = (const uint8 *)mem;
-    return (uint32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
+	const uint8 *mem8 = (const uint8 *)mem;
+	return (uint32)(mem8[0] | (mem8[1] << 8) | (mem8[2] << 16) | (mem8[3] << 24));
 }
 
 void VM::setU32(void *mem, uint32 val) {
-    uint8 *mem8 = (uint8 *)mem;
-    mem8[0] = val & 0xff;
-    mem8[1] = (val >> 8) & 0xff;
-    mem8[2] = (val >> 16) & 0xff;
-    mem8[3] = (val >> 24) & 0xff;
+	uint8 *mem8 = (uint8 *)mem;
+	mem8[0] = val & 0xff;
+	mem8[1] = (val >> 8) & 0xff;
+	mem8[2] = (val >> 16) & 0xff;
+	mem8[3] = (val >> 24) & 0xff;
 }
 
 void VM::push32(uint32 val) {
-    SP -= 4;
-    setU32(_stack + SP, val);
+	SP -= 4;
+	setU32(_stack + SP, val);
 }
 
 uint32 VM::pop32() {
-    uint32 val = getU32(_stack + SP);
-    SP += 4;
-    return val;
+	uint32 val = getU32(_stack + SP);
+	SP += 4;
+	return val;
 }
 
 void VM::pushReg(Reg reg) {
-    SP -= 4;
-    setU32(_stack + SP, reg.val);
-    _stackT[SP] = reg.ref;
+	SP -= 4;
+	setU32(_stack + SP, reg.val);
+	_stackT[SP] = reg.ref;
 }
 
 VM::Reg VM::popReg() {
-    Reg tmp;
-    tmp.val = getU32(_stack + SP);
-    tmp.ref = _stackT[SP];
-    SP += 4;
-    return tmp;
+	Reg tmp;
+	tmp.val = getU32(_stack + SP);
+	tmp.ref = _stackT[SP];
+	SP += 4;
+	return tmp;
 }
 
 uint32 VM::getMem32(int memtype, uint32 offset) {
-    switch (memtype) {
-    default:
-    case REF_UNK:
-        return 0;
+	switch (memtype) {
+	default:
+	case REF_UNK:
+		return 0;
 
-    case REF_STACK:
-        return getU32(_stack + offset);
+	case REF_STACK:
+		return getU32(_stack + offset);
 
-    case REF_EBX:
-        return getU32(EBX + offset);
+	case REF_EBX:
+		return getU32(EBX + offset);
 
-    case REF_EDI:
-        return _readAccess.getU32(offset);
-    }
+	case REF_EDI:
+		return _readAccess.getU32(offset);
+	}
 }
 
 uint8 VM::getMem8(int memtype, uint32 offset) {
-    switch (memtype) {
-    default:
-    case REF_UNK:
-        return 0;
+	switch (memtype) {
+	default:
+	case REF_UNK:
+		return 0;
 
-    case REF_STACK:
-        return _stack[offset];
+	case REF_STACK:
+		return _stack[offset];
 
-    case REF_EBX:
-        return EBX[offset];
+	case REF_EBX:
+		return EBX[offset];
 
-    case REF_EDI:
-        return _readAccess.getU8(offset);
-    }
+	case REF_EDI:
+		return _readAccess.getU8(offset);
+	}
 }
 
 void VM::setMem32(int memtype, uint32 offset, uint32 val) {
-    switch (memtype) {
-    default:
-    case REF_UNK:
-        break;
-    case REF_STACK:
-        setU32(_stack + offset, val);
-        break;
-    case REF_EBX:
-        setU32(EBX + offset, val);
-        break;
-
-    case REF_EDI:
-        _writeAccess.setU32(offset, val);
-        break;
-    }
+	switch (memtype) {
+	default:
+	case REF_UNK:
+		break;
+	case REF_STACK:
+		setU32(_stack + offset, val);
+		break;
+	case REF_EBX:
+		setU32(EBX + offset, val);
+		break;
+
+	case REF_EDI:
+		_writeAccess.setU32(offset, val);
+		break;
+	}
 }
 
 void VM::setMem8(int memtype, uint32 offset, uint8 val) {
-    switch (memtype) {
-    default:
-    case REF_UNK:
-        break;
-    case REF_STACK:
-        _stack[offset] = val;
-        break;
-    case REF_EBX:
-        EBX[offset] = val;
-        break;
-
-    case REF_EDI:
-        _writeAccess.setU8(offset, val);
-        break;
-    }
+	switch (memtype) {
+	default:
+	case REF_UNK:
+		break;
+	case REF_STACK:
+		_stack[offset] = val;
+		break;
+	case REF_EBX:
+		EBX[offset] = val;
+		break;
+
+	case REF_EDI:
+		_writeAccess.setU8(offset, val);
+		break;
+	}
 }
 
 void VM::clearMemory() {
-    _memMap.clear();
-    _memAccess.reset();
+	_memMap.clear();
+	_memAccess.reset();
 }
 
 void VM::writeMemory(uint32 address, const byte* data, uint32 dataSize) {
 
-    uint32 blockAddr = address & (~0xff);
-    uint32 pos = 0;
-    uint32 remain = dataSize;
+	uint32 blockAddr = address & (~0xff);
+	uint32 pos = 0;
+	uint32 remain = dataSize;
 
-    //warning("Write memory at %x sz %x", address, dataSize);
+	//warning("Write memory at %x sz %x", address, dataSize);
 
-    for (uint32 addr = blockAddr; addr < address + dataSize; addr += 0x100) {
-        MemoryBlock &block = _memMap.getOrCreateVal(addr);
+	for (uint32 addr = blockAddr; addr < address + dataSize; addr += 0x100) {
+		MemoryBlock &block = _memMap.getOrCreateVal(addr);
 
-        block.address = addr; // update it
+		block.address = addr; // update it
 
-        uint32 copyCnt = (addr + 0x100) - (address + pos);
-        if (copyCnt > remain)
-            copyCnt = remain;
+		uint32 copyCnt = (addr + 0x100) - (address + pos);
+		if (copyCnt > remain)
+			copyCnt = remain;
 
-        uint32 blockPos = (address + pos) - addr;
-        memcpy(block.data + blockPos, data + pos, copyCnt);
+		uint32 blockPos = (address + pos) - addr;
+		memcpy(block.data + blockPos, data + pos, copyCnt);
 
-        pos += copyCnt;
-        remain -= copyCnt;
-    }
+		pos += copyCnt;
+		remain -= copyCnt;
+	}
 }
 
 void VM::zeroMemory(uint32 address, uint32 count) {
-    uint32 blockAddr = address & (~0xff);
-    uint32 pos = 0;
-    uint32 remain = count;
+	uint32 blockAddr = address & (~0xff);
+	uint32 pos = 0;
+	uint32 remain = count;
 
-    for (uint32 addr = blockAddr; addr < address + count; addr += 0x100) {
-        MemoryBlock *block = findMemoryBlock(addr);
+	for (uint32 addr = blockAddr; addr < address + count; addr += 0x100) {
+		MemoryBlock *block = findMemoryBlock(addr);
 
-        uint32 zeroCnt = (addr + 0x100) - (address + pos);
-        if (zeroCnt > remain)
-            zeroCnt = remain;
+		uint32 zeroCnt = (addr + 0x100) - (address + pos);
+		if (zeroCnt > remain)
+			zeroCnt = remain;
 
-        uint32 blockPos = (address + pos) - addr;
+		uint32 blockPos = (address + pos) - addr;
 
-        if (block)
-            memset(block->data + blockPos, 0, zeroCnt);
+		if (block)
+			memset(block->data + blockPos, 0, zeroCnt);
 
-        pos += zeroCnt;
-        remain -= zeroCnt;
-    }
+		pos += zeroCnt;
+		remain -= zeroCnt;
+	}
 }
 
 VM::MemoryBlock *VM::findMemoryBlock(uint32 address) {
-    Common::HashMap<uint32, MemoryBlock>::iterator it = _memMap.find(address & (~0xff));
-    if (it == _memMap.end())
-        return nullptr;
+	Common::HashMap<uint32, MemoryBlock>::iterator it = _memMap.find(address & (~0xff));
+	if (it == _memMap.end())
+		return nullptr;
 
-    return &it->_value;
+	return &it->_value;
 }
 
 VM::MemoryBlock *VM::createBlock(uint32 address) {
-    MemoryBlock &blk = _memMap.getOrCreateVal(address & (~0xff));
-    blk.address = address & (~0xff);
-    return &blk;
+	MemoryBlock &blk = _memMap.getOrCreateVal(address & (~0xff));
+	blk.address = address & (~0xff);
+	return &blk;
 }
 
 
 
 Common::Array<byte> VM::readMemBlocks(uint32 address, uint32 count) {
-    Common::Array<byte> data(count);
+	Common::Array<byte> data(count);
 
-    readMemBlocks(data.data(), address, count);
+	readMemBlocks(data.data(), address, count);
 
-    return data;
+	return data;
 }
 
 void VM::readMemBlocks(byte *dst, uint32 address, uint32 count) {
-    MemoryBlock *blk = findMemoryBlock(address);
-
-    uint32 pos = 0;
-    uint32 blockAddr = address & (~0xff);
-    uint32 remain = count;
-    while(remain > 0) {
-        uint32 dataCpyCount = (blockAddr + 0x100) - (address + pos);
-        if (dataCpyCount > remain)
-            dataCpyCount = remain;
-
-        if (!blk) {
-            memset(dst + pos, 0, dataCpyCount);
-        } else {
-            memcpy(dst + pos, blk->data + (address + pos - blk->address), dataCpyCount);
-        }
-
-        pos += dataCpyCount;
-        remain -= dataCpyCount;
-        blockAddr += 0x100;
-        blk = findMemoryBlock(blockAddr);
-    }
+	MemoryBlock *blk = findMemoryBlock(address);
+
+	uint32 pos = 0;
+	uint32 blockAddr = address & (~0xff);
+	uint32 remain = count;
+	while (remain > 0) {
+		uint32 dataCpyCount = (blockAddr + 0x100) - (address + pos);
+		if (dataCpyCount > remain)
+			dataCpyCount = remain;
+
+		if (!blk) {
+			memset(dst + pos, 0, dataCpyCount);
+		} else {
+			memcpy(dst + pos, blk->data + (address + pos - blk->address), dataCpyCount);
+		}
+
+		pos += dataCpyCount;
+		remain -= dataCpyCount;
+		blockAddr += 0x100;
+		blk = findMemoryBlock(blockAddr);
+	}
 }
 
 Common::String VM::readMemString(uint32 address, uint32 maxLen) {
-    Common::String s;
+	Common::String s;
 
-    MemoryBlock *blk = findMemoryBlock(address);
+	MemoryBlock *blk = findMemoryBlock(address);
 
-    if (!blk)
-        return s;
+	if (!blk)
+		return s;
 
-    uint32 pos = address - blk->address;
-    char c = blk->data[pos];
+	uint32 pos = address - blk->address;
+	char c = blk->data[pos];
 
-    while(c != 0) {
-        s += c;
+	while (c != 0) {
+		s += c;
 
-        pos++;
-        if (pos >= 0x100) {
-            blk = findMemoryBlock(blk->address + 0x100);
-            pos = 0;
-        }
+		pos++;
+		if (pos >= 0x100) {
+			blk = findMemoryBlock(blk->address + 0x100);
+			pos = 0;
+		}
 
-        if (!blk)
-            break;
+		if (!blk)
+			break;
 
-        c = blk->data[pos];
-    }
-    return s;
+		c = blk->data[pos];
+	}
+	return s;
 }
 
 Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
-    switch (memtype) {
-        default:
-        case REF_UNK:
-            return Common::String();
-
-        case REF_STACK: {
-            Common::String s = Common::String((const char *)_stack + offset);
-            if (s.size() > maxLen)
-                s.erase(maxLen);
-            return s;
-        }
-        case REF_EBX: {
-            Common::String s = Common::String((const char *)EBX + offset);
-            if (s.size() > maxLen)
-                s.erase(maxLen);
-            return s;
-        }
-
-        case REF_EDI:
-            return readMemString(offset, maxLen);
-    }
+	switch (memtype) {
+	default:
+	case REF_UNK:
+		return Common::String();
+
+	case REF_STACK: {
+		Common::String s = Common::String((const char *)_stack + offset);
+		if (s.size() > maxLen)
+			s.erase(maxLen);
+		return s;
+	}
+	case REF_EBX: {
+		Common::String s = Common::String((const char *)EBX + offset);
+		if (s.size() > maxLen)
+			s.erase(maxLen);
+		return s;
+	}
+
+	case REF_EDI:
+		return readMemString(offset, maxLen);
+	}
 }
 
 
 Common::String VM::decodeOp(uint32 address, int *size) {
-    Common::String tmp;
-
-    MemAccess readmem;
-
-    int sz = 1;
-    byte op = readmem.getU8(address);
+	Common::String tmp;
+
+	MemAccess readmem;
+
+	int sz = 1;
+	byte op = readmem.getU8(address);
 
-    address++;
-
-    switch (op) {
-    default:
-    case OP_EXIT:
-        tmp = Common::String("EXIT");
-        break;
+	address++;
+
+	switch (op) {
+	default:
+	case OP_EXIT:
+		tmp = Common::String("EXIT");
+		break;
 
-    case OP_CMP_EQ:
-        tmp = Common::String("EAX =  EDX == EAX (CMP_EQ)");
-        break;
+	case OP_CMP_EQ:
+		tmp = Common::String("EAX =  EDX == EAX (CMP_EQ)");
+		break;
 
-    case OP_CMP_NE:
-        tmp = Common::String("EAX =  EDX != EAX (CMP_NE)");
-        break;
+	case OP_CMP_NE:
+		tmp = Common::String("EAX =  EDX != EAX (CMP_NE)");
+		break;
 
-    case OP_CMP_LE:
-        tmp = Common::String("EAX =  EDX < EAX (CMP_LE) //signed");
-        break;
+	case OP_CMP_LE:
+		tmp = Common::String("EAX =  EDX < EAX (CMP_LE) //signed");
+		break;
 
-    case OP_CMP_LEQ:
-        tmp = Common::String("EAX =  EDX <= EAX (CMP_LEQ) //signed");
-        break;
+	case OP_CMP_LEQ:
+		tmp = Common::String("EAX =  EDX <= EAX (CMP_LEQ) //signed");
+		break;
 
-    case OP_CMP_GR:
-        tmp = Common::String("EAX =  EDX > EAX (CMP_GR) //signed");
-        break;
+	case OP_CMP_GR:
+		tmp = Common::String("EAX =  EDX > EAX (CMP_GR) //signed");
+		break;
 
-    case OP_CMP_GREQ:
-        tmp = Common::String("EAX =  EDX >= EAX (CMP_GREQ) //signed");
-        break;
-
-    case OP_CMP_NAE:
-        tmp = Common::String("EAX =  EDX < EAX (CMP_NAE) //unsigned");
-        break;
-
-    case OP_CMP_NA:
-        tmp = Common::String("EAX =  EDX <= EAX (CMP_NA) //unsigned");
-        break;
-
-    case OP_CMP_A:
-        tmp = Common::String("EAX =  EDX > EAX (CMP_A) //unsigned");
-        break;
-
-    case OP_CMP_AE:
-        tmp = Common::String("EAX =  EDX >= EAX (CMP_AE) //unsigned");
-        break;
-
-    case OP_BRANCH:
-        tmp = Common::String::format("BR %x", address + (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_JMP:
-        tmp = Common::String::format("JMP %x", address + (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_SP_ADD:
-        tmp = Common::String::format("ADD SP, %x", (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EDI_ECX_AL:
-        tmp = Common::String::format("MOV byte ptr[EDI + %x], AL", (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EBX_ECX_AL:
-        tmp = Common::String::format("MOV byte ptr[EBX + %x], AL", (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EDI_ECX_EAX:
-        tmp = Common::String::format("MOV dword ptr[EDI + %x], EAX", (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EBX_ECX_EAX:
-        tmp = Common::String::format("MOV dword ptr[EBX + %x], EAX", (int32)readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_RET:
-        tmp = Common::String("RET");
-        break;
-
-    case OP_RETX:
-        tmp = Common::String::format("RET%x", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EDX_EAX:
-        tmp = Common::String("MOV EDX, EAX");
-        break;
-
-    case OP_ADD_EAX_EDX:
-        tmp = Common::String("ADD EAX, EDX");
-        break;
-
-    case OP_MUL:
-        tmp = Common::String("MUL EDX");
-        break;
-
-    case OP_OR:
-        tmp = Common::String("OR EDX");
-        break;
-
-    case OP_XOR:
-        tmp = Common::String("XOR EDX");
-        break;
-
-    case OP_AND:
-        tmp = Common::String("AND EDX");
-        break;
-
-    case OP_NEG:
-        tmp = Common::String("NEG EAX");
-        break;
-
-    case OP_SAR:
-        tmp = Common::String("SAR EAX, EDX,EAX // edx>>eax");
-        break;
-
-    case OP_SHL:
-        tmp = Common::String("SHL EAX, EDX,EAX // edx<<eax");
-        break;
-
-    case OP_LOAD:
-        tmp = Common::String::format("MOV EAX, %x", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_INC:
-        tmp = Common::String("INC EAX");
-        break;
-
-    case OP_DEC:
-        tmp = Common::String("DEC EAX");
-        break;
-
-    case OP_XCHG:
-        tmp = Common::String("XCHG EAX,EDX");
-        break;
-
-    case OP_PUSH_EAX:
-        tmp = Common::String("PUSH EAX");
-        break;
-
-    case OP_POP_EDX:
-        tmp = Common::String("POP EDX");
-        break;
-
-    case OP_LOAD_OFFSET_EDI:
-    case OP_LOAD_OFFSET_EDI2:
-        tmp = Common::String::format("LEA EAX, [EDI + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_LOAD_OFFSET_EBX:
-        tmp = Common::String::format("LEA EAX, [EBX + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_LOAD_OFFSET_ESP:
-        tmp = Common::String::format("LEA EAX, [SP + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_PTR_EDX_AL:
-        tmp = Common::String("MOV byte ptr [EDX], AL");
-        break;
-
-    case OP_MOV_PTR_EDX_EAX:
-        tmp = Common::String("MOV dword ptr [EDX], EAX");
-        break;
-
-    case OP_SHL_2:
-        tmp = Common::String("SHL EAX, 2");
-        break;
-
-    case OP_ADD_4:
-        tmp = Common::String("ADD EAX, 4");
-        break;
-
-    case OP_SUB_4:
-        tmp = Common::String("SUB EAX, 4");
-        break;
-
-    case OP_XCHG_ESP:
-        tmp = Common::String("XCHG EAX, [SP]");
-        break;
-
-    case OP_NEG_ADD:
-        tmp = Common::String("EAX = EDX - EAX (OP_NEG_ADD)");
-        break;
-
-    case OP_DIV:
-        tmp = Common::String("EAX = EDX / EAX  |   EDX = EDX %% EAX (DIV)");
-        break;
-
-    case OP_MOV_EAX_BPTR_EDI:
-        tmp = Common::String::format("MOV EAX, byte ptr [EDI + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EAX_BPTR_EBX:
-        tmp = Common::String::format("MOV EAX, byte ptr [EBX + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EAX_DPTR_EDI:
-        tmp = Common::String::format("MOV EAX, dword ptr [EDI + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EAX_DPTR_EBX:
-        tmp = Common::String::format("MOV EAX, dword ptr [EBX + %x]", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_MOV_EAX_BPTR_EAX:
-        tmp = Common::String("MOV EAX, byte ptr [EAX]");
-        break;
-
-    case OP_MOV_EAX_DPTR_EAX:
-        tmp = Common::String("MOV EAX, dword ptr [EAX]");
-        break;
-
-    case OP_PUSH_ESI_ADD_EDI:
-        tmp = Common::String::format("CALL %x", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_CALL_FUNC:
-        tmp = Common::String::format("CALL FUNC %d", readmem.getU32(address));
-        sz += 4;
-        break;
-
-    case OP_PUSH_ESI_SET_EDX_EDI:
-        tmp = Common::String("CALL EDX");
-        break;
-    }
-
-    if (size)
-        *size = sz;
-
-    return tmp;
+	case OP_CMP_GREQ:
+		tmp = Common::String("EAX =  EDX >= EAX (CMP_GREQ) //signed");
+		break;
+
+	case OP_CMP_NAE:
+		tmp = Common::String("EAX =  EDX < EAX (CMP_NAE) //unsigned");
+		break;
+
+	case OP_CMP_NA:
+		tmp = Common::String("EAX =  EDX <= EAX (CMP_NA) //unsigned");
+		break;
+
+	case OP_CMP_A:
+		tmp = Common::String("EAX =  EDX > EAX (CMP_A) //unsigned");
+		break;
+
+	case OP_CMP_AE:
+		tmp = Common::String("EAX =  EDX >= EAX (CMP_AE) //unsigned");
+		break;
+
+	case OP_BRANCH:
+		tmp = Common::String::format("BR %x", address + (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_JMP:
+		tmp = Common::String::format("JMP %x", address + (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_SP_ADD:
+		tmp = Common::String::format("ADD SP, %x", (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EDI_ECX_AL:
+		tmp = Common::String::format("MOV byte ptr[EDI + %x], AL", (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EBX_ECX_AL:
+		tmp = Common::String::format("MOV byte ptr[EBX + %x], AL", (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EDI_ECX_EAX:
+		tmp = Common::String::format("MOV dword ptr[EDI + %x], EAX", (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EBX_ECX_EAX:
+		tmp = Common::String::format("MOV dword ptr[EBX + %x], EAX", (int32)readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_RET:
+		tmp = Common::String("RET");
+		break;
+
+	case OP_RETX:
+		tmp = Common::String::format("RET%x", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EDX_EAX:
+		tmp = Common::String("MOV EDX, EAX");
+		break;
+
+	case OP_ADD_EAX_EDX:
+		tmp = Common::String("ADD EAX, EDX");
+		break;
+
+	case OP_MUL:
+		tmp = Common::String("MUL EDX");
+		break;
+
+	case OP_OR:
+		tmp = Common::String("OR EDX");
+		break;
+
+	case OP_XOR:
+		tmp = Common::String("XOR EDX");
+		break;
+
+	case OP_AND:
+		tmp = Common::String("AND EDX");
+		break;
+
+	case OP_NEG:
+		tmp = Common::String("NEG EAX");
+		break;
+
+	case OP_SAR:
+		tmp = Common::String("SAR EAX, EDX,EAX // edx>>eax");
+		break;
+
+	case OP_SHL:
+		tmp = Common::String("SHL EAX, EDX,EAX // edx<<eax");
+		break;
+
+	case OP_LOAD:
+		tmp = Common::String::format("MOV EAX, %x", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_INC:
+		tmp = Common::String("INC EAX");
+		break;
+
+	case OP_DEC:
+		tmp = Common::String("DEC EAX");
+		break;
+
+	case OP_XCHG:
+		tmp = Common::String("XCHG EAX,EDX");
+		break;
+
+	case OP_PUSH_EAX:
+		tmp = Common::String("PUSH EAX");
+		break;
+
+	case OP_POP_EDX:
+		tmp = Common::String("POP EDX");
+		break;
+
+	case OP_LOAD_OFFSET_EDI:
+	case OP_LOAD_OFFSET_EDI2:
+		tmp = Common::String::format("LEA EAX, [EDI + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_LOAD_OFFSET_EBX:
+		tmp = Common::String::format("LEA EAX, [EBX + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_LOAD_OFFSET_ESP:
+		tmp = Common::String::format("LEA EAX, [SP + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_PTR_EDX_AL:
+		tmp = Common::String("MOV byte ptr [EDX], AL");
+		break;
+
+	case OP_MOV_PTR_EDX_EAX:
+		tmp = Common::String("MOV dword ptr [EDX], EAX");
+		break;
+
+	case OP_SHL_2:
+		tmp = Common::String("SHL EAX, 2");
+		break;
+
+	case OP_ADD_4:
+		tmp = Common::String("ADD EAX, 4");
+		break;
+
+	case OP_SUB_4:
+		tmp = Common::String("SUB EAX, 4");
+		break;
+
+	case OP_XCHG_ESP:
+		tmp = Common::String("XCHG EAX, [SP]");
+		break;
+
+	case OP_NEG_ADD:
+		tmp = Common::String("EAX = EDX - EAX (OP_NEG_ADD)");
+		break;
+
+	case OP_DIV:
+		tmp = Common::String("EAX = EDX / EAX  |   EDX = EDX %% EAX (DIV)");
+		break;
+
+	case OP_MOV_EAX_BPTR_EDI:
+		tmp = Common::String::format("MOV EAX, byte ptr [EDI + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EAX_BPTR_EBX:
+		tmp = Common::String::format("MOV EAX, byte ptr [EBX + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EAX_DPTR_EDI:
+		tmp = Common::String::format("MOV EAX, dword ptr [EDI + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EAX_DPTR_EBX:
+		tmp = Common::String::format("MOV EAX, dword ptr [EBX + %x]", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_MOV_EAX_BPTR_EAX:
+		tmp = Common::String("MOV EAX, byte ptr [EAX]");
+		break;
+
+	case OP_MOV_EAX_DPTR_EAX:
+		tmp = Common::String("MOV EAX, dword ptr [EAX]");
+		break;
+
+	case OP_PUSH_ESI_ADD_EDI:
+		tmp = Common::String::format("CALL %x", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_CALL_FUNC:
+		tmp = Common::String::format("CALL FUNC %d", readmem.getU32(address));
+		sz += 4;
+		break;
+
+	case OP_PUSH_ESI_SET_EDX_EDI:
+		tmp = Common::String("CALL EDX");
+		break;
+	}
+
+	if (size)
+		*size = sz;
+
+	return tmp;
 }
 
 
 Common::String VM::disassembly(uint32 address) {
-    Common::String tmp;
+	Common::String tmp;
 
-    uint32 addr = address;
-    MemAccess readmem;
+	uint32 addr = address;
+	MemAccess readmem;
 
-    while (true) {
-        tmp += Common::String::format("%08x: ", addr);
+	while (true) {
+		tmp += Common::String::format("%08x: ", addr);
 
-        byte op = readmem.getU8(addr);
+		byte op = readmem.getU8(addr);
 
-        int sz = 1;
-        tmp += decodeOp(addr, &sz);
-        tmp += "\n";
+		int sz = 1;
+		tmp += decodeOp(addr, &sz);
+		tmp += "\n";
 
-        addr += sz;
+		addr += sz;
 
-        if (op == OP_EXIT)
-            break;
-    }
+		if (op == OP_EXIT)
+			break;
+	}
 
-    return tmp;
+	return tmp;
 }
 
 
 Common::String VM::opLog(const Common::Array<OpLog> &log) {
-    Common::String tmp;
+	Common::String tmp;
 
-    for (const OpLog &l : log) {
-        tmp += Common::String::format("%08x: SP:%04x OP:[%02d] ", l.addr, l.sp, l.op) + decodeOp(l.addr) + "\n";
-    }
+	for (const OpLog &l : log) {
+		tmp += Common::String::format("%08x: SP:%04x OP:[%02d] ", l.addr, l.sp, l.op) + decodeOp(l.addr) + "\n";
+	}
 
-    Common::DumpFile f;
+	Common::DumpFile f;
 
-    if (f.open("oplog", true)) {
-        f.writeString(tmp);
-        f.flush();
-        f.close();
-    }
+	if (f.open("oplog", true)) {
+		f.writeString(tmp);
+		f.flush();
+		f.close();
+	}
 
-    return tmp;
+	return tmp;
 }
 
 void VM::printDisassembly(uint32 address) {
-    Common::String tmp = disassembly(address);
-    warning("%s", tmp.c_str());
+	Common::String tmp = disassembly(address);
+	warning("%s", tmp.c_str());
 }
 
 }
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index b5047875b8a..cb419bbcec3 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -28,186 +28,190 @@ namespace Gamos {
 
 class VM {
 public:
-    static constexpr const uint THREADS_COUNT = 2;
-    static constexpr const uint STACK_SIZE = 0x100;
-    static constexpr const uint STACK_POS = 0x80;
-
-    enum OP{
-        OP_EXIT = 0,
-        OP_CMP_EQ = 1,
-        OP_CMP_NE = 2,
-        OP_CMP_LE = 3,
-        OP_CMP_LEQ = 4,
-        OP_CMP_GR = 5,
-        OP_CMP_GREQ = 6,
-        OP_CMP_NAE = 7,
-        OP_CMP_NA = 8,
-        OP_CMP_A = 9,
-        OP_CMP_AE = 10,
-        OP_BRANCH = 11,
-        OP_JMP = 12,
-        OP_SP_ADD = 13,
-        OP_MOV_EDI_ECX_AL = 14,
-        OP_MOV_EBX_ECX_AL = 15,
-        OP_MOV_EDI_ECX_EAX = 16,
-        OP_MOV_EBX_ECX_EAX = 17,
-        OP_RET = 18,
-        OP_RETX = 19,
-        OP_MOV_EDX_EAX = 20,
-        OP_ADD_EAX_EDX = 21,
-        OP_MUL = 22,
-        OP_OR = 23,
-        OP_XOR = 24,
-        OP_AND = 25,
-        OP_NEG = 26,
-        OP_SAR = 27,
-        OP_SHL = 28,
-        OP_LOAD = 29,
-        OP_INC = 30,
-        OP_DEC = 31,
-        OP_XCHG = 32,
-        OP_PUSH_EAX = 33,
-        OP_POP_EDX = 34,
-        OP_LOAD_OFFSET_EDI = 35,
-        OP_LOAD_OFFSET_EDI2 = 36,
-        OP_LOAD_OFFSET_EBX = 37,
-        OP_LOAD_OFFSET_ESP = 38,
-        OP_MOV_PTR_EDX_AL = 39,
-        OP_MOV_PTR_EDX_EAX = 40,
-        OP_SHL_2 = 41,
-        OP_ADD_4 = 42,
-        OP_SUB_4 = 43,
-        OP_XCHG_ESP = 44,
-        OP_NEG_ADD = 45,
-        OP_DIV = 46,
-        OP_MOV_EAX_BPTR_EDI = 47,
-        OP_MOV_EAX_BPTR_EBX = 48,
-        OP_MOV_EAX_DPTR_EDI = 49,
-        OP_MOV_EAX_DPTR_EBX = 50,
-        OP_MOV_EAX_BPTR_EAX = 51,
-        OP_MOV_EAX_DPTR_EAX = 52,
-        OP_PUSH_ESI_ADD_EDI = 53,
-        OP_CALL_FUNC = 54,
-        OP_PUSH_ESI_SET_EDX_EDI = 55,
-
-        OP_MAX
-    };
-
-    enum MEMREF {
-        REF_UNK = 0,
-        REF_STACK = 1,
-        REF_EBX = 2,
-        REF_EDI = 3
-    };
-
-    struct Reg {
-        uint32 val = 0;
-        byte ref = REF_UNK;
-    };
-
-    typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
-
-    struct MemoryBlock {
-        uint32 address = 0;
-        byte data[256];
-
-        MemoryBlock() {
-            address = 0;
-            memset(data, 0, sizeof(data));
-        }
-    };
-
-    struct OpLog {
-        uint32 addr;
-        OP op;
-        uint32 sp;
-    };
-
-    struct MemAccess {
-        MemoryBlock *_currentBlock = nullptr;
-
-        uint8 getU8(uint32 address);
-        uint32 getU32(uint32 address);
-
-        void setU8(uint32 address, uint8 val);
-        void setU32(uint32 address, uint32 val);
-
-        void reset() { _currentBlock = nullptr; }
-    };
+	static constexpr const uint THREADS_COUNT = 2;
+	static constexpr const uint STACK_SIZE = 0x100;
+	static constexpr const uint STACK_POS = 0x80;
+
+	enum OP {
+		OP_EXIT = 0,
+		OP_CMP_EQ = 1,
+		OP_CMP_NE = 2,
+		OP_CMP_LE = 3,
+		OP_CMP_LEQ = 4,
+		OP_CMP_GR = 5,
+		OP_CMP_GREQ = 6,
+		OP_CMP_NAE = 7,
+		OP_CMP_NA = 8,
+		OP_CMP_A = 9,
+		OP_CMP_AE = 10,
+		OP_BRANCH = 11,
+		OP_JMP = 12,
+		OP_SP_ADD = 13,
+		OP_MOV_EDI_ECX_AL = 14,
+		OP_MOV_EBX_ECX_AL = 15,
+		OP_MOV_EDI_ECX_EAX = 16,
+		OP_MOV_EBX_ECX_EAX = 17,
+		OP_RET = 18,
+		OP_RETX = 19,
+		OP_MOV_EDX_EAX = 20,
+		OP_ADD_EAX_EDX = 21,
+		OP_MUL = 22,
+		OP_OR = 23,
+		OP_XOR = 24,
+		OP_AND = 25,
+		OP_NEG = 26,
+		OP_SAR = 27,
+		OP_SHL = 28,
+		OP_LOAD = 29,
+		OP_INC = 30,
+		OP_DEC = 31,
+		OP_XCHG = 32,
+		OP_PUSH_EAX = 33,
+		OP_POP_EDX = 34,
+		OP_LOAD_OFFSET_EDI = 35,
+		OP_LOAD_OFFSET_EDI2 = 36,
+		OP_LOAD_OFFSET_EBX = 37,
+		OP_LOAD_OFFSET_ESP = 38,
+		OP_MOV_PTR_EDX_AL = 39,
+		OP_MOV_PTR_EDX_EAX = 40,
+		OP_SHL_2 = 41,
+		OP_ADD_4 = 42,
+		OP_SUB_4 = 43,
+		OP_XCHG_ESP = 44,
+		OP_NEG_ADD = 45,
+		OP_DIV = 46,
+		OP_MOV_EAX_BPTR_EDI = 47,
+		OP_MOV_EAX_BPTR_EBX = 48,
+		OP_MOV_EAX_DPTR_EDI = 49,
+		OP_MOV_EAX_DPTR_EBX = 50,
+		OP_MOV_EAX_BPTR_EAX = 51,
+		OP_MOV_EAX_DPTR_EAX = 52,
+		OP_PUSH_ESI_ADD_EDI = 53,
+		OP_CALL_FUNC = 54,
+		OP_PUSH_ESI_SET_EDX_EDI = 55,
+
+		OP_MAX
+	};
+
+	enum MEMREF {
+		REF_UNK = 0,
+		REF_STACK = 1,
+		REF_EBX = 2,
+		REF_EDI = 3
+	};
+
+	struct Reg {
+		uint32 val = 0;
+		byte ref = REF_UNK;
+	};
+
+	typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
+
+	struct MemoryBlock {
+		uint32 address = 0;
+		byte data[256];
+
+		MemoryBlock() {
+			address = 0;
+			memset(data, 0, sizeof(data));
+		}
+	};
+
+	struct OpLog {
+		uint32 addr;
+		OP op;
+		uint32 sp;
+	};
+
+	struct MemAccess {
+		MemoryBlock *_currentBlock = nullptr;
+
+		uint8 getU8(uint32 address);
+		uint32 getU32(uint32 address);
+
+		void setU8(uint32 address, uint8 val);
+		void setU32(uint32 address, uint32 val);
+
+		void reset() {
+			_currentBlock = nullptr;
+		}
+	};
 
 public:
-    inline static MemAccess& memory() {return _memAccess;};
+	inline static MemAccess &memory() {
+		return _memAccess;
+	};
 
-    static void clearMemory();
-    static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
+	static void clearMemory();
+	static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
 
-    static void zeroMemory(uint32 address, uint32 count);
+	static void zeroMemory(uint32 address, uint32 count);
 
-    static MemoryBlock *findMemoryBlock(uint32 address);
+	static MemoryBlock *findMemoryBlock(uint32 address);
 
-    static MemoryBlock *createBlock(uint32 address);
+	static MemoryBlock *createBlock(uint32 address);
 
-    static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
-    static void readMemBlocks(byte *dst, uint32 address, uint32 count);
+	static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+	static void readMemBlocks(byte *dst, uint32 address, uint32 count);
 
-    static Common::String readMemString(uint32 address, uint32 maxLen = 256);
+	static Common::String readMemString(uint32 address, uint32 maxLen = 256);
 
-    Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
+	Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
 
-    uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
+	uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
 
-    static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
+	static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
 
-    static int32 getS32(const void *);
-    static uint32 getU32(const void *);
-    static void setU32(void *, uint32 val);
+	static int32 getS32(const void *);
+	static uint32 getU32(const void *);
+	static void setU32(void *, uint32 val);
 
-    void push32(uint32 val);
-    uint32 pop32();
+	void push32(uint32 val);
+	uint32 pop32();
 
-    void pushReg(Reg reg);
-    Reg popReg();
+	void pushReg(Reg reg);
+	Reg popReg();
 
-    uint32 getMem32(int memtype, uint32 offset);
-    uint8 getMem8(int memtype, uint32 offset);
+	uint32 getMem32(int memtype, uint32 offset);
+	uint8 getMem8(int memtype, uint32 offset);
 
-    void setMem32(int memtype, uint32 offset, uint32 val);
-    void setMem8(int memtype, uint32 offset, uint8 val);
+	void setMem32(int memtype, uint32 offset, uint32 val);
+	void setMem8(int memtype, uint32 offset, uint8 val);
 
-    static Common::String decodeOp(uint32 address, int *size = nullptr);
-    static Common::String disassembly(uint32 address);
+	static Common::String decodeOp(uint32 address, int *size = nullptr);
+	static Common::String disassembly(uint32 address);
 
-    static Common::String opLog(const Common::Array<OpLog> &log);
+	static Common::String opLog(const Common::Array<OpLog> &log);
 
-    static void printDisassembly(uint32 address);
+	static void printDisassembly(uint32 address);
 
 private:
 
 public:
-    bool _inUse = false;
+	bool _inUse = false;
 
-    uint32 ESI = 0;
-    byte *EBX = nullptr;
-    Reg EAX;
-    Reg EDX;
-    Reg ECX;
-    uint32 SP = 0;
-    byte _stack[STACK_SIZE];
-    byte _stackT[STACK_SIZE];
+	uint32 ESI = 0;
+	byte *EBX = nullptr;
+	Reg EAX;
+	Reg EDX;
+	Reg ECX;
+	uint32 SP = 0;
+	byte _stack[STACK_SIZE];
+	byte _stackT[STACK_SIZE];
 
 private:
-    MemAccess _readAccess;
-    MemAccess _writeAccess;
+	MemAccess _readAccess;
+	MemAccess _writeAccess;
 
 public:
-    static CallDispatcher _callFuncs;
-    static void *_callingObject;
+	static CallDispatcher _callFuncs;
+	static void *_callingObject;
 
-    static Common::HashMap<uint32, MemoryBlock> _memMap;
-    static bool _interrupt;
+	static Common::HashMap<uint32, MemoryBlock> _memMap;
+	static bool _interrupt;
 
-    static VM _threads[THREADS_COUNT];
-    static MemAccess _memAccess;
+	static VM _threads[THREADS_COUNT];
+	static MemAccess _memAccess;
 };
 
 


Commit: ed9300c387d93dbc9784d191bb1ac7bcddf30bf2
    https://github.com/scummvm/scummvm/commit/ed9300c387d93dbc9784d191bb1ac7bcddf30bf2
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:39+01:00

Commit Message:
GAMOS: Removed superfluous semicolons

Changed paths:
    engines/gamos/file.cpp
    engines/gamos/file.h
    engines/gamos/keycodes.h
    engines/gamos/music.cpp
    engines/gamos/music.h
    engines/gamos/pool.h


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index 48c4ba4a19d..1210fbf90d9 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -206,4 +206,4 @@ void Archive::decompress(RawData const *in, RawData *out) {
 }
 
 
-};
+}
diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index 82c42df9afc..5a660f08474 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -82,6 +82,6 @@ private:
 
 
 
-}; // namespace Gamos
+} // namespace Gamos
 
 #endif // GAMOS_FILE_H
diff --git a/engines/gamos/keycodes.h b/engines/gamos/keycodes.h
index 0745004afe9..5952cb27160 100644
--- a/engines/gamos/keycodes.h
+++ b/engines/gamos/keycodes.h
@@ -278,7 +278,7 @@ public:
 };
 
 
-};
+}
 
 
 #endif
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index 813dc40bd29..649b0998e34 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -187,4 +187,4 @@ void MidiMusic::_timerProc(void *data) {
 	}
 }
 
-};
+}
diff --git a/engines/gamos/music.h b/engines/gamos/music.h
index 2cf482add7b..11f061c1d08 100644
--- a/engines/gamos/music.h
+++ b/engines/gamos/music.h
@@ -62,6 +62,6 @@ public:
 	static void _timerProc(void *data);
 };
 
-};
+}
 
 #endif //GAMOS_MUSIC_H
diff --git a/engines/gamos/pool.h b/engines/gamos/pool.h
index be3a0fb55c3..20572f17b29 100644
--- a/engines/gamos/pool.h
+++ b/engines/gamos/pool.h
@@ -155,6 +155,6 @@ protected:
 	size_type _size = 0;
 };
 
-};
+}
 
 #endif


Commit: f1773b8d7561241f358e4d0e2d9d448cb4436161
    https://github.com/scummvm/scummvm/commit/f1773b8d7561241f358e4d0e2d9d448cb4436161
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:40+01:00

Commit Message:
GAMOS: Fix not working skip of Pilots2 intro caused by dealigned read of keycodes

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 05ee1b29b50..a0e2b81b599 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1088,6 +1088,7 @@ void GamosEngine::readData2(const RawData &data) {
 		_d2_fld17 = dataStream.readByte(); // x17
 		_d2_fld18 = dataStream.readByte(); // x18
 		_d2_fld19 = dataStream.readByte(); // x19
+		dataStream.seek(0x1c);
 		_d2_outLeft = dataStream.readSint32LE(); // x1c
 		_d2_outTop = dataStream.readSint32LE(); // x20
 		_d2_index = dataStream.readSint16LE(); // x24


Commit: 7146e5a7c402ed271d28adb54fb6b0366fa24c37
    https://github.com/scummvm/scummvm/commit/7146e5a7c402ed271d28adb54fb6b0366fa24c37
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:40+01:00

Commit Message:
GAMOS: Fix crash on attempt of create actions dump caused by empty path

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index a0e2b81b599..61b374bce14 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -3605,7 +3605,7 @@ bool GamosEngine::FUN_004038b8() {
 }
 
 void GamosEngine::dumpActions() {
-	Common::String t = Common::String::format("actions_%d.txt", _currentModuleID);
+	Common::String t = Common::String::format("./actions_%d.txt", _currentModuleID);
 
 	Common::DumpFile f;
 


Commit: ac78097f243ecf76b0e6ab3ea11f6dd83b238d3c
    https://github.com/scummvm/scummvm/commit/ac78097f243ecf76b0e6ab3ea11f6dd83b238d3c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:40+01:00

Commit Message:
GAMOS: Implement update of mouse cursor

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 61b374bce14..e5cb5448330 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "gamos/gamos.h"
+#include "graphics/cursorman.h"
 #include "graphics/framelimiter.h"
 #include "gamos/detection.h"
 #include "gamos/console.h"
@@ -1105,7 +1106,7 @@ void GamosEngine::readData2(const RawData &data) {
 		_svFps = dataStream.readByte(); // x1b
 		_svFrame = dataStream.readSint32LE(); // x1c
 		_midiTrack = dataStream.readUint32LE(); //0x38
-		_mouseCursorImgId = dataStream.readUint32LE(); //0x3c
+		_mouseCursorImgId = dataStream.readSint32LE(); //0x3c
 		//0x40
 		for (int i = 0; i < 12; i++) {
 			_messageProc._keyCodes[i] = dataStream.readByte();
@@ -1140,7 +1141,7 @@ void GamosEngine::readData2(const RawData &data) {
 		_svFps = dataStream.readByte(); // x1b
 		_svFrame = dataStream.readSint32LE(); // x1c
 		_midiTrack = dataStream.readUint32LE(); // x20
-		_mouseCursorImgId = dataStream.readUint32LE(); // x24
+		_mouseCursorImgId = dataStream.readSint32LE(); // x24
 		//0x28
 		for (int i = 0; i < 12; i++) {
 			_messageProc._keyCodes[i] = dataStream.readByte();
@@ -1181,7 +1182,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 		while (loop) {
 			if (!PTR_00417388) {
-				if (FUN_004033a8(mouseMove) && FUN_004038b8())
+				if (updateMouseCursor(mouseMove) && FUN_004038b8())
 					return 1;
 				else
 					return 0;
@@ -2856,27 +2857,8 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 
 void GamosEngine::setCursor(int id, bool dirtRect) {
 	if (_unk9 == 0) {
-		if (dirtRect && _cursorObject.sprId != -1)
-			addDirtRectOnObject(&_cursorObject);
-
 		_mouseCursorImgId = id;
-
-		_cursorObject.sprId = id;
-		_cursorObject.frame = 0;
-		_cursorObject.seqId = 0;
-
-		_cursorObject.flags = 0xc1;
-		_cursorObject.fld_2 = _sprites[id].field_3; // max frames
-		_cursorObject.actID = 0; //frame
-		_cursorObject.x = 0;
-		_cursorObject.y = 0;
-		_cursorObject.pImg = &_sprites[id].sequences[0]->operator[](0);
-
-		_system->setMouseCursor(_cursorObject.pImg->image->surface.getPixels(),
-		                        _cursorObject.pImg->image->surface.w,
-		                        _cursorObject.pImg->image->surface.h,
-		                        _cursorObject.pImg->xoffset,
-		                        _cursorObject.pImg->yoffset, 0);
+		_cursorFrame = 0;
 	}
 }
 
@@ -3592,10 +3574,35 @@ void GamosEngine::FUN_004025d0() {
 }
 
 
-bool GamosEngine::FUN_004033a8(Common::Point mouseMove) {
-	_cursorObject.x = mouseMove.x;
-	_cursorObject.y = mouseMove.y;
-	warning("Not implemented FUN_004033a8");
+bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
+	if (_unk9)
+		return true;
+
+	if (_mouseCursorImgId >= 0) {
+		Sprite &cursorSpr = _sprites[_mouseCursorImgId];
+
+		if (cursorSpr.field_3 > 1) {
+
+			_cursorFrame++;
+			if (_cursorFrame >= cursorSpr.field_3)
+				_cursorFrame = 0;
+
+			ImagePos &impos = cursorSpr.sequences[0]->operator[](_cursorFrame);
+			Graphics::Surface &surf = impos.image->surface;
+			CursorMan.replaceCursor(surf, impos.xoffset, impos.yoffset, 0);
+		} else {
+			if (_currentCursor != _mouseCursorImgId) {
+				ImagePos &impos = cursorSpr.sequences[0]->operator[](0);
+				Graphics::Surface &surf = impos.image->surface;
+				CursorMan.replaceCursor(surf, impos.xoffset, impos.yoffset, 0);
+			}
+		}
+	} else {
+		if (_currentCursor != _mouseCursorImgId)
+			CursorMan.setDefaultArrowCursor();
+	}
+
+	_currentCursor = _mouseCursorImgId;
 	return true;
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4994df92ecc..c371324b45e 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -313,7 +313,10 @@ private:
 	uint32 _seed = 1;
 
 	Object _cursorObject;
-	uint32 _mouseCursorImgId = 0;
+
+	int32 _cursorFrame = 0;
+	int32 _mouseCursorImgId = 0;
+	int32 _currentCursor = -1;
 
 
 
@@ -529,7 +532,7 @@ protected:
 
 	bool FUN_00402fb4();
 
-	bool FUN_004033a8(Common::Point mouseMove);
+	bool updateMouseCursor(Common::Point mouseMove);
 	bool FUN_004038b8();
 	bool FUN_00402bc4();
 	bool FUN_00402f34(bool p1, bool p2, Object *obj);
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index f409b1c59f7..3d5cec15f25 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -230,7 +230,7 @@ void GamosEngine::writeStateData(Common::SeekableWriteStream *stream) {
 	stream->writeByte(_svFps); // 0x33
 	stream->writeSint32LE(_svFrame); // 0x34
 	stream->writeUint32LE(_midiTrack); // 0x38
-	stream->writeUint32LE(_mouseCursorImgId); // 0x3c
+	stream->writeSint32LE(_mouseCursorImgId); // 0x3c
 	// 0x40
 	for (int i = 0; i < 12; i++)
 		stream->writeByte(_messageProc._keyCodes[i]);
@@ -267,7 +267,7 @@ void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
 	_svFps = dataStream->readByte(); // x1b
 	_svFrame = dataStream->readSint32LE(); // x1c
 	_midiTrack = dataStream->readUint32LE(); //0x38
-	_mouseCursorImgId = dataStream->readUint32LE(); //0x3c
+	_mouseCursorImgId = dataStream->readSint32LE(); //0x3c
 
 	for (int i = 0; i < 12; i++)
 		_messageProc._keyCodes[i] = dataStream->readByte();


Commit: b37dc2f059807e958f28426547336f85dbe16bbb
    https://github.com/scummvm/scummvm/commit/b37dc2f059807e958f28426547336f85dbe16bbb
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:41+01:00

Commit Message:
GAMOS: Rename _d2 fields identified as scroll parameters

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index e5cb5448330..fbc52b96f1a 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1090,16 +1090,16 @@ void GamosEngine::readData2(const RawData &data) {
 		_d2_fld18 = dataStream.readByte(); // x18
 		_d2_fld19 = dataStream.readByte(); // x19
 		dataStream.seek(0x1c);
-		_d2_outLeft = dataStream.readSint32LE(); // x1c
-		_d2_outTop = dataStream.readSint32LE(); // x20
-		_d2_index = dataStream.readSint16LE(); // x24
-		_d2_fld26 = dataStream.readSint16LE(); // x26
-		_d2_fld28 = dataStream.readSint16LE(); // x28
-		_d2_fld2a = dataStream.readSint16LE(); // x2a
-		_d2_fld2c = dataStream.readByte(); // x2c
-		_d2_fld2d = dataStream.readByte(); // x2d
-		_d2_fld2e = dataStream.readByte(); // x2e
-		_d2_fld2f = dataStream.readByte(); // x2f
+		_scrollX = dataStream.readSint32LE(); // x1c
+		_scrollY = dataStream.readSint32LE(); // x20
+		_scrollTrackObj = dataStream.readSint16LE(); // x24
+		_scrollSpeed = dataStream.readSint16LE(); // x26
+		_scrollCutoff = dataStream.readSint16LE(); // x28
+		_scrollSpeedReduce = dataStream.readSint16LE(); // x2a
+		_scrollBorderL = dataStream.readByte(); // x2c
+		_scrollBorderR = dataStream.readByte(); // x2d
+		_scrollBorderU = dataStream.readByte(); // x2e
+		_scrollBorderB = dataStream.readByte(); // x2f
 		_sndChannels = dataStream.readByte(); // x30
 		_sndVolume = dataStream.readByte(); // x34
 		_midiVolume = dataStream.readByte(); // x1a
@@ -1125,16 +1125,16 @@ void GamosEngine::readData2(const RawData &data) {
 		_d2_fld17 = dataStream.readByte(); // x17
 		_d2_fld18 = 0;
 		_d2_fld19 = 0;
-		_d2_outLeft = 0;
-		_d2_outTop = 0;
-		_d2_index = -1;
-		_d2_fld26 = 16;
-		_d2_fld28 = 80;
-		_d2_fld2a = -1;
-		_d2_fld2c = 0;
-		_d2_fld2d = 0;
-		_d2_fld2e = 0;
-		_d2_fld2f = 0;
+		_scrollX = 0;
+		_scrollY = 0;
+		_scrollTrackObj = -1;
+		_scrollSpeed = 16;
+		_scrollCutoff = 80;
+		_scrollSpeedReduce = -1;
+		_scrollBorderL = 0;
+		_scrollBorderR = 0;
+		_scrollBorderU = 0;
+		_scrollBorderB = 0;
 		_sndChannels = dataStream.readByte(); // x18
 		_sndVolume = dataStream.readByte(); // x19
 		_midiVolume = dataStream.readByte(); // x1a
@@ -2887,8 +2887,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	if (act1 != 0xe)
 		tmpb |= act1 | 0x40;
 
-	//actPos +=
-	warning("Not full FUN_00402c2c");
+	actPos += Common::Point(_scrollX, _scrollY);
 
 	Object *pobj = nullptr;
 	uint8 actT = 0;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index c371324b45e..2fe8e0f3544 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -341,16 +341,16 @@ private:
 	uint8 _d2_fld17 = 0;
 	uint8 _d2_fld18 = 0;
 	uint8 _d2_fld19 = 0;
-	int32 _d2_outLeft = 0;
-	int32 _d2_outTop = 0;
-	int32 _d2_index = 0;
-	int16 _d2_fld26 = 0;
-	int16 _d2_fld28 = 0;
-	int16 _d2_fld2a = 0;
-	uint8 _d2_fld2c = 0;
-	uint8 _d2_fld2d = 0;
-	uint8 _d2_fld2e = 0;
-	uint8 _d2_fld2f = 0;
+	int32 _scrollX = 0;
+	int32 _scrollY = 0;
+	int32 _scrollTrackObj = 0;
+	int16 _scrollSpeed = 0;
+	int16 _scrollCutoff = 0;
+	int16 _scrollSpeedReduce = 0;
+	uint8 _scrollBorderL = 0;
+	uint8 _scrollBorderR = 0;
+	uint8 _scrollBorderU = 0;
+	uint8 _scrollBorderB = 0;
 	uint8 _sndChannels = 0;
 	uint8 _sndVolume = 0;
 	uint8 _midiVolume = 0;
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 3d5cec15f25..5589357550b 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -214,16 +214,16 @@ void GamosEngine::writeStateData(Common::SeekableWriteStream *stream) {
 	stream->writeByte(_d2_fld19); // 0x19
 	stream->writeByte(0); // 0x1a
 	stream->writeByte(0); // 0x1b
-	stream->writeSint32LE(_d2_outLeft); // 0x1c
-	stream->writeSint32LE(_d2_outTop); // 0x20
-	stream->writeSint16LE(_d2_index); // 0x24
-	stream->writeSint16LE(_d2_fld26); // 0x26
-	stream->writeSint16LE(_d2_fld28); // 0x28
-	stream->writeSint16LE(_d2_fld2a); // 0x2a
-	stream->writeByte(_d2_fld2c); // 0x2c
-	stream->writeByte(_d2_fld2d); // 0x2d
-	stream->writeByte(_d2_fld2e); // 0x2e
-	stream->writeByte(_d2_fld2f); // 0x2f
+	stream->writeSint32LE(_scrollX); // 0x1c
+	stream->writeSint32LE(_scrollY); // 0x20
+	stream->writeSint16LE(_scrollTrackObj); // 0x24
+	stream->writeSint16LE(_scrollSpeed); // 0x26
+	stream->writeSint16LE(_scrollCutoff); // 0x28
+	stream->writeSint16LE(_scrollSpeedReduce); // 0x2a
+	stream->writeByte(_scrollBorderL); // 0x2c
+	stream->writeByte(_scrollBorderR); // 0x2d
+	stream->writeByte(_scrollBorderU); // 0x2e
+	stream->writeByte(_scrollBorderB); // 0x2f
 	stream->writeByte(_sndChannels); // 0x30
 	stream->writeByte(_sndVolume); // 0x31
 	stream->writeByte(_midiVolume); // 0x32
@@ -251,16 +251,16 @@ void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
 	_d2_fld18 = dataStream->readByte(); // x18
 	_d2_fld19 = dataStream->readByte(); // x19
 	dataStream->seek(0x1c);
-	_d2_outLeft = dataStream->readSint32LE(); // x1c
-	_d2_outTop = dataStream->readSint32LE(); // x20
-	_d2_index = dataStream->readSint16LE(); // x24
-	_d2_fld26 = dataStream->readSint16LE(); // x26
-	_d2_fld28 = dataStream->readSint16LE(); // x28
-	_d2_fld2a = dataStream->readSint16LE(); // x2a
-	_d2_fld2c = dataStream->readByte(); // x2c
-	_d2_fld2d = dataStream->readByte(); // x2d
-	_d2_fld2e = dataStream->readByte(); // x2e
-	_d2_fld2f = dataStream->readByte(); // x2f
+	_scrollX = dataStream->readSint32LE(); // x1c
+	_scrollY = dataStream->readSint32LE(); // x20
+	_scrollTrackObj = dataStream->readSint16LE(); // x24
+	_scrollSpeed = dataStream->readSint16LE(); // x26
+	_scrollCutoff = dataStream->readSint16LE(); // x28
+	_scrollSpeedReduce = dataStream->readSint16LE(); // x2a
+	_scrollBorderL = dataStream->readByte(); // x2c
+	_scrollBorderR = dataStream->readByte(); // x2d
+	_scrollBorderU = dataStream->readByte(); // x2e
+	_scrollBorderB = dataStream->readByte(); // x2f
 	_sndChannels = dataStream->readByte(); // x30
 	_sndVolume = dataStream->readByte(); // x34
 	_midiVolume = dataStream->readByte(); // x1a


Commit: ad4a8a72941886831cebcfb0019190e3c24f8b74
    https://github.com/scummvm/scummvm/commit/ad4a8a72941886831cebcfb0019190e3c24f8b74
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:41+01:00

Commit Message:
GAMOS: Rename _bkgUpdateSizes to _bkgSize

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index fbc52b96f1a..0de6eb93d73 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -669,8 +669,8 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	uint32 bkgnum2 = dataStream.readUint32LE(); // 4
 	_statesWidth = dataStream.readUint32LE(); // 8
 	_statesHeight = dataStream.readUint32LE(); // c
-	_bkgUpdateSizes.x = dataStream.readUint32LE(); // 10
-	_bkgUpdateSizes.y = dataStream.readUint32LE(); // 14
+	_bkgSize.x = dataStream.readUint32LE(); // 10
+	_bkgSize.y = dataStream.readUint32LE(); // 14
 	/* bkgbufferSize */ dataStream.readUint32LE(); // 18
 	uint32 actsCount = dataStream.readUint32LE(); // 1c
 	uint32 unk1Count = dataStream.readUint32LE(); // 20
@@ -1064,7 +1064,7 @@ bool GamosEngine::setPaletteCurrentGS() {
 	if (!usePalette(_gameScreens[curGS].palette, 256, _currentFade, true))
 		return false;
 
-	addDirtyRect(Common::Rect(_bkgUpdateSizes.x, _bkgUpdateSizes.y));
+	addDirtyRect(Common::Rect(_bkgSize.x, _bkgSize.y));
 
 	return true;
 }
@@ -2197,7 +2197,7 @@ void GamosEngine::doDraw() {
 	}
 
 	if (_currentFade)
-		updateScreen(true, Common::Rect(_bkgUpdateSizes.x, _bkgUpdateSizes.y));
+		updateScreen(true, Common::Rect(_bkgSize.x, _bkgSize.y));
 
 	_currentFade = 0;
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 2fe8e0f3544..acaddcc8471 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -290,7 +290,7 @@ private:
 	Common::Array<Image *> _images;
 	Common::Array<ImageSeq *> _imgSeq;
 
-	Common::Point _bkgUpdateSizes;
+	Common::Point _bkgSize;
 
 	Common::Array<GameScreen> _gameScreens;
 
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 5589357550b..4363fefbd06 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -94,7 +94,7 @@ bool GamosEngine::switchToGameScreen(int id, bool doNotStore) {
 	_currentGameScreen = id;
 	GameScreen &gs = _gameScreens[id];
 
-	addDirtyRect(Common::Rect(Common::Point(), _bkgUpdateSizes));
+	addDirtyRect(Common::Rect(Common::Point(), _bkgSize));
 
 	_states = gs._savedStates;
 


Commit: df7cf01c7bc05b83312bf74155b497ab492dd59f
    https://github.com/scummvm/scummvm/commit/df7cf01c7bc05b83312bf74155b497ab492dd59f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:41+01:00

Commit Message:
GAMOS: Implement screen scroll code

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 0de6eb93d73..b2f8df0483d 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -134,8 +134,6 @@ Common::Error GamosEngine::run() {
 			_messageProc._act2 = ACT_NONE;
 			_messageProc._act1 = ACT_NONE;
 			_messageProc._rawKeyCode = ACT_NONE;
-
-			doDraw();
 		} else {
 			if (prevMousePos != _messageProc._mouseReportedPos)
 				_screen->update();
@@ -1182,7 +1180,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 		while (loop) {
 			if (!PTR_00417388) {
-				if (updateMouseCursor(mouseMove) && FUN_004038b8())
+				if (updateMouseCursor(mouseMove) && scrollAndDraw())
 					return 1;
 				else
 					return 0;
@@ -3605,8 +3603,95 @@ bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
 	return true;
 }
 
-bool GamosEngine::FUN_004038b8() {
-	warning("Not implemented FUN_004038b8");
+bool GamosEngine::scrollAndDraw() {
+	if (_scrollTrackObj != -1) {
+		Object &obj = _objects[_scrollTrackObj];
+		Common::Point objPos(obj.pos * _gridCellW, obj.blk * _gridCellH);
+
+		Common::Rect objArea;
+		objArea.right = _scrollX + _width - (_scrollBorderR + 1) * _gridCellW;
+		objArea.bottom = _scrollY + _height - (_scrollBorderB + 1) * _gridCellH;
+		objArea.left = _scrollX + _scrollBorderL * _gridCellW;
+		objArea.top = _scrollY + _scrollBorderU * _gridCellH;
+
+		int32 lDistance = 0;
+		int32 rDistance = 0;
+		int32 uDistance = 0;
+		int32 dDistance = 0;
+
+		if (objPos.x < objArea.left) {
+            lDistance = objArea.left - objPos.x;
+            if (lDistance > _scrollX)
+                lDistance = _scrollX;
+        } else if (objPos.x > objArea.right) {
+            int32 maxR = _bkgSize.x - _width - _scrollX;
+            rDistance = objPos.x - objArea.right;
+            if (rDistance > maxR)
+                rDistance = maxR;
+        }
+
+        if (objPos.y < objArea.top) {
+            uDistance = objArea.top - objPos.y;
+            if (uDistance > _scrollY)
+                uDistance = _scrollY;
+        } else if (objPos.y > objArea.bottom) {
+            int32 maxD = _bkgSize.y - _height - _scrollY;
+            dDistance = objPos.y - objArea.bottom;
+            if (dDistance > maxD)
+                dDistance = maxD;
+        }
+
+		if (lDistance != 0 || rDistance != 0 || uDistance != 0 || dDistance != 0) {
+			int32 lSpeed = _scrollSpeed;
+			int32 rSpeed = _scrollSpeed;
+			int32 uSpeed = _scrollSpeed;
+			int32 dSpeed = _scrollSpeed;
+			while (lDistance != 0 || rDistance != 0 || uDistance != 0 || dDistance != 0) {
+				int32 lDelta = (lDistance < lSpeed) ? lDistance : lSpeed;
+				int32 rDelta = (rDistance < rSpeed) ? rDistance : rSpeed;
+				int32 uDelta = (uDistance < uSpeed) ? uDistance : uSpeed;
+				int32 dDelta = (dDistance < dSpeed) ? dDistance : dSpeed;
+
+				_scrollX += rDelta - lDelta;
+				_scrollY += dDelta - uDelta;
+
+				doDraw();
+
+				lDistance -= lDelta;
+				if (lDistance != 0 && lDistance <= _scrollCutoff) {
+					lSpeed += _scrollSpeedReduce;
+					if (lSpeed < 2)
+						lSpeed = 1;
+				}
+
+				rDistance -= rDelta;
+				if (rDistance != 0 && rDistance <= _scrollCutoff) {
+					rSpeed += _scrollSpeedReduce;
+					if (rSpeed < 2)
+						rSpeed = 1;
+				}
+
+				uDistance -= uDelta;
+				if (uDistance != 0 && uDistance <= _scrollCutoff) {
+					uSpeed += _scrollSpeedReduce;
+					if (uSpeed < 2)
+						uSpeed = 1;
+				}
+
+				dDistance -= dDelta;
+				if (dDistance != 0 && dDistance <= _scrollCutoff) {
+					dSpeed += _scrollSpeedReduce;
+					if (dSpeed < 2)
+						dSpeed = 1;
+				}
+
+				_system->delayMillis(1000 / 15); // 15fps
+			}
+		}
+	}
+
+	doDraw();
+
 	return true;
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index acaddcc8471..79dcc32d66e 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -533,7 +533,7 @@ protected:
 	bool FUN_00402fb4();
 
 	bool updateMouseCursor(Common::Point mouseMove);
-	bool FUN_004038b8();
+	bool scrollAndDraw();
 	bool FUN_00402bc4();
 	bool FUN_00402f34(bool p1, bool p2, Object *obj);
 


Commit: 5eb4ad3699c0af7e56637cc26c93d4a0247c6a90
    https://github.com/scummvm/scummvm/commit/5eb4ad3699c0af7e56637cc26c93d4a0247c6a90
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:42+01:00

Commit Message:
GAMOS: Rework VM registers and address as working throught structure and methods. Store memtype in 2 high bits.

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index b2f8df0483d..303d22b8595 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2244,46 +2244,46 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	switch (funcID) {
 	case 0:
 		DAT_004177ff = true;
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 	case 1:
-		vm->EAX.val = PTR_00417218->y == -1 ? 1 : 0;
+		vm->EAX.setVal( PTR_00417218->y == -1 ? 1 : 0 );
 		break;
 
 	case 2:
 		arg1 = vm->pop32();
 		if (PTR_00417218->x == -1)
-			vm->EAX.val = 0;
+			vm->EAX.setVal(0);
 		else
-			vm->EAX.val = _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0;
+			vm->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
 		break;
 	case 3:
 		//warning("func 3 %x check 0x10", PTR_00417218->fld_4 & 0x90);
-		vm->EAX.val = (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0;
+		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
 		break;
 	case 4:
 		//warning("func 4 %x check 0x20", PTR_00417218->fld_4 & 0xa0);
-		vm->EAX.val = (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0;
+		vm->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
 		break;
 	case 5:
 		arg1 = vm->pop32();
 		//warning("func 5 %x check %x", PTR_00417218->fld_4 & 0xb0, arg1);
-		vm->EAX.val = (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0;
+		vm->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
 		break;
 	case 6:
 		arg1 = vm->pop32();
 		//warning("func 6 %x check %x", PTR_00417218->fld_4 & 0x4f, arg1);
-		vm->EAX.val = (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0;
+		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
 		break;
 	case 9:
 		arg1 = vm->pop32();
-		vm->EAX.val = savedDoActions(_subtitleActions[arg1]);
+		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
 	case 13: {
-		VM::Reg regRef = vm->popReg(); //implement
-		Common::String str = vm->getString(regRef.ref, regRef.val);
+		VM::ValAddr regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef);
 		//warning("CallDispatcher 13 keycode %s", str.c_str());
-		vm->EAX.val = 0;
+		vm->EAX.setVal(0);
 		break;
 	}
 
@@ -2291,23 +2291,23 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		arg1 = vm->pop32();
 		loadModule(arg1);
 		setNeedReload();
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 16:
 		arg1 = vm->pop32();
-		vm->EAX.val = scriptFunc16(arg1);
+		vm->EAX.setVal( scriptFunc16(arg1) );
 		break;
 
 	case 17:
 		arg1 = vm->pop32();
 		playSound(arg1);
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 19:
 		arg1 = vm->pop32();
-		vm->EAX.val = scriptFunc19(arg1);
+		vm->EAX.setVal( scriptFunc19(arg1) );
 		break;
 
 	case 20: {
@@ -2315,17 +2315,17 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		for (const SubtitlePoint &d : _subtitlePoints[arg1]) {
 			FUN_0040738c(d.sprId, d.x, d.y, true);
 		}
-		vm->EAX.val = savedDoActions(_subtitleActions[arg1]);
+		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 	}
 	break;
 
 	case 24: {
-		VM::Reg regRef = vm->popReg();
+		VM::ValAddr regRef = vm->popReg();
 		arg2 = vm->pop32();
 		const SubtitlePoint &d = _subtitlePoints[arg2][0];
-		addSubtitles(vm, regRef.ref, regRef.val, d.sprId, d.x, d.y);
+		addSubtitles(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y);
 
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 	}
 	break;
 
@@ -2343,18 +2343,18 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 				addDirtRectOnObject(&obj);
 			}
 		}
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 	}
 	break;
 
 	case 26:
 		removeSubtitles(PTR_00417218);
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 27:
 		FUN_004025d0();
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 30: {
@@ -2370,23 +2370,23 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	case 31:
 		arg1 = vm->pop32();
 		setCursor(arg1, true);
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 32:
 		setCursor(0, false);
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 33:
 		PTR_00417218->fld_5 = _statesHeight - PTR_00417218->blk;
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 		break;
 
 	case 34: {
-		VM::Reg regRef = vm->popReg();
-		vm->setMem8(regRef.ref, regRef.val, PTR_00417218->fld_5);
-		vm->EAX.val = 1;
+		VM::ValAddr regRef = vm->popReg();
+		vm->setMem8(regRef, PTR_00417218->fld_5);
+		vm->EAX.setVal(1);
 	}
 	break;
 
@@ -2494,17 +2494,17 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	case 38:
 		arg1 = vm->pop32();
 		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412ca0)
-			vm->EAX.val = 0;
+			vm->EAX.setVal(0);
 		else
-			vm->EAX.val = 1;
+			vm->EAX.setVal(1);
 		break;
 
 	case 39:
 		arg1 = vm->pop32();
 		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412c9c)
-			vm->EAX.val = 0;
+			vm->EAX.setVal(0);
 		else
-			vm->EAX.val = 1;
+			vm->EAX.setVal(1);
 		break;
 
 	case 42: {
@@ -2531,7 +2531,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 				FUN_00402a68(tmp);
 			}
 		}
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 	}
 	break;
 
@@ -2544,7 +2544,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			tmp.flags = 0;
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 	}
 	break;
 
@@ -2557,13 +2557,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			tmp.flags = 1;
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 	}
 	break;
 
 	case 45:
 		arg1 = vm->pop32();
-		vm->EAX.val = (PTR_00417218->flags & arg1) ? 1 : 0;
+		vm->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
 		break;
 
 	case 47: {
@@ -2571,23 +2571,23 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 
 		switch (arg1) {
 		case 0:
-			vm->EAX.val = _d2_fld16 != 0 ? 1 : 0;
+			vm->EAX.setVal(_d2_fld16 != 0 ? 1 : 0);
 			break;
 
 		case 1:
-			vm->EAX.val = _d2_fld14 != 0 ? 1 : 0;
+			vm->EAX.setVal(_d2_fld14 != 0 ? 1 : 0);
 			break;
 
 		case 2:
-			vm->EAX.val = 1; //BYTE_004177fb != 0 ? 1 : 0;
+			vm->EAX.setVal(1); //BYTE_004177fb != 0 ? 1 : 0;
 			break;
 
 		case 3:
-			vm->EAX.val = _d2_fld17 != 0 ? 1 : 0;
+			vm->EAX.setVal(_d2_fld17 != 0 ? 1 : 0);
 			break;
 
 		case 4:
-			vm->EAX.val = _d2_fld18 != 0 ? 1 : 0;
+			vm->EAX.setVal(_d2_fld18 != 0 ? 1 : 0);
 			break;
 
 		default:
@@ -2606,28 +2606,28 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 
 	case 54:
 		arg1 = vm->pop32();
-		vm->EAX.val = rndRange16(arg1);
+		vm->EAX.setVal(rndRange16(arg1));
 		break;
 
 	case 55: {
-		VM::Reg regRef = vm->popReg(); //implement
-		Common::String str = vm->getString(regRef.ref, regRef.val);
+		VM::ValAddr regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef);
 		warning("PlayMovie 55: %s", str.c_str());
-		vm->EAX.val = 1;
+		vm->EAX.setVal(1);
 	}
 	break;
 
 	case 57: {
-		VM::Reg regRef = vm->popReg(); //implement
-		Common::String str = vm->getString(regRef.ref, regRef.val);
+		VM::ValAddr regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef);
 		warning("CallDispatcher 57 keycode %s", str.c_str());
-		vm->EAX.val = 0;
+		vm->EAX.setVal(0);
 	}
 	break;
 
 	default:
 		warning("Call Dispatcher %d", funcID);
-		vm->EAX.val = 0;
+		vm->EAX.setVal(0);
 		break;
 	}
 }
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index fb8a51721f5..ac8eff00a95 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -147,77 +147,77 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 			break;
 
 		case OP_CMP_EQ:
-			if (EDX.val == EAX.val)
-				EAX.val = 1;
+			if (EDX.getVal() == EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_NE:
-			if (EDX.val != EAX.val)
-				EAX.val = 1;
+			if (EDX.getVal() != EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_LE:
-			if ((int32)EDX.val < (int32)EAX.val)
-				EAX.val = 1;
+			if ((int32)EDX.getVal() < (int32)EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_LEQ:
-			if ((int32)EDX.val <= (int32)EAX.val)
-				EAX.val = 1;
+			if ((int32)EDX.getVal() <= (int32)EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_GR:
-			if ((int32)EDX.val > (int32)EAX.val)
-				EAX.val = 1;
+			if ((int32)EDX.getVal() > (int32)EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_GREQ:
-			if ((int32)EDX.val >= (int32)EAX.val)
-				EAX.val = 1;
+			if ((int32)EDX.getVal() >= (int32)EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_NAE:
-			if (EDX.val < EAX.val)
-				EAX.val = 1;
+			if (EDX.getVal() < EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_NA:
-			if (EDX.val <= EAX.val)
-				EAX.val = 1;
+			if (EDX.getVal() <= EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_A:
-			if (EDX.val > EAX.val)
-				EAX.val = 1;
+			if (EDX.getVal() > EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_CMP_AE:
-			if (EDX.val >= EAX.val)
-				EAX.val = 1;
+			if (EDX.getVal() >= EAX.getVal())
+				EAX.setVal(1);
 			else
-				EAX.val = 0;
+				EAX.setVal(0);
 			break;
 
 		case OP_BRANCH:
-			if (EAX.val != 0)
+			if (EAX.getVal() != 0)
 				ESI += 4;
 			else
 				ESI += (int32)_readAccess.getU32(ESI);
@@ -233,26 +233,22 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 			break;
 
 		case OP_MOV_EDI_ECX_AL:
-			ECX.val = _readAccess.getU32(ESI);
-			setMem8(REF_EDI, ECX.val, EAX.val & 0xff);
+			setMem8(REF_EDI, _readAccess.getU32(ESI), EAX.getVal() & 0xff);
 			ESI += 4;
 			break;
 
 		case OP_MOV_EBX_ECX_AL:
-			ECX.val = _readAccess.getU32(ESI);
-			setMem8(REF_EBX, ECX.val, EAX.val & 0xff);
+			setMem8(REF_EBX, _readAccess.getU32(ESI), EAX.getVal() & 0xff);
 			ESI += 4;
 			break;
 
 		case OP_MOV_EDI_ECX_EAX:
-			ECX.val = _readAccess.getU32(ESI);
-			setMem32(REF_EDI, ECX.val, EAX.val);
+			setMem32(REF_EDI, _readAccess.getU32(ESI), EAX.getVal());
 			ESI += 4;
 			break;
 
 		case OP_MOV_EBX_ECX_EAX:
-			ECX.val = _readAccess.getU32(ESI);
-			setMem32(REF_EBX, ECX.val, EAX.val);
+			setMem32(REF_EBX, _readAccess.getU32(ESI), EAX.getVal());
 			ESI += 4;
 			break;
 
@@ -264,7 +260,7 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 		case OP_RETX:
 			ECX = popReg();
 			SP += _readAccess.getU32(ESI);
-			ESI = ECX.val;
+			ESI = ECX.getVal();
 			ESI += 4;
 			break;
 
@@ -273,51 +269,48 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 			break;
 
 		case OP_ADD_EAX_EDX:
-			EAX.val += EDX.val;
-			if (EAX.ref == REF_UNK && EDX.ref != REF_UNK)
-				EAX.ref = EDX.ref;
+			EAX.setVal(EAX.getVal() + EDX.getVal());
 			break;
 
 		case OP_MUL:
-			EAX.val *= EDX.val;
+			EAX.setVal(EAX.getVal() * EDX.getVal());
 			break;
 
 		case OP_OR:
-			EAX.val |= EDX.val;
+            EAX.setVal(EAX.getVal() | EDX.getVal());
 			break;
 
 		case OP_XOR:
-			EAX.val ^= EDX.val;
+            EAX.setVal(EAX.getVal() ^ EDX.getVal());
 			break;
 
 		case OP_AND:
-			EAX.val &= EDX.val;
+            EAX.setVal(EAX.getVal() & EDX.getVal());
 			break;
 
 		case OP_NEG:
-			EAX.val = (uint32)(-((int32)EAX.val));
+            EAX.setVal((uint32)(-(int32)EAX.getVal()));
 			break;
 
 		case OP_SAR:
-			EAX.val = (uint32)(((int32)EDX.val) >> (EAX.val & 0xff)); /* must be arythmetic shift! */
+            EAX.setVal((int32)EDX.getVal() >> (EAX.getVal() & 0xff)); /* must be arythmetic shift! */
 			break;
 
 		case OP_SHL:
-			EAX.val = EDX.val << (EAX.val & 0xff);
+            EAX.setVal(EDX.getVal() << (EAX.getVal() & 0xff));
 			break;
 
 		case OP_LOAD:
-			EAX.val = _readAccess.getU32(ESI);
-			EAX.ref = REF_UNK;
+            EAX.setVal( _readAccess.getU32(ESI) );
 			ESI += 4;
 			break;
 
 		case OP_INC:
-			EAX.val += 1;
+			EAX.setVal( EAX.getVal() + 1 );
 			break;
 
 		case OP_DEC:
-			EAX.val -= 1;
+            EAX.setVal( EAX.getVal() - 1 );
 			break;
 
 		case OP_XCHG:
@@ -336,41 +329,38 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 
 		case OP_LOAD_OFFSET_EDI:
 		case OP_LOAD_OFFSET_EDI2:
-			EAX.val = _readAccess.getU32(ESI);
-			EAX.ref = REF_EDI;
+            EAX.setAddress(REF_EDI, _readAccess.getU32(ESI));
 			ESI += 4;
 			break;
 
 		case OP_LOAD_OFFSET_EBX:
-			EAX.val = _readAccess.getU32(ESI);
-			EAX.ref = REF_EBX;
+            EAX.setAddress(REF_EBX, _readAccess.getU32(ESI));
 			ESI += 4;
 			break;
 
 		case OP_LOAD_OFFSET_ESP:
-			EAX.val = _readAccess.getU32(ESI) + SP;
-			EAX.ref = REF_STACK;
+            EAX.setAddress(REF_STACK, _readAccess.getU32(ESI) + SP);
 			ESI += 4;
 			break;
 
 		case OP_MOV_PTR_EDX_AL:
-			setMem8(EDX.ref, EDX.val, EAX.val & 0xff);
+			setMem8(EDX, EAX.getVal() & 0xff);
 			break;
 
 		case OP_MOV_PTR_EDX_EAX:
-			setMem32(EDX.ref, EDX.val, EAX.val);
+			setMem32(EDX, EAX.getVal());
 			break;
 
 		case OP_SHL_2:
-			EAX.val <<= 2;
+			EAX.setVal( EAX.getVal() << 2 );
 			break;
 
 		case OP_ADD_4:
-			EAX.val += 4;
+            EAX.setVal( EAX.getVal() + 4 );
 			break;
 
 		case OP_SUB_4:
-			EAX.val -= 4;
+            EAX.setVal( EAX.getVal() - 4 );
 			break;
 
 		case OP_XCHG_ESP:
@@ -380,47 +370,41 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 			break;
 
 		case OP_NEG_ADD:
-			EAX.val = (uint32)(-((int32)EAX.val)) + EDX.val;
+            EAX.setVal( (-(int32)EAX.getVal()) + EDX.getVal() );
 			break;
 
 		case OP_DIV:
 			ECX = EAX;
-			EAX.val = (int32)EDX.val / (int32)ECX.val;
-			EDX.val = (int32)EDX.val % (int32)ECX.val;
+            EAX.setVal( (int32)EDX.getVal() / (int32)ECX.getVal() );
+            EDX.setVal( (int32)EDX.getVal() % (int32)ECX.getVal() );
 			break;
 
 		case OP_MOV_EAX_BPTR_EDI:
-			ECX.val = _readAccess.getU32(ESI);
-			EAX.val = (int8)getMem8(REF_EDI, ECX.val);
+			EAX.setVal( (int32)((int8)getMem8(REF_EDI, _readAccess.getU32(ESI))) );
 			ESI += 4;
 			break;
 
 		case OP_MOV_EAX_BPTR_EBX:
-			ECX.val = _readAccess.getU32(ESI);
-			EAX.val = (int8)getMem8(REF_EBX, ECX.val);
+            EAX.setVal( (int32)((int8)getMem8(REF_EBX, _readAccess.getU32(ESI))) );
 			ESI += 4;
 			break;
 
 		case OP_MOV_EAX_DPTR_EDI:
-			ECX.val = _readAccess.getU32(ESI);
-			EAX.val = getMem32(REF_EDI, ECX.val);
+            EAX.setVal( getMem32(REF_EDI, _readAccess.getU32(ESI)) );
 			ESI += 4;
 			break;
 
 		case OP_MOV_EAX_DPTR_EBX:
-			ECX.val = _readAccess.getU32(ESI);
-			EAX.val = getMem32(REF_EBX, ECX.val);
+            EAX.setVal( getMem32(REF_EBX, _readAccess.getU32(ESI)) );
 			ESI += 4;
 			break;
 
 		case OP_MOV_EAX_BPTR_EAX:
-			EAX.val = (int8)getMem8(EAX.ref, EAX.val);
-			EAX.ref = REF_UNK;
+			EAX.setVal( (int32)( (int8)getMem8(EAX) ) );
 			break;
 
 		case OP_MOV_EAX_DPTR_EAX:
-			EAX.val = getMem32(EAX.ref, EAX.val);
-			EAX.ref = REF_UNK;
+            EAX.setVal( getMem32(EAX) );
 			break;
 
 		case OP_PUSH_ESI_ADD_EDI:
@@ -429,20 +413,20 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 			break;
 
 		case OP_CALL_FUNC:
-			EAX.val = _readAccess.getU32(ESI);
+			EAX.setVal( _readAccess.getU32(ESI) );
 			ESI += 4;
 			if (_callFuncs)
-				_callFuncs(_callingObject, this, EAX.val);
+				_callFuncs(_callingObject, this, EAX.getVal());
 			break;
 
 		case OP_PUSH_ESI_SET_EDX_EDI:
 			push32(ESI);
-			ESI = EDX.val;
+			ESI = EDX.getVal();
 			break;
 		}
 	}
 
-	return EAX.val;
+	return EAX.getVal();
 }
 
 
@@ -496,16 +480,14 @@ uint32 VM::pop32() {
 	return val;
 }
 
-void VM::pushReg(Reg reg) {
+void VM::pushReg(ValAddr reg) {
 	SP -= 4;
-	setU32(_stack + SP, reg.val);
-	_stackT[SP] = reg.ref;
+	setU32(_stack + SP, reg.getVal());
 }
 
-VM::Reg VM::popReg() {
-	Reg tmp;
-	tmp.val = getU32(_stack + SP);
-	tmp.ref = _stackT[SP];
+VM::ValAddr VM::popReg() {
+	ValAddr tmp;
+	tmp.setVal( getU32(_stack + SP) );
 	SP += 4;
 	return tmp;
 }
@@ -527,6 +509,10 @@ uint32 VM::getMem32(int memtype, uint32 offset) {
 	}
 }
 
+uint32 VM::getMem32(const ValAddr &addr) {
+    return getMem32(addr.getMemType(), addr.getOffset());
+}
+
 uint8 VM::getMem8(int memtype, uint32 offset) {
 	switch (memtype) {
 	default:
@@ -544,6 +530,10 @@ uint8 VM::getMem8(int memtype, uint32 offset) {
 	}
 }
 
+uint8 VM::getMem8(const ValAddr &addr) {
+    return getMem8(addr.getMemType(), addr.getOffset());
+}
+
 void VM::setMem32(int memtype, uint32 offset, uint32 val) {
 	switch (memtype) {
 	default:
@@ -562,6 +552,10 @@ void VM::setMem32(int memtype, uint32 offset, uint32 val) {
 	}
 }
 
+void VM::setMem32(const ValAddr &addr, uint32 val) {
+    setMem32(addr.getMemType(), addr.getOffset(), val);
+}
+
 void VM::setMem8(int memtype, uint32 offset, uint8 val) {
 	switch (memtype) {
 	default:
@@ -580,6 +574,10 @@ void VM::setMem8(int memtype, uint32 offset, uint8 val) {
 	}
 }
 
+void VM::setMem8(const ValAddr &addr, uint8 val) {
+    setMem8(addr.getMemType(), addr.getOffset(), val);
+}
+
 void VM::clearMemory() {
 	_memMap.clear();
 	_memAccess.reset();
@@ -732,6 +730,10 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
 	}
 }
 
+Common::String VM::getString(const ValAddr &addr, uint32 maxLen) {
+    return getString(addr.getMemType(), addr.getOffset(), maxLen);
+}
+
 
 Common::String VM::decodeOp(uint32 address, int *size) {
 	Common::String tmp;
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index cb419bbcec3..1d052e49da7 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -28,190 +28,207 @@ namespace Gamos {
 
 class VM {
 public:
-	static constexpr const uint THREADS_COUNT = 2;
-	static constexpr const uint STACK_SIZE = 0x100;
-	static constexpr const uint STACK_POS = 0x80;
-
-	enum OP {
-		OP_EXIT = 0,
-		OP_CMP_EQ = 1,
-		OP_CMP_NE = 2,
-		OP_CMP_LE = 3,
-		OP_CMP_LEQ = 4,
-		OP_CMP_GR = 5,
-		OP_CMP_GREQ = 6,
-		OP_CMP_NAE = 7,
-		OP_CMP_NA = 8,
-		OP_CMP_A = 9,
-		OP_CMP_AE = 10,
-		OP_BRANCH = 11,
-		OP_JMP = 12,
-		OP_SP_ADD = 13,
-		OP_MOV_EDI_ECX_AL = 14,
-		OP_MOV_EBX_ECX_AL = 15,
-		OP_MOV_EDI_ECX_EAX = 16,
-		OP_MOV_EBX_ECX_EAX = 17,
-		OP_RET = 18,
-		OP_RETX = 19,
-		OP_MOV_EDX_EAX = 20,
-		OP_ADD_EAX_EDX = 21,
-		OP_MUL = 22,
-		OP_OR = 23,
-		OP_XOR = 24,
-		OP_AND = 25,
-		OP_NEG = 26,
-		OP_SAR = 27,
-		OP_SHL = 28,
-		OP_LOAD = 29,
-		OP_INC = 30,
-		OP_DEC = 31,
-		OP_XCHG = 32,
-		OP_PUSH_EAX = 33,
-		OP_POP_EDX = 34,
-		OP_LOAD_OFFSET_EDI = 35,
-		OP_LOAD_OFFSET_EDI2 = 36,
-		OP_LOAD_OFFSET_EBX = 37,
-		OP_LOAD_OFFSET_ESP = 38,
-		OP_MOV_PTR_EDX_AL = 39,
-		OP_MOV_PTR_EDX_EAX = 40,
-		OP_SHL_2 = 41,
-		OP_ADD_4 = 42,
-		OP_SUB_4 = 43,
-		OP_XCHG_ESP = 44,
-		OP_NEG_ADD = 45,
-		OP_DIV = 46,
-		OP_MOV_EAX_BPTR_EDI = 47,
-		OP_MOV_EAX_BPTR_EBX = 48,
-		OP_MOV_EAX_DPTR_EDI = 49,
-		OP_MOV_EAX_DPTR_EBX = 50,
-		OP_MOV_EAX_BPTR_EAX = 51,
-		OP_MOV_EAX_DPTR_EAX = 52,
-		OP_PUSH_ESI_ADD_EDI = 53,
-		OP_CALL_FUNC = 54,
-		OP_PUSH_ESI_SET_EDX_EDI = 55,
-
-		OP_MAX
-	};
-
-	enum MEMREF {
-		REF_UNK = 0,
-		REF_STACK = 1,
-		REF_EBX = 2,
-		REF_EDI = 3
-	};
-
-	struct Reg {
-		uint32 val = 0;
-		byte ref = REF_UNK;
-	};
-
-	typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
-
-	struct MemoryBlock {
-		uint32 address = 0;
-		byte data[256];
-
-		MemoryBlock() {
-			address = 0;
-			memset(data, 0, sizeof(data));
-		}
-	};
-
-	struct OpLog {
-		uint32 addr;
-		OP op;
-		uint32 sp;
-	};
-
-	struct MemAccess {
-		MemoryBlock *_currentBlock = nullptr;
-
-		uint8 getU8(uint32 address);
-		uint32 getU32(uint32 address);
-
-		void setU8(uint32 address, uint8 val);
-		void setU32(uint32 address, uint32 val);
-
-		void reset() {
-			_currentBlock = nullptr;
-		}
-	};
+    static constexpr const uint THREADS_COUNT = 2;
+    static constexpr const uint STACK_SIZE = 0x100;
+    static constexpr const uint STACK_POS = 0x80;
+    static constexpr const uint MEMTYPE_SHIFT = 30;
+    static constexpr const uint ADDRESS_MASK = (1 << MEMTYPE_SHIFT) - 1;
+
+    enum OP {
+        OP_EXIT = 0,
+        OP_CMP_EQ = 1,
+        OP_CMP_NE = 2,
+        OP_CMP_LE = 3,
+        OP_CMP_LEQ = 4,
+        OP_CMP_GR = 5,
+        OP_CMP_GREQ = 6,
+        OP_CMP_NAE = 7,
+        OP_CMP_NA = 8,
+        OP_CMP_A = 9,
+        OP_CMP_AE = 10,
+        OP_BRANCH = 11,
+        OP_JMP = 12,
+        OP_SP_ADD = 13,
+        OP_MOV_EDI_ECX_AL = 14,
+        OP_MOV_EBX_ECX_AL = 15,
+        OP_MOV_EDI_ECX_EAX = 16,
+        OP_MOV_EBX_ECX_EAX = 17,
+        OP_RET = 18,
+        OP_RETX = 19,
+        OP_MOV_EDX_EAX = 20,
+        OP_ADD_EAX_EDX = 21,
+        OP_MUL = 22,
+        OP_OR = 23,
+        OP_XOR = 24,
+        OP_AND = 25,
+        OP_NEG = 26,
+        OP_SAR = 27,
+        OP_SHL = 28,
+        OP_LOAD = 29,
+        OP_INC = 30,
+        OP_DEC = 31,
+        OP_XCHG = 32,
+        OP_PUSH_EAX = 33,
+        OP_POP_EDX = 34,
+        OP_LOAD_OFFSET_EDI = 35,
+        OP_LOAD_OFFSET_EDI2 = 36,
+        OP_LOAD_OFFSET_EBX = 37,
+        OP_LOAD_OFFSET_ESP = 38,
+        OP_MOV_PTR_EDX_AL = 39,
+        OP_MOV_PTR_EDX_EAX = 40,
+        OP_SHL_2 = 41,
+        OP_ADD_4 = 42,
+        OP_SUB_4 = 43,
+        OP_XCHG_ESP = 44,
+        OP_NEG_ADD = 45,
+        OP_DIV = 46,
+        OP_MOV_EAX_BPTR_EDI = 47,
+        OP_MOV_EAX_BPTR_EBX = 48,
+        OP_MOV_EAX_DPTR_EDI = 49,
+        OP_MOV_EAX_DPTR_EBX = 50,
+        OP_MOV_EAX_BPTR_EAX = 51,
+        OP_MOV_EAX_DPTR_EAX = 52,
+        OP_PUSH_ESI_ADD_EDI = 53,
+        OP_CALL_FUNC = 54,
+        OP_PUSH_ESI_SET_EDX_EDI = 55,
+
+        OP_MAX
+    };
+
+    enum MEMREF {
+        REF_UNK = 0,
+        REF_STACK = 1,
+        REF_EBX = 2,
+        REF_EDI = 3
+    };
+
+    struct ValAddr {
+        uint32 value = 0;
+
+        inline uint32 getVal() const { return value; };
+        inline void setVal(uint32 v) { value = v; };
+
+        inline uint32 getOffset() const { return value & ADDRESS_MASK; };
+        inline uint getMemType() const { return (value >> MEMTYPE_SHIFT ) & 3; };
+
+        inline void setMemType(uint tp) { value = (value & ADDRESS_MASK) | ((tp & 3) << MEMTYPE_SHIFT); };
+        inline void setOffset(uint32 offset) { value = (value & (~ADDRESS_MASK)) | (offset & ADDRESS_MASK); };
+
+        inline void setAddress(uint tp, uint32 offset) { value = (offset & ADDRESS_MASK) | ((tp & 3) << MEMTYPE_SHIFT); };
+    };
+
+    typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
+
+    struct MemoryBlock {
+        uint32 address = 0;
+        byte data[256];
+
+        MemoryBlock() {
+            address = 0;
+            memset(data, 0, sizeof(data));
+        }
+    };
+
+    struct OpLog {
+        uint32 addr;
+        OP op;
+        uint32 sp;
+    };
+
+    struct MemAccess {
+        MemoryBlock *_currentBlock = nullptr;
+
+        uint8 getU8(uint32 address);
+        uint32 getU32(uint32 address);
+
+        void setU8(uint32 address, uint8 val);
+        void setU32(uint32 address, uint32 val);
+
+        void reset() {
+            _currentBlock = nullptr;
+        }
+    };
 
 public:
-	inline static MemAccess &memory() {
-		return _memAccess;
-	};
+    inline static MemAccess &memory() {
+        return _memAccess;
+    };
 
-	static void clearMemory();
-	static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
+    static void clearMemory();
+    static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
 
-	static void zeroMemory(uint32 address, uint32 count);
+    static void zeroMemory(uint32 address, uint32 count);
 
-	static MemoryBlock *findMemoryBlock(uint32 address);
+    static MemoryBlock *findMemoryBlock(uint32 address);
 
-	static MemoryBlock *createBlock(uint32 address);
+    static MemoryBlock *createBlock(uint32 address);
 
-	static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
-	static void readMemBlocks(byte *dst, uint32 address, uint32 count);
+    static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+    static void readMemBlocks(byte *dst, uint32 address, uint32 count);
 
-	static Common::String readMemString(uint32 address, uint32 maxLen = 256);
+    static Common::String readMemString(uint32 address, uint32 maxLen = 256);
 
-	Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
+    Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
+    Common::String getString(const ValAddr &addr, uint32 maxLen = 256);
 
-	uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
+    uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
 
-	static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
+    static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
 
-	static int32 getS32(const void *);
-	static uint32 getU32(const void *);
-	static void setU32(void *, uint32 val);
+    static int32 getS32(const void *);
+    static uint32 getU32(const void *);
+    static void setU32(void *, uint32 val);
 
-	void push32(uint32 val);
-	uint32 pop32();
+    void push32(uint32 val);
+    uint32 pop32();
 
-	void pushReg(Reg reg);
-	Reg popReg();
+    void pushReg(ValAddr reg);
+    ValAddr popReg();
 
-	uint32 getMem32(int memtype, uint32 offset);
-	uint8 getMem8(int memtype, uint32 offset);
+    uint32 getMem32(int memtype, uint32 offset);
+    uint32 getMem32(const ValAddr& addr);
+    uint8 getMem8(int memtype, uint32 offset);
+    uint8 getMem8(const ValAddr& addr);
 
-	void setMem32(int memtype, uint32 offset, uint32 val);
-	void setMem8(int memtype, uint32 offset, uint8 val);
+    void setMem32(int memtype, uint32 offset, uint32 val);
+    void setMem32(const ValAddr& addr, uint32 val);
+    void setMem8(int memtype, uint32 offset, uint8 val);
+    void setMem8(const ValAddr& addr, uint8 val);
 
-	static Common::String decodeOp(uint32 address, int *size = nullptr);
-	static Common::String disassembly(uint32 address);
+    static Common::String decodeOp(uint32 address, int *size = nullptr);
+    static Common::String disassembly(uint32 address);
 
-	static Common::String opLog(const Common::Array<OpLog> &log);
+    static Common::String opLog(const Common::Array<OpLog> &log);
 
-	static void printDisassembly(uint32 address);
+    static void printDisassembly(uint32 address);
 
 private:
 
 public:
-	bool _inUse = false;
+    bool _inUse = false;
 
-	uint32 ESI = 0;
-	byte *EBX = nullptr;
-	Reg EAX;
-	Reg EDX;
-	Reg ECX;
-	uint32 SP = 0;
-	byte _stack[STACK_SIZE];
-	byte _stackT[STACK_SIZE];
+    uint32 ESI = 0;
+    byte *EBX = nullptr;
+    ValAddr EAX;
+    ValAddr EDX;
+    ValAddr ECX;
+    uint32 SP = 0;
+    byte _stack[STACK_SIZE];
+    byte _stackT[STACK_SIZE];
 
 private:
-	MemAccess _readAccess;
-	MemAccess _writeAccess;
+    MemAccess _readAccess;
+    MemAccess _writeAccess;
 
 public:
-	static CallDispatcher _callFuncs;
-	static void *_callingObject;
+    static CallDispatcher _callFuncs;
+    static void *_callingObject;
 
-	static Common::HashMap<uint32, MemoryBlock> _memMap;
-	static bool _interrupt;
+    static Common::HashMap<uint32, MemoryBlock> _memMap;
+    static bool _interrupt;
 
-	static VM _threads[THREADS_COUNT];
-	static MemAccess _memAccess;
+    static VM _threads[THREADS_COUNT];
+    static MemAccess _memAccess;
 };
 
 


Commit: 893a66e6d9fe010e8b0781d2829617ebd40494ec
    https://github.com/scummvm/scummvm/commit/893a66e6d9fe010e8b0781d2829617ebd40494ec
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:42+01:00

Commit Message:
GAMOS: Add wildsnakes detection

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 4243f2bfbab..9efb70a5dec 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -26,6 +26,7 @@ const PlainGameDescriptor gamosGames[] = {
 	{ "solgamer", "21 Solitaire" },
 	{ "pilots", "Pilots 1" },
 	{ "pilots2", "Pilots 2" },
+	{ "wild", "WildSnakes"},
 	{ 0, 0 }
 };
 
@@ -69,6 +70,19 @@ const GamosGameDescription gameDescriptions[] = {
 		"pilots2.exe",
 		0x80000018
 	},
+	{
+		{
+			"wild",
+			0,
+			AD_ENTRY1s("wildus.exe", "6049dd1645071da1b60cdd395e6999ba", 11475754),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"wildus.exe",
+		0x80000018
+	},
 	{
 		AD_TABLE_END_MARKER,
 		"",


Commit: 239f4c1ddfde47390a1efa9d1d249ad0c0ab5b2c
    https://github.com/scummvm/scummvm/commit/239f4c1ddfde47390a1efa9d1d249ad0c0ab5b2c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:42+01:00

Commit Message:
GAMOS: Fix intro in wildsnakes

Changed paths:
    engines/gamos/movie.cpp


diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index b14204758bc..55b61d7352b 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -508,7 +508,7 @@ byte *MoviePlayer::blit2(Common::Rect rect, byte *in, Graphics::Surface *surface
 				x += count;
 			}
 		} else if (b == 0) {
-			x += b + 1;
+			x = rect.right;
 		} else if (b != 1) {
 			int count = b + 1;
 			byte val = *in;


Commit: db182500c782eb2f7e8dbe13d8525ab6550af81f
    https://github.com/scummvm/scummvm/commit/db182500c782eb2f7e8dbe13d8525ab6550af81f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:43+01:00

Commit Message:
GAMOS: Smooth mouse in intro player and decrease cpu usage by idle for 1ms

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/movie.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 303d22b8595..d56b1fd8832 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -116,7 +116,7 @@ Common::Error GamosEngine::run() {
 		}
 
 		uint32 curTime = _system->getMillis();
-		if (curTime > _lastTimeStamp + _delayTime) {
+		if (curTime >= _lastTimeStamp + _delayTime) {
 			_lastTimeStamp = curTime;
 
 			if (_messageProc._gd2flags & 2) {
@@ -136,7 +136,8 @@ Common::Error GamosEngine::run() {
 			_messageProc._rawKeyCode = ACT_NONE;
 		} else {
 			if (prevMousePos != _messageProc._mouseReportedPos)
-				_screen->update();
+				_system->updateScreen();
+			_system->delayMillis(1);
 		}
 
 		//if (_delayTime)
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 55b61d7352b..5e382536f6a 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -336,6 +336,7 @@ int MoviePlayer::processImageChunk() {
 					break;
 
 				g_system->delayMillis(1);
+                g_system->updateScreen();
 			}
 		}
 


Commit: 4f0b4148d041241f3d9a3327d667495a45d344a0
    https://github.com/scummvm/scummvm/commit/4f0b4148d041241f3d9a3327d667495a45d344a0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:43+01:00

Commit Message:
GAMOS: Disable movie player debug warnings

Changed paths:
    engines/gamos/movie.cpp


diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 5e382536f6a..b2d18267f72 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -135,7 +135,7 @@ bool MoviePlayer::error() {
 }
 
 int MoviePlayer::processControlChunk() {
-	warning("%x movieProcessControl %d", (uint32)_file->pos(), _hdrBytes[1]);
+	//warning("%x movieProcessControl %d", (uint32)_file->pos(), _hdrBytes[1]);
 
 	switch (_hdrBytes[1]) {
 	case 0:
@@ -208,7 +208,7 @@ int MoviePlayer::processControlChunk() {
 }
 
 int MoviePlayer::processImageChunk() {
-	warning("%x movieProcessImageChunk %d", (uint32)_file->pos(), _hdrValue1);
+	//warning("%x movieProcessImageChunk %d", (uint32)_file->pos(), _hdrValue1);
 	if (!readCompressed(_bufferSize, &_buffer))
 		return 0;
 
@@ -274,7 +274,7 @@ int MoviePlayer::processImageChunk() {
 				wh = _frameSize;
 			}
 
-			warning("movie blit%d %d %d %d %d", val & 3, xy.x, xy.y, wh.x, wh.y);
+			//warning("movie blit%d %d %d %d %d", val & 3, xy.x, xy.y, wh.x, wh.y);
 			static byte *(*blitters[4])(Common::Rect, byte *, Graphics::Surface *) = {
 				&blit0,
 				&blit1,
@@ -351,7 +351,7 @@ int MoviePlayer::processImageChunk() {
 }
 
 int MoviePlayer::processPaletteChunk() {
-	warning("%x movieProcessPaletteChunk", (uint32)_file->pos());
+	//warning("%x movieProcessPaletteChunk", (uint32)_file->pos());
 	if (!readCompressed(_paletteBufferSize, &_paletteBuffer))
 		return 0;
 
@@ -362,14 +362,14 @@ int MoviePlayer::processPaletteChunk() {
 }
 
 int MoviePlayer::processSoundChunk() {
-	warning("%x movieProcessSoundChunk", (uint32)_file->pos());
+	//warning("%x movieProcessSoundChunk", (uint32)_file->pos());
 	if (!readCompressed(_soundBufferSize, &_soundBuffer))
 		return 0;
 	return 1;
 }
 
 int MoviePlayer::proccessMidiChunk() {
-	warning("%x movieProcessMidiChunk", (uint32)_file->pos());
+	//warning("%x movieProcessMidiChunk", (uint32)_file->pos());
 
 	if (_midiStarted && (_forceStopMidi == false || _hdrBytes[1] != 0)) {
 		_gamos->stopMidi();


Commit: fa16fdc85b41d49820f89878f2a3b5e3184d0acf
    https://github.com/scummvm/scummvm/commit/fa16fdc85b41d49820f89878f2a3b5e3184d0acf
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:44+01:00

Commit Message:
GAMOS: Fix mouse cursor palette

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index d56b1fd8832..adfd6d565e4 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -102,7 +102,8 @@ Common::Error GamosEngine::run() {
 	if (saveSlot != -1)
 		(void)loadGameState(saveSlot);
 
-	_system->showMouse(true);
+	CursorMan.setDefaultArrowCursor();
+	CursorMan.showMouse(true);
 
 	init(getRunFile());
 
@@ -2855,10 +2856,12 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 }
 
 void GamosEngine::setCursor(int id, bool dirtRect) {
-	if (_unk9 == 0) {
+	if (_unk9 == 0)
 		_mouseCursorImgId = id;
-		_cursorFrame = 0;
-	}
+	else
+		_mouseCursorImgId = -1;
+
+	_cursorFrame = 0;
 }
 
 
@@ -3573,10 +3576,7 @@ void GamosEngine::FUN_004025d0() {
 
 
 bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
-	if (_unk9)
-		return true;
-
-	if (_mouseCursorImgId >= 0) {
+	if (_mouseCursorImgId >= 0 && _unk9 == 0) {
 		Sprite &cursorSpr = _sprites[_mouseCursorImgId];
 
 		if (cursorSpr.field_3 > 1) {
@@ -3587,12 +3587,14 @@ bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
 
 			ImagePos &impos = cursorSpr.sequences[0]->operator[](_cursorFrame);
 			Graphics::Surface &surf = impos.image->surface;
-			CursorMan.replaceCursor(surf, impos.xoffset, impos.yoffset, 0);
+			CursorMan.replaceCursor(surf, -impos.xoffset, -impos.yoffset, 0);
+			CursorMan.disableCursorPalette(true);
 		} else {
 			if (_currentCursor != _mouseCursorImgId) {
 				ImagePos &impos = cursorSpr.sequences[0]->operator[](0);
 				Graphics::Surface &surf = impos.image->surface;
-				CursorMan.replaceCursor(surf, impos.xoffset, impos.yoffset, 0);
+				CursorMan.replaceCursor(surf, -impos.xoffset, -impos.yoffset, 0);
+				CursorMan.disableCursorPalette(true);
 			}
 		}
 	} else {


Commit: ca326dfea2fe1930157d9f9168304ee1e471cd02
    https://github.com/scummvm/scummvm/commit/ca326dfea2fe1930157d9f9168304ee1e471cd02
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:44+01:00

Commit Message:
GAMOS: Implement key sequence check(vm func 13)

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index adfd6d565e4..10880f635d8 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -242,6 +242,8 @@ bool GamosEngine::loader2() {
 }
 
 bool GamosEngine::loadModule(uint id) {
+	_keySeq.clear();
+
 	if ((!_runReadDataMod && !writeStateFile()) ||
 	        !_arch.seekDir(1))
 		return false;
@@ -1166,10 +1168,22 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	_needReload = false;
 	VM::_interrupt = false;
 
+	if (_d2_fld16 == 0) {
+		act1 = ACT_NONE;
+		act2 = ACT_NONE;
+		RawKeyCode = ACT_NONE;
+	}
+
 	RawKeyCode = keyCode;
 
-	FUN_00402c2c(mouseMove, actPos, act2, act1);
+	if (RawKeyCode != ACT_NONE) {
+		if (_keySeq.size() >= 32)
+			_keySeq = _keySeq.substr(_keySeq.size() - 31);
+
+		_keySeq += RawKeyCode;
+	}
 
+	FUN_00402c2c(mouseMove, actPos, act2, act1);
 	if (FUN_00402bc4()) {
 		bool loop = false;
 		if (!DAT_00417802)
@@ -2282,10 +2296,17 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
 	case 13: {
-		VM::ValAddr regRef = vm->popReg(); //implement
+		VM::ValAddr regRef = vm->popReg();
 		Common::String str = vm->getString(regRef);
-		//warning("CallDispatcher 13 keycode %s", str.c_str());
+
 		vm->EAX.setVal(0);
+
+		for(uint i = 0; i < str.size(); i++) {
+			if (str[i] == RawKeyCode) {
+				vm->EAX.setVal(1);
+				break;
+			}
+		}
 		break;
 	}
 
@@ -2622,10 +2643,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	case 57: {
 		VM::ValAddr regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef);
-		warning("CallDispatcher 57 keycode %s", str.c_str());
-		vm->EAX.setVal(0);
-	}
-	break;
+		if (_keySeq.find(str) != Common::String::npos) {
+			_keySeq.clear();
+			vm->EAX.setVal(1);
+		} else
+			vm->EAX.setVal(0);
+	} break;
 
 	default:
 		warning("Call Dispatcher %d", funcID);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 79dcc32d66e..ac77348e63a 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -425,6 +425,8 @@ private:
 
 	uint8 RawKeyCode = 0;
 
+	Common::String _keySeq;
+
 
 	/* path find ? */
 	int32 DAT_00412c8c = 0;


Commit: 6a40704d7f2376fad468fa291d8d0c6459a705f8
    https://github.com/scummvm/scummvm/commit/6a40704d7f2376fad468fa291d8d0c6459a705f8
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:44+01:00

Commit Message:
GAMOS: Implement text input used in wildsnakes for score board

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 10880f635d8..4ce89ea9c22 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -643,7 +643,7 @@ bool GamosEngine::loadInitModule() {
 	_xorSeq[1].clear();
 	_xorSeq[0].clear();
 	_isMoviePlay = 0;
-	DAT_00417802 = false;
+	_txtInputActive = false;
 	//DAT_00417808 = 0;
 	_runReadDataMod = true;
 	//DAT_00417807 = 0;
@@ -1186,10 +1186,10 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
 	if (FUN_00402bc4()) {
 		bool loop = false;
-		if (!DAT_00417802)
+		if (!_txtInputActive)
 			loop = FUN_00402fb4();
-		/*else
-		    loop = FUN_00403314(_messageProc._act2);*/
+		else
+		    loop = onTxtInputUpdate(act2);
 
 		if (_needReload)
 			return 2;  // rerun update after loadModule
@@ -1207,10 +1207,10 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 			if (!FUN_00402bc4())
 				return 0;
 
-			if (!DAT_00417802)
+			if (!_txtInputActive)
 				loop = FUN_00402fb4();
-			/*else
-			    loop = FUN_00403314(_messageProc._act2);*/
+			else
+			    loop = onTxtInputUpdate(act2);
 
 			if (_needReload)
 				return 2; // rerun update after loadModule
@@ -2342,6 +2342,19 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	}
 	break;
 
+	case 21: {
+		VM::ValAddr regRef = vm->popReg();
+		arg2 = vm->pop32();
+		vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH) );
+	} break;
+
+	case 22: {
+		VM::ValAddr regRef = vm->popReg();
+		arg2 = vm->pop32();
+		const SubtitlePoint &d = _subtitlePoints[arg2][0];
+		vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y) );
+	} break;
+
 	case 24: {
 		VM::ValAddr regRef = vm->popReg();
 		arg2 = vm->pop32();
@@ -3721,6 +3734,200 @@ bool GamosEngine::scrollAndDraw() {
 	return true;
 }
 
+int GamosEngine::txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
+	if (memtype != VM::REF_EDI) {
+		error("Unsupported memtype");
+		return 0;
+	}
+
+	if (_txtInputActive == false) {
+		removeSubtitles(PTR_00417218);
+		PTR_00417218->fld_3 |= 2;
+		_txtInputVmOffset = offset;
+		_txtInputSpriteID = sprId;
+		_txtInputX = x;
+		_txtInputY = y;
+		_txtInputObject = PTR_00417218;
+		_txtInputAction = PTR_00417214;
+		_txtInputObjectIndex = _curObjIndex;
+
+		txtInputProcess(0);
+		return 1;
+	}
+	return 0;
+}
+
+void GamosEngine::txtInputProcess(uint8 c) {
+	PTR_00417218 = _txtInputObject;
+	PTR_00417214 = _txtInputAction;
+	_curObjIndex = _txtInputObjectIndex;
+
+	Sprite &spr = _sprites[_txtInputSpriteID];
+
+	uint8 ib = c;
+
+	while (true) {
+		if (ib == 0) {
+			if (_txtInputActive) {
+				_txtInputActive = false;
+				removeSubtitles(PTR_00417218);
+				return;
+			}
+			_txtInputActive = true;
+			_txtInputTyped = false;
+			ib = VM::memory().getU8(_txtInputVmOffset);
+			_txtInputVmOffset++;
+			continue;
+		} else if (ib == KeyCodes::WIN_BACK) {
+			if (_txtInputTyped) {
+				if (_txtInputLength)
+					txtInputEraseBack(1);
+				return;
+			}
+		} else if (ib == KeyCodes::WIN_RETURN) {
+			if (_txtInputTyped) {
+				_txtInputBuffer[_txtInputLength] = 0;
+				switch (_txtInputFlags & 7) {
+					case 0:
+						_txtInputVMAccess.setU8( atoi((char *)_txtInputBuffer) );
+						break;
+
+					case 1: {
+						VmTxtFmtAccess adr;
+						adr.setVal( _txtInputVMAccess.getU32() );
+						adr.write(_txtInputBuffer, _txtInputLength + 1);
+					} break;
+
+					case 2:
+						_txtInputVMAccess.write(_txtInputBuffer, _txtInputLength + 1);
+						break;
+
+					case 3:
+						_txtInputVMAccess.setU32( atoi((char *)_txtInputBuffer) );
+						break;
+
+					case 4: {
+						VmTxtFmtAccess adr;
+						adr.setVal( _txtInputVMAccess.getU32() );
+						adr.setU32( atoi((char *)_txtInputBuffer) );
+					} break;
+				}
+
+				_txtInputTyped = false;
+				ib = VM::memory().getU8(_txtInputVmOffset);
+				_txtInputVmOffset++;
+				continue;
+			}
+		} else if (ib == 0xf) {
+			_txtInputFlags = VM::memory().getU8(_txtInputVmOffset);
+			_txtInputVmOffset++;
+			_txtInputMaxLength = VM::memory().getU8(_txtInputVmOffset);
+			_txtInputVmOffset++;
+
+			if ((_txtInputFlags & 0x70) == 0 || (_txtInputFlags & 0x70) == 0x10) {
+				_txtInputVMAccess.setMemType(VM::REF_EDI);
+				if ((_txtInputFlags & 0x70) == 0x10) {
+					_txtInputVMAccess.setMemType(VM::REF_EBX);
+					_txtInputVMAccess.objMem = PTR_004173e8;
+				}
+				if ( (_txtInputFlags & 0x80) == 0 ) {
+					_txtInputVMAccess.setOffset( VM::memory().getU8(_txtInputVmOffset) );
+					_txtInputVmOffset++;
+				} else {
+					_txtInputVMAccess.setOffset( VM::memory().getU32(_txtInputVmOffset) );
+					_txtInputVmOffset += 4;
+				}
+				switch (_txtInputFlags & 7) {
+					case 0:
+					case 3:
+					case 4:
+						_txtInputIsNumber = true;
+						break;
+
+					case 1:
+					case 2:
+						_txtInputIsNumber = false;
+						break;
+				}
+
+				_txtInputLength = 0;
+				_txtInputTyped = true;
+				return;
+			}
+		} else if (ib == KeyCodes::WIN_ESCAPE) {
+			if (_txtInputTyped) {
+				if (_txtInputLength != 0) {
+                    txtInputEraseBack(_txtInputLength);
+                    return;
+                }
+
+				if (_txtInputActive) {
+					_txtInputActive = false;
+					removeSubtitles(PTR_00417218);
+					return;
+				}
+				_txtInputActive = true;
+				_txtInputTyped = false;
+				ib = VM::memory().getU8(_txtInputVmOffset);
+				_txtInputVmOffset++;
+				continue;
+			}
+		}
+
+		if (_txtInputTyped) {
+			if (_txtInputLength < _txtInputMaxLength) {
+				if (ib < spr.field_1)
+					ib = tolower(ib);
+				if (ib > spr.field_2)
+					ib = toupper(ib);
+				if (ib >= spr.field_1 && ib <= spr.field_2 &&
+				   (_txtInputIsNumber == false || Common::isDigit(ib))) {
+					_txtInputBuffer[_txtInputLength] = ib;
+					_txtInputObjects[_txtInputLength] = addSubtitleImage(ib, _txtInputSpriteID, &_txtInputX, _txtInputY);
+					_txtInputLength++;
+				}
+			}
+			return;
+		} else {
+			addSubtitleImage(ib, _txtInputSpriteID, &_txtInputX, _txtInputY);
+			ib = VM::memory().getU8(_txtInputVmOffset);
+			_txtInputVmOffset++;
+		}
+	}
+}
+
+void GamosEngine::txtInputEraseBack(int n) {
+	for (int32 i = _txtInputLength - 1; i >= 0 && n > 0; i--, n--) {
+		ImagePos *ips = _txtInputObjects[i]->pImg;
+		_txtInputX -= ips->image->surface.w - ips->xoffset;
+		removeObjectMarkDirty(_txtInputObjects[i]);
+
+		_txtInputLength--;
+	}
+}
+
+bool GamosEngine::onTxtInputUpdate(uint8 c) {
+	for(int i = 0; i < _objects.size(); i++) {
+		Object &obj = _objects[i];
+		if ((obj.flags & 0x87) == 0x81) {
+			if ((obj.frame + 1 == obj.fld_2) && obj.pos != 255 && obj.blk != 255) {
+				int32 idx = (obj.blk << 8) | obj.pos;
+				obj.fld_4 = _objects[idx].pos;
+				obj.fld_5 = _objects[idx].blk;
+			}
+			FUN_00402f34(false, false, &obj);
+		}
+	}
+
+	if (RawKeyCode != KeyCodes::WIN_SPACE && RawKeyCode != KeyCodes::WIN_RETURN &&
+		(RawKeyCode == ACT_NONE || c != ACT_NONE) )
+		return true;
+
+	txtInputProcess(RawKeyCode);
+	return true;
+}
+
+
 void GamosEngine::dumpActions() {
 	Common::String t = Common::String::format("./actions_%d.txt", _currentModuleID);
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index ac77348e63a..f444731ab97 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -239,6 +239,56 @@ struct GameScreen {
 	RawData _bkgImageData;
 };
 
+struct VmTxtFmtAccess : VM::ValAddr {
+	byte *objMem = nullptr;
+
+	inline bool isObjMem() const { return getMemType() == VM::REF_EBX;}
+
+	inline Common::String getString(uint maxLen = 256) const {
+		if (isObjMem()) {
+			Common::String s = Common::String((const char *)objMem + getOffset());
+			if (s.size() > maxLen)
+				s.erase(maxLen);
+			return s;
+		}
+
+		return VM::readMemString(getOffset(), maxLen);
+	}
+
+	inline uint8 getU8() const {
+		if (isObjMem())
+			return objMem[getOffset()];
+		return VM::memory().getU8(getOffset());
+	}
+
+	inline uint32 getU32() const {
+		if (isObjMem())
+			return VM::getU32(objMem + getOffset());
+		return VM::memory().getU32(getOffset());
+	}
+
+	inline void write(byte *src, uint len) {
+		if (isObjMem())
+			memcpy(objMem + getOffset(), src, len);
+		else
+			VM::writeMemory(getOffset(), src, len);
+	}
+
+	inline void setU8(uint8 v) {
+		if (isObjMem())
+			objMem[getOffset()] = v;
+		else
+			VM::memory().setU8(getOffset(), v);
+	}
+
+	inline void setU32(uint32 v) {
+		if (isObjMem())
+			VM::setU32(objMem + getOffset(), v);
+		else
+			VM::memory().setU32(getOffset(), v);
+	}
+};
+
 class GamosEngine : public Engine {
 	friend class MoviePlayer;
 
@@ -412,8 +462,6 @@ private:
 
 	int32 _curObjIndex = 0;
 
-	bool DAT_00417802 = false;
-
 
 	int32 DAT_004173f0 = 0;
 	int32 DAT_004173f4 = 0;
@@ -428,6 +476,26 @@ private:
 	Common::String _keySeq;
 
 
+	int32 _txtInputVmOffset = -1;
+	int32 _txtInputSpriteID = 0;
+	int32 _txtInputX = 0;
+	int32 _txtInputY = 0;
+	uint8 _txtInputBuffer[256];
+	Object *_txtInputObjects[256];
+	int32 _txtInputLength = 0;
+	int32 _txtInputMaxLength = 0;
+	VmTxtFmtAccess _txtInputVMAccess;
+	uint8 _txtInputFlags = 0;
+	bool _txtInputTyped = false;
+	bool _txtInputIsNumber = false;
+	Object *_txtInputObject = nullptr;
+	ObjectAction *_txtInputAction = nullptr;
+	int32 _txtInputObjectIndex = -1;
+
+
+	bool _txtInputActive = false;
+
+
 	/* path find ? */
 	int32 DAT_00412c8c = 0;
 	int32 DAT_00412c90 = 0;
@@ -588,7 +656,11 @@ protected:
 
 	void FUN_004025d0();
 
+	int txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y);
+	void txtInputProcess(uint8 c);
+	void txtInputEraseBack(int n);
 
+	bool onTxtInputUpdate(uint8 c);
 
 	/* save-load */
 	void storeToGameScreen(int id);


Commit: b4a6d43280b340212ba2f41fc60a69f79bad8a2e
    https://github.com/scummvm/scummvm/commit/b4a6d43280b340212ba2f41fc60a69f79bad8a2e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:45+01:00

Commit Message:
GAMOS: Update text output function to support score board draw in wildsnake

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 4ce89ea9c22..7631494defb 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2355,6 +2355,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y) );
 	} break;
 
+	case 23: {
+		VM::ValAddr regRef = vm->popReg();
+		arg2 = vm->pop32();
+		addSubtitles(vm, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH);
+		vm->EAX.setVal(1);
+	} break;
+
 	case 24: {
 		VM::ValAddr regRef = vm->popReg();
 		arg2 = vm->pop32();
@@ -3062,27 +3069,39 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 						offset += 4;
 					}
 
-					warning("addSubtitles unimplemented part");
-
+					Common::String tmp;
 					switch (flg & 7) {
 					case 0:
+						tmp = gamos_itoa((int32)(int8)vm->getMem8(btp, boff), 10);
 						break;
 
-					case 1:
-						break;
+					case 1: {
+						VM::ValAddr addr;
+						addr.setVal( vm->getMem32(btp, boff) );
+						tmp = vm->getString(addr, b2);
+					} break;
 
 					case 2:
+						tmp = vm->getString(btp, boff, b2);
 						break;
 
 					case 3:
+						tmp = gamos_itoa(vm->getMem32(btp, boff), 10);
 						break;
 
-					case 4:
-						break;
+					case 4: {
+						VM::ValAddr addr;
+						addr.setVal( vm->getMem32(btp, boff) );
+						tmp = gamos_itoa(vm->getMem32(addr), 10);
+					} break;
 
 					case 5:
 						break;
 					}
+
+					for (int i = 0; i < tmp.size(); i++) {
+						addSubtitleImage(tmp[i], sprId, &x, y);
+					}
 				}
 			}
 		} else {
@@ -3734,6 +3753,38 @@ bool GamosEngine::scrollAndDraw() {
 	return true;
 }
 
+Common::String GamosEngine::gamos_itoa(int n, uint radix) {
+	Common::String tmp;
+	bool minus = false;
+	uint un = n;
+	if (radix == 10 && n < 0) {
+		un = -n;
+		minus = true;
+	}
+
+	if (un == 0) {
+		tmp += '0';
+	} else {
+		while (un != 0) {
+			uint r = un % radix;
+			un /= radix;
+			if (r > 9)
+				tmp += 'A' + r - 10;
+			else
+				tmp += '0' + r;
+		}
+	}
+	if (minus)
+		tmp += '-';
+
+	for (int i = 0, j = tmp.size() - 1; i < j; i++, j--) {
+		char c = tmp[i];
+		tmp.setChar(tmp[j], i);
+		tmp.setChar(c, j);
+	}
+	return tmp;
+}
+
 int GamosEngine::txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
 	if (memtype != VM::REF_EDI) {
 		error("Unsupported memtype");
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index f444731ab97..4f00f469f08 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -686,6 +686,9 @@ protected:
 
 	static void callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID);
 
+
+	static Common::String gamos_itoa(int value, uint radix);
+
 public:
 
 	inline void rndSeed(uint32 seed) {


Commit: ec02914c1e98931bd4abdb105e6d18c854782698
    https://github.com/scummvm/scummvm/commit/ec02914c1e98931bd4abdb105e6d18c854782698
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:45+01:00

Commit Message:
GAMOS: Implement volume manipulation

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/music.cpp
    engines/gamos/music.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 7631494defb..b27f53a93c6 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -625,6 +625,10 @@ bool GamosEngine::init(const Common::String &moduleName) {
 	if (!loadInitModule())
 		return false;
 
+	_savedSndVolume = !ConfMan.hasKey("sfx_volume") ? 255 : ConfMan.getInt("sfx_volume");
+	_savedMidiVolume = !ConfMan.hasKey("music_volume") ? 255 : ConfMan.getInt("music_volume");
+	_sndVolumeTarget = _savedSndVolume;
+	_midiVolumeTarget = _savedMidiVolume;
 
 	if (!playIntro())
 		return false;
@@ -646,10 +650,10 @@ bool GamosEngine::loadInitModule() {
 	_txtInputActive = false;
 	//DAT_00417808 = 0;
 	_runReadDataMod = true;
-	//DAT_00417807 = 0;
-	//DAT_00417806 = 0;
-	//DAT_004177fa = 0;
-	//DAT_004177fb = 0;
+	_savedSndVolume = 0;
+	_savedMidiVolume = 0;
+	_sndVolumeTarget = 0;
+	_midiVolumeTarget = 0;
 	//_mouseInWindow = false;
 
 	return loadModule(0);
@@ -1160,10 +1164,40 @@ bool GamosEngine::playMidi(Common::Array<byte> *buffer) {
 
 bool GamosEngine::playSound(uint id) {
 	Audio::SeekableAudioStream *stream = Audio::makeRawStream(_soundSamples[id].data(), _soundSamples[id].size(), 11025, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
-	_mixer->playStream(Audio::Mixer::kPlainSoundType, nullptr, stream, id);
+	_mixer->playStream(Audio::Mixer::kPlainSoundType, nullptr, stream, -1, _sndVolume);
 	return true;
 }
 
+int GamosEngine::stepVolume(int volume, int target) {
+	int d = target - volume;
+	if (d == 0)
+		return 0;
+
+	int step = 255 / _fps;
+	if (d < 0) {
+		step = -step;
+		if (step < d)
+			step = d;
+	} else {
+		if (step > d)
+			step = d;
+	}
+	return step;
+}
+
+void GamosEngine::changeVolume() {
+	const int sndStep = stepVolume(_sndVolume, _sndVolumeTarget);
+	if (sndStep) {
+		_sndVolume += sndStep;
+		_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, _sndVolume);
+	}
+	const int midiStep = stepVolume(_midiVolume, _midiVolumeTarget);
+	if (midiStep) {
+		_midiVolume += midiStep;
+		_musicPlayer.setVolume(_midiVolume);
+	}
+}
+
 uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
 	_needReload = false;
 	VM::_interrupt = false;
@@ -1184,6 +1218,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	}
 
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
+	changeVolume();
 	if (FUN_00402bc4()) {
 		bool loop = false;
 		if (!_txtInputActive)
@@ -2639,6 +2674,52 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	}
 	break;
 
+	case 48: {
+		arg1 = vm->pop32();
+
+		switch (arg1) {
+		case 0:
+			_d2_fld16 = 0;
+			break;
+		case 1:
+			_d2_fld16 = 1;
+			break;
+		case 2:
+			_d2_fld14 = 0;
+			_sndVolumeTarget = 0;
+			break;
+		case 3:
+			_d2_fld14 = 1;
+			_sndVolumeTarget = _savedSndVolume;
+			break;
+		case 4:
+			_midiVolumeTarget = 0;
+			break;
+		case 5:
+			_midiVolumeTarget = _savedMidiVolume;
+			break;
+		case 6:
+			_d2_fld17 = 0;
+			break;
+		case 7:
+			_d2_fld17 = 1;
+			break;
+		case 8:
+			//FUN_0040a9c0(0);
+			_d2_fld18 = 0;
+			break;
+		case 9:
+			if (_d2_fld19 != 0xff) {
+				//FUN_0040a958(_d2_fld19);
+			}
+			_d2_fld18 = 1;
+			break;
+		default:
+			break;
+		}
+		vm->EAX.setVal(1);
+	} break;
+
 	case 49: {
 		arg1 = vm->pop32();
 		arg2 = vm->pop32();
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4f00f469f08..1d4c5505243 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -407,6 +407,11 @@ private:
 	uint8 _svFps = 0;
 	uint32 _svFrame = 0;
 
+	uint8 _sndVolumeTarget = 0;
+	uint8 _midiVolumeTarget = 0;
+	uint8 _savedSndVolume = 0;
+	uint8 _savedMidiVolume = 0;
+
 	bool _enableMidi = false;
 	int32 _midiTrack = 0;
 
@@ -556,6 +561,10 @@ protected:
 	bool playMidi(Common::Array<byte> *buffer);
 
 	bool playSound(uint id);
+	int stepVolume(int volume, int target);
+
+	void changeVolume();
+
 
 	void stopMidi();
 	void stopMCI();
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index 649b0998e34..c120e7ab973 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -130,6 +130,9 @@ void MidiMusic::update() {
 
 				doDelay = (b & 0x80) == 0;
 				param2 = b & 0x7f;
+
+				if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_ON)
+					param2 = param2 * _volume / 255;
 			}
 
 			if (doSend)
@@ -147,6 +150,16 @@ void MidiMusic::update() {
 	}
 }
 
+void MidiMusic::setVolume(uint8 volume) {
+	if (volume == 0) {
+		_midiMute = true;
+		_driver->stopAllNotes();
+	} else
+		_midiMute = false;
+
+	_volume = volume;
+}
+
 int16 MidiMusic::midi2low() {
 	if (_dataPos >= _pMidiData.size())
 		return -1;
diff --git a/engines/gamos/music.h b/engines/gamos/music.h
index 11f061c1d08..24ad6370a26 100644
--- a/engines/gamos/music.h
+++ b/engines/gamos/music.h
@@ -49,6 +49,8 @@ private:
 	uint32 _midiOp = 0; /* save midi event type between update cycles */
 	bool _midiMute = false;
 
+	uint8 _volume;
+
 public:
 
 	MidiMusic();
@@ -57,6 +59,9 @@ public:
 	void stopMusic();
 	bool playMusic(Common::Array<byte> *midiData);
 	void update();
+
+	void setVolume(uint8 volume);
+
 	int16 midi2low();
 
 	static void _timerProc(void *data);


Commit: 4b41d8b586acf87fcfe6da00fbb6e3706d51a4b0
    https://github.com/scummvm/scummvm/commit/4b41d8b586acf87fcfe6da00fbb6e3706d51a4b0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:45+01:00

Commit Message:
GAMOS: Fix no music on replay of music (wildsnakes)

Changed paths:
    engines/gamos/music.cpp


diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index c120e7ab973..83dc4529d48 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -61,8 +61,7 @@ bool MidiMusic::playMusic(Common::Array<byte> *midiData) {
 	if (!_mutex.lock())
 		return false;
 
-	_pMidiData.clear();
-	_pMidiData.swap(*midiData);
+	_pMidiData = *midiData;
 
 	_dataStart = 4;
 	_dataPos = _dataStart;


Commit: a38406da599a96f6f3380d746c04a2916d219333
    https://github.com/scummvm/scummvm/commit/a38406da599a96f6f3380d746c04a2916d219333
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:46+01:00

Commit Message:
GAMOS: Update and implement missing path-finding code

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index b27f53a93c6..59f64fbb7e9 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2465,109 +2465,165 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		VM::ValAddr regRef = vm->popReg();
 		vm->setMem8(regRef, PTR_00417218->fld_5);
 		vm->EAX.setVal(1);
-	}
-	break;
+	} break;
 
-	case 35:
+	case 35: {
 		arg1 = vm->pop32();
-
+		uint ret = 0;
 		switch (arg1) {
 		case 3:
-			FUN_00408648(0xe, 0xff, 0xff);
+			ret = FUN_00408648(0xe, 0xff, 0xff);
 			break;
 
 		case 4:
-			FUN_00408648(0xe, 0xfe, 0xff);
+			ret = FUN_00408648(0xe, 0xfe, 0xff);
 			break;
 
 		case 5:
-			FUN_00408648(0xe, 0xfe, 0xfe);
+			ret = FUN_00408648(0xe, 0xfe, 0xfe);
 			break;
 
 		case 6:
-			FUN_00408648(0x82, 0xff, 0xff);
+			ret = FUN_00408648(0x82, 0xff, 0xff);
 			break;
 
 		case 7:
-			FUN_00408648(0x82, 0xfe, 0xff);
+			ret = FUN_00408648(0x82, 0xfe, 0xff);
 			break;
 
 		case 8:
-			FUN_00408648(0x82, 0xfe, 0xfe);
+			ret = FUN_00408648(0x82, 0xfe, 0xfe);
 			break;
 
 		case 9:
-			FUN_00408648(0x83, 0xff, 0xff);
+			ret = FUN_00408648(0x83, 0xff, 0xff);
 			break;
 
 		case 10:
-			FUN_00408648(0x83, 0xfe, 0xff);
+			ret = FUN_00408648(0x83, 0xfe, 0xff);
 			break;
 
 		case 11:
-			FUN_00408648(0x83, 0xfe, 0xfe);
+			ret = FUN_00408648(0x83, 0xfe, 0xfe);
 			break;
 
 		default:
 			break;
 		}
+		vm->EAX.setVal(ret);
+	} break;
 
-		break;
-
-	case 36:
+	case 36: {
 		arg1 = vm->pop32();
 		arg2 = vm->pop32();
 
+		uint ret = 0;
 		switch (arg1) {
 		case 1:
-			FUN_00408648(0, arg2, 0xff);
+			ret = FUN_00408648(0, arg2, 0xff);
 			break;
 
 		case 2:
-			FUN_00408648(0, arg2, 0xfe);
+			ret = FUN_00408648(0, arg2, 0xfe);
 			break;
 
 		case 3:
-			FUN_00408648(0xe, arg2, 0xff);
+			ret = FUN_00408648(0xe, arg2, 0xff);
 			break;
 
 		case 4:
-			FUN_00408648(0xe, arg2, 0xfe);
+			ret = FUN_00408648(0xe, arg2, 0xfe);
 			break;
 
 		case 5:
-			FUN_00408648(0xe, arg2, arg2);
+			ret = FUN_00408648(0xe, arg2, arg2);
 			break;
 
 		case 6:
-			FUN_00408648(0x82, arg2, 0xff);
+			ret = FUN_00408648(0x82, arg2, 0xff);
 			break;
 
 		case 7:
-			FUN_00408648(0x82, arg2, 0xfe);
+			ret = FUN_00408648(0x82, arg2, 0xfe);
 			break;
 
 		case 8:
-			FUN_00408648(0x82, arg2, arg2);
+			ret = FUN_00408648(0x82, arg2, arg2);
 			break;
 
 		case 9:
-			FUN_00408648(0x83, arg2, 0xff);
+			ret = FUN_00408648(0x83, arg2, 0xff);
 			break;
 
 		case 10:
-			FUN_00408648(0x83, arg2, 0xfe);
+			ret = FUN_00408648(0x83, arg2, 0xfe);
 			break;
 
 		case 11:
-			FUN_00408648(0x83, arg2, arg2);
+			ret = FUN_00408648(0x83, arg2, arg2);
 			break;
 
 		default:
 			break;
 		}
+		vm->EAX.setVal(ret);
+	} break;
 
-		break;
+	case 37: {
+		arg1 = vm->pop32();
+		arg2 = vm->pop32();
+
+		uint ret = 0;
+		switch (arg1) {
+		case 1:
+			ret = FUN_004088cc(0, arg2, 0xff);
+			break;
+
+		case 2:
+			ret = FUN_004088cc(0, arg2, 0xfe);
+			break;
+
+		case 3:
+			ret = FUN_004088cc(0xe, arg2, 0xff);
+			break;
+
+		case 4:
+			ret = FUN_004088cc(0xe, arg2, 0xfe);
+			break;
+
+		case 5:
+			ret = FUN_004088cc(0xe, arg2, arg2);
+			break;
+
+		case 6:
+			ret = FUN_004088cc(0x82, arg2, 0xff);
+			break;
+
+		case 7:
+			ret = FUN_004088cc(0x82, arg2, 0xfe);
+			break;
+
+		case 8:
+			ret = FUN_004088cc(0x82, arg2, arg2);
+			break;
+
+		case 9:
+			ret = FUN_004088cc(0x83, arg2, 0xff);
+			break;
+
+		case 10:
+			ret = FUN_004088cc(0x83, arg2, 0xfe);
+			break;
+
+		case 11:
+			ret = FUN_004088cc(0x83, arg2, arg2);
+			break;
+
+		default:
+			break;
+		}
+		vm->EAX.setVal(ret);
+	} break;
 
 	case 38:
 		arg1 = vm->pop32();
@@ -3263,35 +3319,34 @@ void GamosEngine::FUN_00407db8(uint8 p) {
 	DAT_00417804 = 0;
 }
 
-void GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
+byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
 	FUN_00407db8(p1);
 
 	if (p1 == 0x82 || p1 == 0x83) {
 		if (p1 != DAT_004177fe)
-			return;
+			return 0;
 		if (p2 != 0xff && p2 != DAT_004177fd)
-			return;
+			return 0;
 	} else {
 		if (p1 != 0xe) {
 			if (p3 == 0xff)
-				FUN_004084bc(p2);
+				return FUN_004084bc(p2);
 			else
-				FUN_00408510(p2);
-			return;
+				return FUN_00408510(p2);
 		}
 		if (p2 != 0xff && p2 != DAT_00417803)
-			return;
+			return 0;
 	}
 
 	if (p3 == 0xff)
-		FUN_00407e2c();
+		return FUN_00407e2c();
 	else if (p3 == 0xfe)
-		FUN_0040856c();
+		return FUN_0040856c();
 	else
-		FUN_004085d8(p2);
+		return FUN_004085d8(p2);
 }
 
-void GamosEngine::FUN_004084bc(uint8 p) {
+byte GamosEngine::FUN_004084bc(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
 			uint16 th1 = _states.at(i, j);
@@ -3301,10 +3356,10 @@ void GamosEngine::FUN_004084bc(uint8 p) {
 				_pathMap.at(i, j) = 2;
 		}
 	}
-	FUN_0040841c(true);
+	return FUN_0040841c(true);
 }
 
-void GamosEngine::FUN_00408510(uint8 p) {
+byte GamosEngine::FUN_00408510(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
 			uint16 th1 = _states.at(i, j);
@@ -3317,10 +3372,10 @@ void GamosEngine::FUN_00408510(uint8 p) {
 				_pathMap.at(i, j) = 3;
 		}
 	}
-	FUN_0040841c(false);
+	return FUN_0040841c(false);
 }
 
-void GamosEngine::FUN_0040856c() {
+byte GamosEngine::FUN_0040856c() {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
 			uint16 th1 = _states.at(i, j);
@@ -3332,10 +3387,10 @@ void GamosEngine::FUN_0040856c() {
 		}
 	}
 	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
-	FUN_0040841c(false);
+	return FUN_0040841c(false);
 }
 
-void GamosEngine::FUN_004085d8(uint8 p) {
+byte GamosEngine::FUN_004085d8(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
 			uint16 th1 = _states.at(i, j);
@@ -3347,44 +3402,41 @@ void GamosEngine::FUN_004085d8(uint8 p) {
 		}
 	}
 	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
-	FUN_0040841c(false);
+	return FUN_0040841c(false);
 }
 
-void GamosEngine::FUN_0040841c(bool p) {
+byte GamosEngine::FUN_0040841c(bool p) {
 	_pathMap.at(DAT_00412c8c, DAT_00412c90) = 6;
 
 	while (true) {
 		byte res = FUN_004081b8(6, 4);
 		if (res == 0)
-			break;
+			return 0;
 		else if (res == 1) {
 			if (p)
-				FUN_00407e2c();
+				return FUN_00407e2c();
 			else
-				FUN_00407f70(6);
-			break;
+				return FUN_00407f70(6);
 		}
 
 		res = FUN_004081b8(4, 5);
 		if (res == 0)
-			break;
+			return 0;
 		else if (res == 1) {
 			if (p)
-				FUN_00407e2c();
+				return FUN_00407e2c();
 			else
-				FUN_00407f70(4);
-			break;
+				return FUN_00407f70(4);
 		}
 
 		res = FUN_004081b8(5, 6);
 		if (res == 0)
-			break;
+			return 0;
 		else if (res == 1) {
 			if (p)
-				FUN_00407e2c();
+				return FUN_00407e2c();
 			else
-				FUN_00407f70(5);
-			break;
+				return FUN_00407f70(5);
 		}
 	}
 }
@@ -3579,6 +3631,81 @@ byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
 	return ret;
 }
 
+byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
+	FUN_00407db8(p1);
+
+	if (p1 == 0x82 || p1 == 0x83) {
+		if (p1 != DAT_004177fe)
+			return 0;
+
+		if ( (_thing2[p2].field_0[ DAT_004177fd >> 3 ] & (1 << (DAT_004177fd & 7))) == 0 )
+			return 0;
+	} else {
+		if (p1 != 0xe) {
+			if (p3 == 0xff)
+				return FUN_004086e4(_thing2[p2].field_0);
+			else
+				return FUN_00408778(_thing2[p2].field_0);
+		}
+
+		if ( (_thing2[p2].field_0[ DAT_00417803 >> 3 ] & (1 << (DAT_00417803 & 7))) == 0 )
+			return 0;
+	}
+
+	if (p3 == 0xff)
+		return FUN_00407e2c();
+	else if (p3 == 0xfe)
+		return FUN_0040881c(_thing2[p2].field_0);
+	else
+		return FUN_0040856c();
+}
+
+byte GamosEngine::FUN_004086e4(const Common::Array<byte> &arr) {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+
+			if ( ((arr[th1 >> 3]) & (1 << (th1 & 7))) == 0 )
+				_pathMap.at(i, j) = 0;
+			else
+				_pathMap.at(i, j) = 2;
+		}
+	}
+	return FUN_0040841c(true);
+}
+
+byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+
+			if ( ((arr[th1 >> 3]) & (1 << (th1 & 7))) == 0 )
+				_pathMap.at(i, j) = 3;
+			else
+				_pathMap.at(i, j) = 2;
+		}
+	}
+	return FUN_0040841c(false);
+}
+
+byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
+	for (int j = 0; j < _statesHeight; j++) {
+		for (int i = 0; i < _statesWidth; i++) {
+			uint16 th1 = _states.at(i, j);
+
+			if ( ((arr[th1 >> 3]) & (1 << (th1 & 7))) == 0 )
+				_pathMap.at(i, j) = 3;
+			else
+				_pathMap.at(i, j) = 0;
+		}
+	}
+	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
+	return FUN_0040841c(false);
+}
+
+
+
+
 void Actions::parse(const byte *data, size_t dataSize) {
 	Common::MemoryReadStream rstream(data, dataSize);
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 1d4c5505243..cbf787c9d32 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -652,16 +652,21 @@ protected:
 	void addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
 
 	void FUN_00407db8(uint8 p);
-	void FUN_00408648(uint8 p1, uint8 p2, uint8 p3);
-	void FUN_004084bc(uint8 p);
-	void FUN_00408510(uint8 p);
-	void FUN_0040856c();
-	void FUN_004085d8(uint8 p);
-	void FUN_0040841c(bool p);
+	byte FUN_00408648(uint8 p1, uint8 p2, uint8 p3);
+	byte FUN_004084bc(uint8 p);
+	byte FUN_00408510(uint8 p);
+	byte FUN_0040856c();
+	byte FUN_004085d8(uint8 p);
+	byte FUN_0040841c(bool p);
 	byte FUN_00407e2c();
 	byte FUN_00407f70(uint8 p);
 	byte FUN_004081b8(uint8 cv, uint8 sv);
 
+	byte FUN_004088cc(uint8 p1, uint8 p2, uint8 p3);
+	byte FUN_004086e4(const Common::Array<byte> &arr);
+	byte FUN_00408778(const Common::Array<byte> &arr);
+	byte FUN_0040881c(const Common::Array<byte> &arr);
+
 
 	void FUN_004025d0();
 


Commit: b6fada6766d5d169f17849b9984fb37a6c71b3a0
    https://github.com/scummvm/scummvm/commit/b6fada6766d5d169f17849b9984fb37a6c71b3a0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:46+01:00

Commit Message:
GAMOS: Play not only intro movies

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 59f64fbb7e9..fd05a84f074 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -890,7 +890,7 @@ bool GamosEngine::playMovie(int id) {
 
 
 bool GamosEngine::scriptFunc18(uint32 id) {
-	if (true) {
+	if (_d2_fld17 != 0) {
 		_isMoviePlay++;
 		bool res = playMovie(id);
 		_isMoviePlay--;
@@ -2363,6 +2363,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.setVal(1);
 		break;
 
+	case 18:
+		arg1 = vm->pop32();
+		vm->EAX.setVal( scriptFunc18(arg1) ? 1 : 0 );
+		break;
+
 	case 19:
 		arg1 = vm->pop32();
 		vm->EAX.setVal( scriptFunc19(arg1) );


Commit: 52cb4bde5b1b502d5981d898e992259b81444415
    https://github.com/scummvm/scummvm/commit/52cb4bde5b1b502d5981d898e992259b81444415
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:46+01:00

Commit Message:
GAMOS: Style and code improvements

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index fd05a84f074..4876f313b24 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -18,23 +18,26 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-
+#include "gamos/console.h"
+#include "gamos/detection.h"
 #include "gamos/gamos.h"
+
 #include "graphics/cursorman.h"
 #include "graphics/framelimiter.h"
-#include "gamos/detection.h"
-#include "gamos/console.h"
-#include "common/scummsys.h"
+#include "graphics/paletteman.h"
+
 #include "common/config-manager.h"
 #include "common/debug-channels.h"
+#include "common/endian.h"
 #include "common/events.h"
-#include "common/system.h"
+#include "common/keyboard.h"
 #include "common/rect.h"
+#include "common/scummsys.h"
+#include "common/system.h"
 #include "common/util.h"
+
 #include "engines/util.h"
-#include "graphics/paletteman.h"
-#include "common/keyboard.h"
-#include "common/endian.h"
+
 #include "audio/mididrv.h"
 #include "audio/midiplayer.h"
 
@@ -2290,7 +2293,7 @@ uint32 GamosEngine::doScript(uint32 scriptAddress) {
 
 
 void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
-	uint32 arg1 = 0, arg2 = 0, arg3 = 0;
+	uint32 arg1 = 0, arg2 = 0;
 
 	switch (funcID) {
 	case 0:
@@ -2309,21 +2312,17 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			vm->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
 		break;
 	case 3:
-		//warning("func 3 %x check 0x10", PTR_00417218->fld_4 & 0x90);
 		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
 		break;
 	case 4:
-		//warning("func 4 %x check 0x20", PTR_00417218->fld_4 & 0xa0);
 		vm->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
 		break;
 	case 5:
 		arg1 = vm->pop32();
-		//warning("func 5 %x check %x", PTR_00417218->fld_4 & 0xb0, arg1);
 		vm->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
 		break;
 	case 6:
 		arg1 = vm->pop32();
-		//warning("func 6 %x check %x", PTR_00417218->fld_4 & 0x4f, arg1);
 		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
 		break;
 	case 9:
@@ -2379,8 +2378,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			FUN_0040738c(d.sprId, d.x, d.y, true);
 		}
 		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
-	}
-	break;
+	} break;
 
 	case 21: {
 		VM::ValAddr regRef = vm->popReg();
@@ -2447,8 +2445,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			PTR_00417218->y = -1;
 			removeObjectMarkDirty(obj);
 		}
-	}
-	break;
+	} break;
 
 	case 31:
 		arg1 = vm->pop32();
@@ -2671,8 +2668,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			}
 		}
 		vm->EAX.setVal(1);
-	}
-	break;
+	} break;
 
 	case 43: {
 		arg1 = vm->pop32();
@@ -2684,8 +2680,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
 		vm->EAX.setVal(1);
-	}
-	break;
+	} break;
 
 	case 44: {
 		arg1 = vm->pop32();
@@ -2697,8 +2692,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
 		vm->EAX.setVal(1);
-	}
-	break;
+	} break;
 
 	case 45:
 		arg1 = vm->pop32();
@@ -3071,7 +3065,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	else if (act2 == ACT_NONE)
 		actPos = move;
 
-	if (act1 != 0xe)
+	if (act1 != ACT_NONE)
 		tmpb |= act1 | 0x40;
 
 	actPos += Common::Point(_scrollX, _scrollY);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index cbf787c9d32..29d29d9ce0e 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -311,8 +311,8 @@ private:
 	uint32 _magic;
 	uint32 _pages1kbCount;
 	uint32 _readBufSize;
-	uint32 _width;
-	uint32 _height;
+	uint32 _width; //screen output width
+	uint32 _height; //screen output height
 	int32 _gridCellW;
 	int32 _gridCellH;
 	uint32 _movieCount;


Commit: 87be9d52089965223448cb40d1ac98563385ad7f
    https://github.com/scummvm/scummvm/commit/87be9d52089965223448cb40d1ac98563385ad7f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:47+01:00

Commit Message:
GAMOS: Implementation or stubs for almost all vm functions

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 4876f313b24..f17c4fedc40 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1988,7 +1988,7 @@ bool GamosEngine::FUN_00402fb4() {
 						bool tmp = false;
 						for (int i = 0; i < 8; i++) {
 							if ((PTR_00417214->unk1 >> 8) & (1 << i)) {
-								//DAT_004173ec = ((i & 3) + ivr8) & 3;
+								DAT_004173ec = ((i & 3) + ivr8) & 3;
 								int fncid = ((i & 3) + ivr8) & 3;
 								if (i > 3)
 									fncid += 4;
@@ -2325,10 +2325,32 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		arg1 = vm->pop32();
 		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
 		break;
+	case 7:
+		arg1 = vm->pop32();
+		if ((PTR_00417218->fld_4 & 0x40) == 0 || (PTR_00417218->fld_4 & 8) != (arg1 & 8))
+			vm->EAX.setVal(0);
+		else
+			vm->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->fld_4 & 7) ? 1 : 0 );
+		break;
+	case 8:
+		arg1 = vm->pop32();
+		vm->EAX.setVal( PTR_00417218->fld_5 == arg1 ? 1 : 0 );
+		break;
 	case 9:
 		arg1 = vm->pop32();
 		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
+	case 10:
+		vm->EAX.setVal( PTR_00417218->fld_2 == 0xfe ? 1 : 0 );
+		break;
+	case 11:
+		arg1 = vm->pop32();
+		vm->EAX.setVal( PTR_00417218->fld_2 == arg1 ? 1 : 0 );
+		break;
+	case 12:
+		arg1 = vm->pop32();
+		vm->EAX.setVal( (1 << (PTR_00417218->fld_2 & 7)) & _thing2[arg1].field_0[PTR_00417218->fld_2 >> 3] );
+		break;
 	case 13: {
 		VM::ValAddr regRef = vm->popReg();
 		Common::String str = vm->getString(regRef);
@@ -2351,6 +2373,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.setVal(1);
 		break;
 
+	case 15:
+		arg1 = vm->pop32();
+		switchToGameScreen(arg1, false);
+		setNeedReload();
+		break;
+
 	case 16:
 		arg1 = vm->pop32();
 		vm->EAX.setVal( scriptFunc16(arg1) );
@@ -2438,6 +2466,18 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.setVal(1);
 		break;
 
+	case 28:
+		arg1 = vm->pop32();
+		//FUN_0040279c(arg1, false);
+		vm->EAX.setVal(1);
+		break;
+
+	case 29:
+		arg1 = vm->pop32();
+		//FUN_0040279c(arg1, true);
+		vm->EAX.setVal(1);
+		break;
+
 	case 30: {
 		if (PTR_00417218->y != -1) {
 			Object *obj = &_objects[PTR_00417218->y];
@@ -2643,6 +2683,22 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			vm->EAX.setVal(1);
 		break;
 
+	case 40:
+		arg1 = vm->pop32();
+		if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412ca0) != 0)
+			vm->EAX.setVal(1);
+		else
+			vm->EAX.setVal(0);
+		break;
+
+	case 41:
+		arg1 = vm->pop32();
+		if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412c9c) != 0)
+			vm->EAX.setVal(1);
+		else
+			vm->EAX.setVal(0);
+		break;
+
 	case 42: {
 		arg1 = vm->pop32();
 		if (DAT_00417804 != 0) {
@@ -2699,6 +2755,15 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		vm->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
 		break;
 
+	case 46: {
+		VM::ValAddr a1 = vm->popReg();
+		VM::ValAddr a2 = vm->popReg();
+		Common::String s = vm->getString(a1);
+		for(int i = 0; i <= s.size(); i++) {
+			vm->setMem8(a2.getMemType(), a2.getOffset() + i, s.c_str()[i]);
+		}
+	} break;
+
 	case 47: {
 		arg1 = vm->pop32();
 
@@ -2783,6 +2848,32 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	}
 	break;
 
+	case 50:
+		arg1 = vm->pop32();
+		PTR_00417388 = _thing2[arg1].field_0.data();
+		vm->EAX.setVal(1);
+		break;
+
+	case 51:
+		PTR_00417388 = nullptr;
+		vm->EAX.setVal(1);
+		break;
+
+	case 52:
+		arg1 = vm->pop32();
+		/* HELP */
+		//FUN_0040c614(arg1);
+		vm->EAX.setVal(1);
+		break;
+
+	case 53: {
+		arg1 = vm->pop32();
+		VM::ValAddr adr = vm->popReg();
+		uint kode = vm->getMem8(adr);
+		_messageProc._keyCodes[arg1] = kode;
+		vm->EAX.setVal(kode);
+	} break;
+
 	case 54:
 		arg1 = vm->pop32();
 		vm->EAX.setVal(rndRange16(arg1));
@@ -2796,6 +2887,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	}
 	break;
 
+	case 56: {
+		VM::ValAddr regRef = vm->popReg(); //implement
+		Common::String str = vm->getString(regRef);
+		warning("Create process: %s", str.c_str());
+		vm->EAX.setVal(1);
+	} break;
+
 	case 57: {
 		VM::ValAddr regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef);
@@ -2806,6 +2904,48 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			vm->EAX.setVal(0);
 	} break;
 
+	case 58: {
+		arg1 = vm->pop32();
+		/* CD AUDIO */
+		vm->EAX.setVal(1);
+	} break;
+
+	case 59: {
+		arg1 = vm->pop32();
+		/* CD AUDIO */
+		vm->EAX.setVal(1);
+	} break;
+
+	case 60:
+		arg1 = vm->pop32();
+		if (arg1 == 0)
+			_scrollTrackObj = -1;
+		else
+			_scrollTrackObj = _curObjIndex;
+		vm->EAX.setVal(1);
+		break;
+
+	case 61: {
+		arg1 = vm->pop32();
+		VM::ValAddr adr = vm->popReg();
+		Common::String tmp = vm->getString(adr);
+
+		int val1 = 0, val2 = 0, val3 = 0, val4 = 0;
+		sscanf(tmp.c_str(), "%d %d %d %d", &val1, &val2, &val3, &val4);
+
+		if (arg1 == 0) {
+			_scrollBorderL = val1;
+			_scrollBorderR = val2;
+			_scrollBorderU = val3;
+			_scrollBorderB = val4;
+		} else {
+			_scrollSpeed = val1;
+			_scrollCutoff = val2;
+			_scrollSpeedReduce = val3;
+		}
+		vm->EAX.setVal(1);
+	} break;
+
 	default:
 		warning("Call Dispatcher %d", funcID);
 		vm->EAX.setVal(0);
@@ -3992,6 +4132,18 @@ Common::String GamosEngine::gamos_itoa(int n, uint radix) {
 	return tmp;
 }
 
+
+bool GamosEngine::FUN_0040705c(int a, int b) {
+	static const int arr[8] = {0, 7, 6, 5, 4, 3, 2, 1};
+	int v = DAT_004173ec;
+	if (v > 3) {
+		v -= 4;
+		a = arr[a];
+	}
+
+	return ((a + v * 2) & 7) == b;
+}
+
 int GamosEngine::txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
 	if (memtype != VM::REF_EDI) {
 		error("Unsupported memtype");
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 29d29d9ce0e..dae32dd0132 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -379,6 +379,8 @@ private:
 
 	bool _midiStarted = false;
 
+	uint8 DAT_004173ec = 0;
+
 	/* Data2 */
 
 	Common::String _stateExt;
@@ -669,6 +671,7 @@ protected:
 
 
 	void FUN_004025d0();
+	bool FUN_0040705c(int a, int b);
 
 	int txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y);
 	void txtInputProcess(uint8 c);


Commit: 66a24c1831c63d9619873d4a979bdd465121e703
    https://github.com/scummvm/scummvm/commit/66a24c1831c63d9619873d4a979bdd465121e703
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:47+01:00

Commit Message:
GAMOS: Add additional scripts into dumpfile

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index f17c4fedc40..41e2d9fb33b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -4381,11 +4381,26 @@ void GamosEngine::dumpActions() {
 
 		i++;
 	}
+
+	i = 0;
+	for (const Actions &act : _subtitleActions) {
+		if (act.flags & Actions::HAS_CONDITION) {
+			t = VM::disassembly(act.conditionAddress);
+			f.writeString(Common::String::format("SubAct %d condition : \n%s\n", i, t.c_str()));
+		}
+
+		if (act.flags & Actions::HAS_FUNCTION) {
+			t = VM::disassembly(act.functionAddress);
+			f.writeString(Common::String::format("SubAct %d action : \n%s\n", i, t.c_str()));
+		}
+
+		i++;
+	}
+
 	f.flush();
 	f.close();
 
 	warning("Actions saved into actions_%d.txt", _currentModuleID);
 }
 
-
 } // End of namespace Gamos


Commit: 623cad8a53425ee12631c3f8c80903765ac8ca99
    https://github.com/scummvm/scummvm/commit/623cad8a53425ee12631c3f8c80903765ac8ca99
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:48+01:00

Commit Message:
GAMOS: Add flip-flop demo detection

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 9efb70a5dec..ef7bf9d61f2 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -27,6 +27,8 @@ const PlainGameDescriptor gamosGames[] = {
 	{ "pilots", "Pilots 1" },
 	{ "pilots2", "Pilots 2" },
 	{ "wild", "WildSnakes"},
+	{ "flop", "Flip-Flop"},
+	{ "it", "IT"},
 	{ 0, 0 }
 };
 
@@ -83,6 +85,19 @@ const GamosGameDescription gameDescriptions[] = {
 		"wildus.exe",
 		0x80000018
 	},
+	{
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("FFLOPRD.EXE", "82d5b8a9d442bcec25c3401b4f7c0f9e", 4637680),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"FFLOPRD.EXE",
+		0x80000016
+	},
 	{
 		AD_TABLE_END_MARKER,
 		"",


Commit: 992948abb58dbcbde0667ccf785ee48d9e5ce762
    https://github.com/scummvm/scummvm/commit/992948abb58dbcbde0667ccf785ee48d9e5ce762
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:48+01:00

Commit Message:
GAMOS: Fix flip-flop demo crash on negative index

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 41e2d9fb33b..808bce90269 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -3313,7 +3313,7 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 	PTR_00417218->fld_3 |= 2;
 
 	while (true) {
-		byte ib = vm->getMem8(memtype, offset);
+		uint8 ib = vm->getMem8(memtype, offset);
 		offset++;
 
 		if (ib == 0)
@@ -3376,7 +3376,7 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 					}
 
 					for (int i = 0; i < tmp.size(); i++) {
-						addSubtitleImage(tmp[i], sprId, &x, y);
+						addSubtitleImage((uint8)tmp[i], sprId, &x, y);
 					}
 				}
 			}
@@ -3387,7 +3387,7 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 
 }
 
-Object *GamosEngine::addSubtitleImage(int32 frame, int32 spr, int32 *pX, int32 y) {
+Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y) {
 	Object *obj = getFreeObject();
 	obj->flags |= 0xe0;
 	obj->actID = 0;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index dae32dd0132..46480ed382c 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -650,7 +650,7 @@ protected:
 		VM::_interrupt = true;
 	};
 
-	Object *addSubtitleImage(int32 seq, int32 spr, int32 *pX, int32 y);
+	Object *addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y);
 	void addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
 
 	void FUN_00407db8(uint8 p);


Commit: f5f8d0b9bbafb756d303353f424323fbaaf723ee
    https://github.com/scummvm/scummvm/commit/f5f8d0b9bbafb756d303353f424323fbaaf723ee
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:48+01:00

Commit Message:
GAMOS: Implement missing function for flip-flop

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 808bce90269..13fb50060d8 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2468,13 +2468,13 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 
 	case 28:
 		arg1 = vm->pop32();
-		//FUN_0040279c(arg1, false);
+		FUN_0040279c(arg1, false);
 		vm->EAX.setVal(1);
 		break;
 
 	case 29:
 		arg1 = vm->pop32();
-		//FUN_0040279c(arg1, true);
+		FUN_0040279c(arg1, true);
 		vm->EAX.setVal(1);
 		break;
 
@@ -3952,6 +3952,18 @@ void Actions::parse(const byte *data, size_t dataSize) {
 	}
 }
 
+void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
+	FUN_004025d0();
+
+	if (rnd)
+		val = _thing2[val].field_1[ 1 + rndRange16(_thing2[val].field_1[0]) ];
+
+	PTR_00417218->fld_2 = val;
+	PTR_00417218->fld_3 = 0x10;
+
+	ObjectAction &act = _objectActions[val];
+	executeScript(1, PTR_00417218->blk, PTR_00417218->pos, nullptr, -1, nullptr, &act, act.onCreateAddress);
+}
 
 void GamosEngine::FUN_004025d0() {
 	if (PTR_00417218->fld_2 != 0xfe) {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 46480ed382c..2bf9d45f870 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -670,6 +670,7 @@ protected:
 	byte FUN_0040881c(const Common::Array<byte> &arr);
 
 
+	void FUN_0040279c(uint8 val, bool rnd);
 	void FUN_004025d0();
 	bool FUN_0040705c(int a, int b);
 


Commit: 2ef840759b9b949128833b116382d61392ef8610
    https://github.com/scummvm/scummvm/commit/2ef840759b9b949128833b116382d61392ef8610
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:49+01:00

Commit Message:
GAMOS: Fix for incorrect generation in IT

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 13fb50060d8..d664240b528 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1710,7 +1710,7 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 		if (!unk1.field_2.empty()) {
 			byte id1 = e.t;
 			e.t = unk1.field_2[ oid ] >> 4;
-			preprocessData(8 + e.t, &e);
+			preprocessData(8 + id1, &e);
 		}
 	}
 


Commit: aec2ef12751ee9e8cca6e076204ff55863ddbc01
    https://github.com/scummvm/scummvm/commit/aec2ef12751ee9e8cca6e076204ff55863ddbc01
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:49+01:00

Commit Message:
GAMOS: Fix wrong assignment

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index d664240b528..1e7ffb287ef 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1406,7 +1406,6 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 			switch (ate.t) {
 			case 0: {
 				uint16 rndval = rndRange16(a.num_act_10e);
-				rnd();
 				for (ActEntry e : a.act_10end[rndval]) {
 					retval += processData(e, absolute);
 					if (_needReload)
@@ -1988,10 +1987,10 @@ bool GamosEngine::FUN_00402fb4() {
 						bool tmp = false;
 						for (int i = 0; i < 8; i++) {
 							if ((PTR_00417214->unk1 >> 8) & (1 << i)) {
-								DAT_004173ec = ((i & 3) + ivr8) & 3;
 								int fncid = ((i & 3) + ivr8) & 3;
 								if (i > 3)
 									fncid += 4;
+								DAT_004173ec = fncid;
 
 								DAT_004177ff = false;
 								_preprocDataId = fncid;


Commit: 08239376d9e0cf68420eedb9f1a356ea87872597
    https://github.com/scummvm/scummvm/commit/08239376d9e0cf68420eedb9f1a356ea87872597
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:49+01:00

Commit Message:
GAMOS: Allow games to quit

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 1e7ffb287ef..32307e58144 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1222,39 +1222,42 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 	FUN_00402c2c(mouseMove, actPos, act2, act1);
 	changeVolume();
-	if (FUN_00402bc4()) {
-		bool loop = false;
-		if (!_txtInputActive)
-			loop = FUN_00402fb4();
-		else
-		    loop = onTxtInputUpdate(act2);
 
-		if (_needReload)
-			return 2;  // rerun update after loadModule
+	if (!FUN_00402bc4())
+		return 0;
 
-		while (loop) {
-			if (!PTR_00417388) {
-				if (updateMouseCursor(mouseMove) && scrollAndDraw())
-					return 1;
-				else
-					return 0;
-			}
+	bool loop = false;
+	if (!_txtInputActive)
+		loop = FUN_00402fb4();
+	else
+		loop = onTxtInputUpdate(act2);
 
-			RawKeyCode = ACT_NONE;
+	if (_needReload)
+		return 2;  // rerun update after loadModule
 
-			if (!FUN_00402bc4())
+	while (loop) {
+		if (!PTR_00417388) {
+			if (updateMouseCursor(mouseMove) && scrollAndDraw())
+				return 1;
+			else
 				return 0;
+		}
 
-			if (!_txtInputActive)
-				loop = FUN_00402fb4();
-			else
-			    loop = onTxtInputUpdate(act2);
+		RawKeyCode = ACT_NONE;
 
-			if (_needReload)
-				return 2; // rerun update after loadModule
-		}
+		if (!FUN_00402bc4())
+			return 0;
+
+		if (!_txtInputActive)
+			loop = FUN_00402fb4();
+		else
+			loop = onTxtInputUpdate(act2);
+
+		if (_needReload)
+			return 2; // rerun update after loadModule
 	}
-	return 1;
+
+	return 0;
 }
 
 int32 GamosEngine::doActions(const Actions &a, bool absolute) {


Commit: 3d0d7f725319045bd0f7f741a838e073644f9d26
    https://github.com/scummvm/scummvm/commit/3d0d7f725319045bd0f7f741a838e073644f9d26
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:50+01:00

Commit Message:
GAMOS: Add detections and set right languages.

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index ef7bf9d61f2..519bba04f4f 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -38,7 +38,7 @@ const GamosGameDescription gameDescriptions[] = {
 			"solgamer",
 			0,
 			AD_ENTRY1s("solgamer.exe", "6049dd1645071da1b60cdd395e6999ba", 24658521),
-			Common::EN_ANY,
+			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
@@ -51,7 +51,7 @@ const GamosGameDescription gameDescriptions[] = {
 			"pilots",
 			0,
 			AD_ENTRY1s("pilots.exe", "152f751d3c1b325e91411dd75de54e95", 48357155),
-			Common::EN_ANY,
+			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
@@ -64,7 +64,7 @@ const GamosGameDescription gameDescriptions[] = {
 			"pilots2",
 			0,
 			AD_ENTRY1s("pilots2.exe", "a0353dfb46043d1b2d1ef8ab6c204b33", 582283983),
-			Common::EN_ANY,
+			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
@@ -90,7 +90,7 @@ const GamosGameDescription gameDescriptions[] = {
 			"flop",
 			0,
 			AD_ENTRY1s("FFLOPRD.EXE", "82d5b8a9d442bcec25c3401b4f7c0f9e", 4637680),
-			Common::EN_ANY,
+			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
@@ -98,6 +98,32 @@ const GamosGameDescription gameDescriptions[] = {
 		"FFLOPRD.EXE",
 		0x80000016
 	},
+	{
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("FFLOPE.EXE", "6049dd1645071da1b60cdd395e6999ba", 4633340),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"FFLOPE.EXE",
+		0x80000018
+	},
+	{
+		{
+			"it",
+			0,
+			AD_ENTRY1s("IT.EXE", "82d5b8a9d442bcec25c3401b4f7c0f9e", 4125894),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"IT.EXE",
+		0x80000016
+	},
 	{
 		AD_TABLE_END_MARKER,
 		"",


Commit: 40026e73e8eee3afee94c30433ff4edd71a5601b
    https://github.com/scummvm/scummvm/commit/40026e73e8eee3afee94c30433ff4edd71a5601b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:50+01:00

Commit Message:
GAMOS: Silence debug warning

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 32307e58144..33d5ddf8e05 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -497,7 +497,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		_objectActions[pid].actions[p1].functionAddress = _loadedDataSize + p3;
 		//warning("RESTP_2C %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
-		warning("Data 38 size %zu", dataSize);
+		//warning("Data 38 size %zu", dataSize);
 		_thing2[pid].field_0.assign(data, data + dataSize);
 	} else if (tp == RESTP_39) {
 		_thing2[pid].field_1.assign(data, data + dataSize);


Commit: 8f7876d90684e8b035a9e4416d9020d7f282a8a3
    https://github.com/scummvm/scummvm/commit/8f7876d90684e8b035a9e4416d9020d7f282a8a3
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:50+01:00

Commit Message:
GAMOS: Implement avi file playing

Changed paths:
  A engines/gamos/video.cpp
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/module.mk


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 33d5ddf8e05..4c3f5935196 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -595,11 +595,10 @@ bool GamosEngine::initMainDatas() {
 	_fadeEffectID = dataStream.readByte();
 	_unk11 = dataStream.readByte();
 
-	/*_winX = dataStream.readUint32LE();
-	_winY = dataStream.readUint32LE();
-	_winW = dataStream.readUint32LE();
-	_winH = dataStream.readUint32LE();*/
-	dataStream.skip(16);
+	_introPos.x = dataStream.readSint32LE();
+	_introPos.y = dataStream.readSint32LE();
+	_introSize.x = dataStream.readSint32LE();
+	_introSize.y = dataStream.readSint32LE();
 
 	int64 pos = dataStream.pos();
 	_string1 = dataStream.readString(0, 64);
@@ -633,6 +632,8 @@ bool GamosEngine::init(const Common::String &moduleName) {
 	_sndVolumeTarget = _savedSndVolume;
 	_midiVolumeTarget = _savedMidiVolume;
 
+	playVideo("intro", _introPos, _introSize);
+
 	if (!playIntro())
 		return false;
 
@@ -983,7 +984,7 @@ void GamosEngine::flushDirtyRects(bool apply) {
 	FUN_0040255c(nullptr);
 }
 
-bool GamosEngine::usePalette(byte *pal, int num, int fade, bool winColors) {
+bool GamosEngine::usePalette(const byte *pal, int num, int fade, bool winColors) {
 
 	static const byte winColorMap[20][3] = {
 		/* r     g     b */
@@ -2884,6 +2885,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	case 55: {
 		VM::ValAddr regRef = vm->popReg(); //implement
 		Common::String str = vm->getString(regRef);
+
+		char buffer[256];
+		int a = 0, b = 0, c = 0, d = 0;
+		sscanf(str.c_str(), "%s %d %d %d %d", buffer, &a, &b, &c, &d);
+
+		playVideo(Common::String(buffer), Common::Point(a, b), Common::Point(c, d));
 		warning("PlayMovie 55: %s", str.c_str());
 		vm->EAX.setVal(1);
 	}
@@ -4351,6 +4358,21 @@ bool GamosEngine::onTxtInputUpdate(uint8 c) {
 	return true;
 }
 
+bool GamosEngine::eventsSkip(bool breakOnInput) {
+	bool brk = false;
+	Common::Event e;
+	while(_system->getEventManager()->pollEvent(e)) {
+		if (breakOnInput){
+			if (e.type == Common::EVENT_LBUTTONUP ||
+				e.type == Common::EVENT_RBUTTONUP ||
+				e.type == Common::EVENT_KEYUP)
+				brk = true;
+		}
+	}
+
+	return shouldQuit() || brk;
+}
+
 
 void GamosEngine::dumpActions() {
 	Common::String t = Common::String::format("./actions_%d.txt", _currentModuleID);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 2bf9d45f870..5c0a747c57f 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -332,6 +332,8 @@ private:
 	bool _onlyScanImage = false;
 	int32 _resReadOffset = 0;
 
+	Common::Point _introPos;
+	Common::Point _introSize;
 	Common::String _string1;
 	Common::String _winCaption;
 
@@ -625,7 +627,7 @@ protected:
 	void doDraw();
 	void flushDirtyRects(bool apply);
 
-	bool usePalette(byte *pal, int num, int fade, bool winColors);
+	bool usePalette(const byte *pal, int num, int fade, bool winColors);
 	bool setPaletteCurrentGS();
 
 	bool loadImage(Image *img);
@@ -707,6 +709,15 @@ protected:
 
 	static Common::String gamos_itoa(int value, uint radix);
 
+
+
+	/* video */
+	void playVideo(const Common::String &video, const Common::Point &pos, const Common::Point &size);
+	void surfacePaletteRemap(Graphics::Surface *dst, const byte *tgtPalette, const Graphics::Surface *src, const byte *srcPalette, int srcCount);
+
+	/* skip events */
+	bool eventsSkip(bool breakOnInput = false);
+
 public:
 
 	inline void rndSeed(uint32 seed) {
diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
index 12d61e3e61e..a02d527d4f9 100644
--- a/engines/gamos/module.mk
+++ b/engines/gamos/module.mk
@@ -11,7 +11,8 @@ MODULE_OBJS = \
 	proc.o \
 	movie.o \
 	saveload.o \
-	vm.o
+	vm.o \
+	video.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_GAMOS), DYNAMIC_PLUGIN)
diff --git a/engines/gamos/video.cpp b/engines/gamos/video.cpp
new file mode 100644
index 00000000000..cc498b66503
--- /dev/null
+++ b/engines/gamos/video.cpp
@@ -0,0 +1,144 @@
+/* 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 "gamos/gamos.h"
+#include "image/bmp.h"
+#include "video/avi_decoder.h"
+
+namespace Gamos {
+
+void GamosEngine::surfacePaletteRemap(Graphics::Surface *dst, const byte *tgtPalette, const Graphics::Surface *src, const byte *srcPalette, int srcColorCount) {
+    byte remap[256];
+    Graphics::PaletteLookup ptgt(tgtPalette, 256);
+
+    const byte *psrc = srcPalette;
+    for (int i = 0; i < srcColorCount; i++) {
+        remap[i] = ptgt.findBestColor(psrc[0], psrc[1], psrc[2]);
+        psrc += 3;
+    }
+
+    for (int y = 0; y < dst->h; y++) {
+        byte *bdst = (byte *)dst->getBasePtr(0, y);
+        const byte *bsrc = (const byte *)src->getBasePtr(0, y);
+        for (int x = 0; x < dst->w; x++) {
+            *bdst = remap[*bsrc];
+            bdst++;
+            bsrc++;
+        }
+    }
+}
+
+void GamosEngine::playVideo(const Common::String &video, const Common::Point &pos, const Common::Point &size) {
+    if (shouldQuit())
+        return;
+
+    Common::Path bmpPath(_string1 + '/' + video + ".bmp", '/');
+    Common::Path aviPath(_string1 + '/' + video + ".avi", '/');
+
+
+    const Graphics::Surface *bkg = nullptr;
+    const byte *bkgPalette = nullptr;
+    int bkgPaletteCount = 0;
+
+    ::Image::BitmapDecoder bmp;
+
+    Graphics::Surface screenCopy;
+    Common::Array<byte> screenPalette;
+
+    bool isAllocated = false;
+
+
+    if (!SearchMan.hasFile(aviPath))
+        return;
+
+    if (SearchMan.hasFile(bmpPath)) {
+        Common::File f;
+        if (f.open(bmpPath)) {
+            bmp.loadStream(f);
+            f.close();
+
+            bkg = bmp.getSurface();
+            bkgPalette = bmp.getPalette();
+            bkgPaletteCount = bmp.getPaletteColorCount();
+        } else {
+            screenCopy.copyFrom( *_screen->surfacePtr() );
+            bkg = &screenCopy;
+
+            screenPalette.resize(3 * 256);
+            _screen->getPalette( screenPalette.data() );
+
+            bkgPalette = screenPalette.data();
+            bkgPaletteCount = 256;
+
+            isAllocated = true;
+        }
+    }
+
+    Common::File *avifile = new Common::File();
+    if (!avifile->open(aviPath)) {
+        delete avifile;
+        return;
+    }
+
+    Video::AVIDecoder avi;
+    avi.loadStream(avifile);
+    avi.start();
+
+    Common::Point sz = size;
+    if (sz.x <= 0 || sz.y <= 0) {
+        sz.x = avi.getWidth();
+        sz.y = avi.getHeight();
+    }
+
+    Common::Event e;
+    while ( !avi.endOfVideo() ) {
+        if (eventsSkip(true))
+            break;
+
+        if (avi.needsUpdate()) {
+            const Graphics::Surface *frm = avi.decodeNextFrame();
+            if (avi.hasDirtyPalette()) {
+                _screen->setPalette(avi.getPalette());
+                surfacePaletteRemap(_screen->surfacePtr(), avi.getPalette(), bkg, bkgPalette, bkgPaletteCount);
+                _screen->markAllDirty();
+            }
+            if (frm) {
+                _screen->blitFrom(*frm, Common::Rect(sz.x, sz.y), pos);
+                _screen->addDirtyRect(Common::Rect(pos, sz.x, sz.y));
+                _screen->update();
+            }
+        } else {
+            _system->updateScreen();
+        }
+
+        _system->delayMillis(1);
+    }
+
+    avi.stop();
+
+    setPaletteCurrentGS();
+    if (isAllocated) {
+        screenCopy.free();
+        screenPalette.clear();
+    }
+}
+
+};


Commit: b58a124d3c5f045552a88780543a8375ec7815c5
    https://github.com/scummvm/scummvm/commit/b58a124d3c5f045552a88780543a8375ec7815c5
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:51+01:00

Commit Message:
GAMOS: Update fade in/out code with event update loop

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 4c3f5935196..a33eee7a6b6 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -931,7 +931,7 @@ void GamosEngine::updateScreen(bool checkers, const Common::Rect &rect) {
 	if (_width == 0 || _height == 0)
 		return;
 
-	if (!checkers) {
+	if (!checkers || shouldQuit()) {
 		_screen->addDirtyRect(rect);
 		return;
 	}
@@ -958,10 +958,18 @@ void GamosEngine::updateScreen(bool checkers, const Common::Rect &rect) {
 			}
 		}
 		_screen->update();
-		val = _system->getMillis() - val;
 
-		if (val < maxDelay)
-			_system->delayMillis(maxDelay - val);
+		while (_system->getMillis() - val < maxDelay) {
+			_system->delayMillis(1);
+
+			if (eventsSkip()) {
+				_screen->addDirtyRect(rect);
+				_screen->update();
+				return;
+			} else {
+				_system->updateScreen();
+			}
+		}
 	}
 }
 
@@ -1015,7 +1023,7 @@ bool GamosEngine::usePalette(const byte *pal, int num, int fade, bool winColors)
 		return false;
 
 	if (_width != 0 && _height != 0) {
-		if (fade == 0) {
+		if (fade == 0 || shouldQuit()) {
 			uint16 color = _screen->getPalette().findBestColor(0, 0, 0);
 			_screen->fillRect(_screen->getBounds(), color);
 			_screen->update();
@@ -1042,10 +1050,20 @@ bool GamosEngine::usePalette(const byte *pal, int num, int fade, bool winColors)
 					_screen->drawLine(0, i, _screen->w - 1, i, color);
 
 				_screen->update();
-				val = _system->getMillis() - val;
 
-				if (val < maxDelay)
-					_system->delayMillis(maxDelay - val);
+				while (_system->getMillis() - val < maxDelay) {
+					_system->delayMillis(1);
+
+					if (eventsSkip()) {
+						j = 8;
+						uint16 color = _screen->getPalette().findBestColor(0, 0, 0);
+						_screen->fillRect(_screen->getBounds(), color);
+						_screen->update();
+						break;
+					} else {
+						_system->updateScreen();
+					}
+				}
 			}
 		}
 	}


Commit: d4d42b1c7d1c56325124ee3019f74a549bb36fe8
    https://github.com/scummvm/scummvm/commit/d4d42b1c7d1c56325124ee3019f74a549bb36fe8
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:51+01:00

Commit Message:
GAMOS: Fix video without bkg image

Changed paths:
    engines/gamos/video.cpp


diff --git a/engines/gamos/video.cpp b/engines/gamos/video.cpp
index cc498b66503..7d14fc3218f 100644
--- a/engines/gamos/video.cpp
+++ b/engines/gamos/video.cpp
@@ -69,6 +69,8 @@ void GamosEngine::playVideo(const Common::String &video, const Common::Point &po
     if (!SearchMan.hasFile(aviPath))
         return;
 
+    bool loadbkg = false;
+
     if (SearchMan.hasFile(bmpPath)) {
         Common::File f;
         if (f.open(bmpPath)) {
@@ -78,18 +80,21 @@ void GamosEngine::playVideo(const Common::String &video, const Common::Point &po
             bkg = bmp.getSurface();
             bkgPalette = bmp.getPalette();
             bkgPaletteCount = bmp.getPaletteColorCount();
-        } else {
-            screenCopy.copyFrom( *_screen->surfacePtr() );
-            bkg = &screenCopy;
+            loadbkg = true;
+        }
+    }
 
-            screenPalette.resize(3 * 256);
-            _screen->getPalette( screenPalette.data() );
+    if (!loadbkg) {
+        screenCopy.copyFrom( *_screen->surfacePtr() );
+        bkg = &screenCopy;
 
-            bkgPalette = screenPalette.data();
-            bkgPaletteCount = 256;
+        screenPalette.resize(3 * 256);
+        _screen->getPalette( screenPalette.data() );
 
-            isAllocated = true;
-        }
+        bkgPalette = screenPalette.data();
+        bkgPaletteCount = 256;
+
+        isAllocated = true;
     }
 
     Common::File *avifile = new Common::File();


Commit: f32b7f1301e3e700d765d0908b4c1d4369b6021b
    https://github.com/scummvm/scummvm/commit/f32b7f1301e3e700d765d0908b4c1d4369b6021b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:51+01:00

Commit Message:
GAMOS: Implement stopSounds method

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index a33eee7a6b6..716d3b89888 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -718,7 +718,6 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_midiTracks.clear();
 	_midiTracks.resize(midiCount);
 
-	_mixer->stopAll();
 	_soundSamples.clear();
 	_soundSamples.resize(soundCount);
 
@@ -910,11 +909,11 @@ void GamosEngine::stopMidi() {
 }
 
 void GamosEngine::stopMCI() {
-	warning("Not implemented stopMCI");
+	//warning("Not implemented stopMCI");
 }
 
 void GamosEngine::stopSounds() {
-	warning("Not implemented stopSounds");
+	_mixer->stopAll();
 }
 
 


Commit: 24cd181d99304c23910c1cde46b39ebdd0494a6b
    https://github.com/scummvm/scummvm/commit/24cd181d99304c23910c1cde46b39ebdd0494a6b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:52+01:00

Commit Message:
GAMOS: Stop sounds on video play and resume midi

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 716d3b89888..43f8c85ac45 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2905,10 +2905,20 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 
 		char buffer[256];
 		int a = 0, b = 0, c = 0, d = 0;
-		sscanf(str.c_str(), "%s %d %d %d %d", buffer, &a, &b, &c, &d);
+		if ( sscanf(str.c_str(), "%s %d %d %d %d", buffer, &a, &b, &c, &d) > 0) {
+			stopMidi();
+			stopSounds();
 
-		playVideo(Common::String(buffer), Common::Point(a, b), Common::Point(c, d));
-		warning("PlayMovie 55: %s", str.c_str());
+			playVideo(Common::String(buffer), Common::Point(a, b), Common::Point(c, d));
+
+			if (_d2_fld19 != 0xff) {
+				/* vm func 58 */
+			}
+
+			if (_midiTrack != -1) {
+				scriptFunc16(_midiTrack);
+			}
+		}
 		vm->EAX.setVal(1);
 	}
 	break;


Commit: 5692d57c281a8cd196c2aeccecdd63ba78ac6daa
    https://github.com/scummvm/scummvm/commit/5692d57c281a8cd196c2aeccecdd63ba78ac6daa
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:52+01:00

Commit Message:
GAMOS: Set video dithering if video not 8bit with palette (pilots 1 final avi)

Changed paths:
    engines/gamos/video.cpp


diff --git a/engines/gamos/video.cpp b/engines/gamos/video.cpp
index 7d14fc3218f..284acf378e7 100644
--- a/engines/gamos/video.cpp
+++ b/engines/gamos/video.cpp
@@ -113,6 +113,18 @@ void GamosEngine::playVideo(const Common::String &video, const Common::Point &po
         sz.y = avi.getHeight();
     }
 
+    bool dither = false;
+    if (avi.getPixelFormat().bytesPerPixel != 1) {
+        if (loadbkg) {
+            usePalette(bkgPalette, bkgPaletteCount, 0, true);
+            _screen->copyFrom(*bkg);
+            _screen->markAllDirty();
+        }
+
+        avi.setDitheringPalette(_screen->getPalette().data());
+        dither = true;
+    }
+
     Common::Event e;
     while ( !avi.endOfVideo() ) {
         if (eventsSkip(true))
@@ -120,7 +132,7 @@ void GamosEngine::playVideo(const Common::String &video, const Common::Point &po
 
         if (avi.needsUpdate()) {
             const Graphics::Surface *frm = avi.decodeNextFrame();
-            if (avi.hasDirtyPalette()) {
+            if (!dither && avi.hasDirtyPalette()) {
                 _screen->setPalette(avi.getPalette());
                 surfacePaletteRemap(_screen->surfacePtr(), avi.getPalette(), bkg, bkgPalette, bkgPaletteCount);
                 _screen->markAllDirty();


Commit: c096938d66e2d4c7e2964e81dae1174e798ba459
    https://github.com/scummvm/scummvm/commit/c096938d66e2d4c7e2964e81dae1174e798ba459
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:53+01:00

Commit Message:
GAMOS: Do not add empty key into seq

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 43f8c85ac45..eb1182ca053 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1231,7 +1231,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 
 	RawKeyCode = keyCode;
 
-	if (RawKeyCode != ACT_NONE) {
+	if (RawKeyCode != 0 && RawKeyCode != ACT_NONE) {
 		if (_keySeq.size() >= 32)
 			_keySeq = _keySeq.substr(_keySeq.size() - 31);
 


Commit: 37eed7077969d5f566798af5c918ff1f0ab284c3
    https://github.com/scummvm/scummvm/commit/37eed7077969d5f566798af5c918ff1f0ab284c3
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:53+01:00

Commit Message:
GAMOS: Silence debug message

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index eb1182ca053..afef0030ceb 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1100,7 +1100,7 @@ bool GamosEngine::setPaletteCurrentGS() {
 void GamosEngine::readData2(const RawData &data) {
 	Common::MemoryReadStream dataStream(data.data(), data.size());
 
-	warning("Game data size %d", data.size());
+	//warning("Game data size %d", data.size());
 
 	if (getEngineVersion() == 0x80000018) {
 		_stateExt = dataStream.readString(0, 4); // FIX ME


Commit: b0c3d455450d203cbc8010cd512c8c43699e4007
    https://github.com/scummvm/scummvm/commit/b0c3d455450d203cbc8010cd512c8c43699e4007
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:53+01:00

Commit Message:
GAMOS: Delete unused stack structure and add comments for undefined pointer

Changed paths:
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index ac8eff00a95..ac20fa4b8e3 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -496,7 +496,7 @@ uint32 VM::getMem32(int memtype, uint32 offset) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
-		return 0;
+		return 0; // Set here breakpoint for find what is going wrong
 
 	case REF_STACK:
 		return getU32(_stack + offset);
@@ -517,7 +517,7 @@ uint8 VM::getMem8(int memtype, uint32 offset) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
-		return 0;
+		return 0; // Set here breakpoint for find what is going wrong
 
 	case REF_STACK:
 		return _stack[offset];
@@ -538,7 +538,7 @@ void VM::setMem32(int memtype, uint32 offset, uint32 val) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
-		break;
+		break; // Set here breakpoint for find what is going wrong
 	case REF_STACK:
 		setU32(_stack + offset, val);
 		break;
@@ -560,7 +560,7 @@ void VM::setMem8(int memtype, uint32 offset, uint8 val) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
-		break;
+		break; // Set here breakpoint for find what is going wrong
 	case REF_STACK:
 		_stack[offset] = val;
 		break;
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index 1d052e49da7..e1a11c56c31 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -214,7 +214,6 @@ public:
     ValAddr ECX;
     uint32 SP = 0;
     byte _stack[STACK_SIZE];
-    byte _stackT[STACK_SIZE];
 
 private:
     MemAccess _readAccess;


Commit: c71f4b8bc8516e6b8f3fcdf4358aab5f50d2a5c2
    https://github.com/scummvm/scummvm/commit/c71f4b8bc8516e6b8f3fcdf4358aab5f50d2a5c2
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:54+01:00

Commit Message:
GAMOS: Fix incorrect blitting functions

Changed paths:
    engines/gamos/blit.cpp


diff --git a/engines/gamos/blit.cpp b/engines/gamos/blit.cpp
index 21cd1e42413..f79796739b7 100644
--- a/engines/gamos/blit.cpp
+++ b/engines/gamos/blit.cpp
@@ -35,18 +35,16 @@ void Blitter::blitNormal(Graphics::Surface *src, const Common::Rect &srcRect, Gr
 
 	drect.clip(dst->w, dst->h);
 
-	Common::Rect srect = srcRect;
-	srect.translate(dstRect.left, dstRect.top);
-	srect.clip(drect);
+	Common::Rect proj(dstRect.origin(), srcRect.width(), srcRect.height());
+	proj.clip(drect);
 
-	drect = srect;
-	srect.translate(-dstRect.left, -dstRect.top);
-
-	if (srect.isEmpty())
+	if (proj.isEmpty())
 		return;
 
+	Common::Rect srect(srcRect.origin() + proj.origin() - dstRect.origin(), proj.width(), proj.height());
+
 	for (int y = 0; y < srect.height(); y++) {
-		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
+		byte *pdst = (byte *)dst->getBasePtr(proj.left, proj.top + y);
 		byte *psrc = (byte *)src->getBasePtr(srect.left, srect.top + y);
 		for (int x = srect.left; x < srect.right; x++) {
 			if (*psrc != 0)
@@ -71,19 +69,19 @@ void Blitter::blitFlipH(Graphics::Surface *src, const Common::Rect &srcRect, Gra
 
 	drect.clip(dst->w, dst->h);
 
-	Common::Rect srect = srcRect;
-	srect.translate(dstRect.left, dstRect.top);
-	srect.clip(drect);
+	Common::Rect proj(dstRect.origin(), srcRect.width(), srcRect.height());
+	proj.clip(drect);
 
-	drect = srect;
-	srect.translate(-dstRect.left, -dstRect.top);
-
-	if (srect.isEmpty())
+	if (proj.isEmpty())
 		return;
 
-	for (int y = srect.top; y < srect.bottom; y++) {
-		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-		byte *psrc = (byte *)src->getBasePtr(srect.right - 1, y);
+	Common::Rect srect(srcRect.origin() + proj.origin() - dstRect.origin(), proj.width(), proj.height());
+
+	int32 sw = src->w;
+
+	for (int y = 0; y < srect.height(); y++) {
+		byte *pdst = (byte *)dst->getBasePtr(proj.left, proj.top + y);
+		byte *psrc = (byte *)src->getBasePtr(sw - 1 - srect.left, srect.top + y);
 		for (int x = srect.left; x < srect.right; x++) {
 			if (*psrc != 0)
 				*pdst = *psrc;
@@ -106,19 +104,19 @@ void Blitter::blitFlipV(Graphics::Surface *src, const Common::Rect &srcRect, Gra
 
 	drect.clip(dst->w, dst->h);
 
-	Common::Rect srect = srcRect;
-	srect.translate(dstRect.left, dstRect.top);
-	srect.clip(drect);
-
-	drect = srect;
-	srect.translate(-dstRect.left, -dstRect.top);
+	Common::Rect proj(dstRect.origin(), srcRect.width(), srcRect.height());
+	proj.clip(drect);
 
-	if (srect.isEmpty())
+	if (proj.isEmpty())
 		return;
 
-	for (int y = srect.top; y < srect.bottom; y++) {
-		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-		byte *psrc = (byte *)src->getBasePtr(srect.left, srect.bottom - 1 - y);
+	Common::Rect srect(srcRect.origin() + proj.origin() - dstRect.origin(), proj.width(), proj.height());
+
+	int32 sh = src->h;
+
+	for (int y = 0; y < srect.height(); y++) {
+		byte *pdst = (byte *)dst->getBasePtr(proj.left, proj.top + y);
+		byte *psrc = (byte *)src->getBasePtr(srect.left, sh - 1 - srect.top - y);
 		for (int x = srect.left; x < srect.right; x++) {
 			if (*psrc != 0)
 				*pdst = *psrc;
@@ -141,19 +139,20 @@ void Blitter::blitFlipVH(Graphics::Surface *src, const Common::Rect &srcRect, Gr
 
 	drect.clip(dst->w, dst->h);
 
-	Common::Rect srect = srcRect;
-	srect.translate(dstRect.left, dstRect.top);
-	srect.clip(drect);
-
-	drect = srect;
-	srect.translate(-dstRect.left, -dstRect.top);
+	Common::Rect proj(dstRect.origin(), srcRect.width(), srcRect.height());
+	proj.clip(drect);
 
-	if (srect.isEmpty())
+	if (proj.isEmpty())
 		return;
 
-	for (int y = srect.top; y < srect.bottom; y++) {
-		byte *pdst = (byte *)dst->getBasePtr(drect.left, drect.top + y);
-		byte *psrc = (byte *)src->getBasePtr(srect.right - 1, srect.bottom - 1 - y);
+	Common::Rect srect(srcRect.origin() + proj.origin() - dstRect.origin(), proj.width(), proj.height());
+
+	int32 sw = src->w;
+	int32 sh = src->h;
+
+	for (int y = 0; y < srect.height(); y++) {
+		byte *pdst = (byte *)dst->getBasePtr(proj.left, proj.top + y);
+		byte *psrc = (byte *)src->getBasePtr(sw - 1 - srect.left, sh - 1 - srect.top - y);
 		for (int x = srect.left; x < srect.right; x++) {
 			if (*psrc != 0)
 				*pdst = *psrc;


Commit: 2d0f9a19a6afa173e977a34ce38f312ae1272d1f
    https://github.com/scummvm/scummvm/commit/2d0f9a19a6afa173e977a34ce38f312ae1272d1f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:54+01:00

Commit Message:
GAMOS: Redo doDraw to original form of game engine

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index afef0030ceb..869d6defe7c 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2143,8 +2143,8 @@ void GamosEngine::addDirtRectOnObject(Object *obj) {
 		rect.left -= imgPos->xoffset;
 		rect.top -= imgPos->yoffset;
 	}
-	rect.right = rect.left + imgPos->image->surface.w;
-	rect.bottom = rect.top + imgPos->image->surface.h;
+	rect.setWidth(imgPos->image->surface.w);
+	rect.setHeight(imgPos->image->surface.h);
 
 	addDirtyRect(rect);
 }
@@ -2158,6 +2158,7 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 	bool intersects = 0;
 	for (int i = 0; i < _dirtyRects.size(); i++) {
 		Common::Rect &r = _dirtyRects[i];
+
 		if (!rect.intersects(r))
 			continue;
 
@@ -2188,10 +2189,8 @@ rerunCheck:
 }
 
 void GamosEngine::doDraw() {
-	if (_dirtyRects.empty()) {
-		_screen->update();
+	if (_dirtyRects.empty())
 		return;
-	}
 
 	int32 bkg = _currentGameScreen;
 	if (bkg == -1)
@@ -2208,11 +2207,6 @@ void GamosEngine::doDraw() {
 		}
 	}
 
-	if (_unk9 == 0 /*&& */) {
-		/*drawList[cnt] = &_cursorObject;
-		cnt++;*/
-	}
-
 	drawList.resize(cnt);
 
 	if (cnt) {
@@ -2228,46 +2222,61 @@ void GamosEngine::doDraw() {
 		}
 	}
 
-	/* add mouse cursor here*/
-
 	for (int i = 0; i < _dirtyRects.size(); i++) {
-		Common::Rect &r = _dirtyRects[i];
+		Common::Rect r = _dirtyRects[i];
+
+		r.translate(-_scrollX, -_scrollY);
+		r.clip(_screen->getBounds());
+
+		if (r.isEmpty())
+			continue;
 
+		Common::Rect srcRect = r;
+		srcRect.translate(_scrollX, _scrollY);
+
+		/* update bkg at this rect */
 		if (_gameScreens[bkg].loaded) {
-			_screen->blitFrom(_gameScreens[bkg]._bkgImage, r, r);
+			_screen->blitFrom(_gameScreens[bkg]._bkgImage, srcRect, r.origin());
 		}
 
-		if (!_currentFade)
-			_screen->addDirtyRect(r);
-	}
+		for (Object *o : drawList) {
+			if (o->pImg && loadImage(o->pImg->image)) {
 
-	for (Object *o : drawList) {
-		/*if (o->pImg && loadImage(o->pImg->image)) {
-		    Common::Rect out(Common::Point(o->x, o->y), o->pImg->image->surface.w, o->pImg->image->surface.h);
-		    out.clip(_screen->getBounds());
-		    out.translate(-o->x, -o->y);
-		    _screen->copyRectToSurfaceWithKey(o->pImg->image->surface, o->x+out.left, o->y+out.top, out, 0);
-		}*/
-		if (o->pImg && loadImage(o->pImg->image)) {
-			uint flip = 0;
-			if (o->flags & 8)
-				flip |= Graphics::FLIP_H;
-			if (o->flags & 0x10)
-				flip |= Graphics::FLIP_V;
-			if (o->flags & 0x40) {
-				Blitter::blit(&o->pImg->image->surface,
-				              Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
-				              _screen->surfacePtr(),
-				              Common::Rect(o->x - o->pImg->xoffset, o->y - o->pImg->yoffset, _screen->w, _screen->h), flip);
-			} else {
-				Blitter::blit(&o->pImg->image->surface,
-				              Common::Rect(o->pImg->image->surface.w, o->pImg->image->surface.h),
-				              _screen->surfacePtr(),
-				              Common::Rect(o->x, o->y, o->x + o->pImg->image->surface.w, o->y + o->pImg->image->surface.h), flip);
+				Common::Rect s;
+				s.left = o->x - _scrollX;
+				s.top = o->y - _scrollY;
+
+				if (o->flags & 0x40) {
+					s.left -= o->pImg->xoffset;
+					s.top -= o->pImg->yoffset;
+				}
+
+				s.setWidth(o->pImg->image->surface.w);
+				s.setHeight(o->pImg->image->surface.h);
+
+				if (!s.intersects(r))
+					continue;
+
+				Common::Rect sdirt = s;
+				sdirt.clip(r);
+
+				Common::Rect ssrc(sdirt.origin() - s.origin(), sdirt.width(), sdirt.height());
+
+				uint flip = 0;
+				if (o->flags & 8)
+					flip |= Graphics::FLIP_H;
+				if (o->flags & 0x10)
+					flip |= Graphics::FLIP_V;
+
+				Blitter::blit(&o->pImg->image->surface, ssrc, _screen->surfacePtr(), sdirt, flip);
 			}
 		}
+
+		if (!_currentFade)
+			_screen->addDirtyRect(r);
 	}
 
+
 	if (_currentFade)
 		updateScreen(true, Common::Rect(_bkgSize.x, _bkgSize.y));
 


Commit: 597e2fe214db3180caf3602310cf60450b118d5a
    https://github.com/scummvm/scummvm/commit/597e2fe214db3180caf3602310cf60450b118d5a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:02:54+01:00

Commit Message:
GAMOS: Fix compilation

Changed paths:
    engines/gamos/video.cpp


diff --git a/engines/gamos/video.cpp b/engines/gamos/video.cpp
index 284acf378e7..522e8c8cce8 100644
--- a/engines/gamos/video.cpp
+++ b/engines/gamos/video.cpp
@@ -78,8 +78,8 @@ void GamosEngine::playVideo(const Common::String &video, const Common::Point &po
             f.close();
 
             bkg = bmp.getSurface();
-            bkgPalette = bmp.getPalette();
-            bkgPaletteCount = bmp.getPaletteColorCount();
+            bkgPalette = bmp.getPalette().data();
+            bkgPaletteCount = bmp.getPalette().size();
             loadbkg = true;
         }
     }


Commit: e8712f98be5fa2874de670a26d0ddf6bb67255ed
    https://github.com/scummvm/scummvm/commit/e8712f98be5fa2874de670a26d0ddf6bb67255ed
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:55+01:00

Commit Message:
GAMOS: Give names for object flags

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 869d6defe7c..b18abe16150 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1757,7 +1757,7 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 		if (_needReload)
 			return;
 		obj = getFreeObject();
-		obj->flags = (e.t << 4) | 3;
+		obj->flags = (e.t << 4) | Object::FLAG_VALID | Object::FLAG_HASACTION;
 		obj->actID = oid;
 		obj->fld_4 = 0;
 		obj->fld_5 = (act.unk1 >> 16) & 0xff;
@@ -1811,13 +1811,13 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 
 	for (uint i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
-		if (obj.flags & 1) {
-			if (obj.flags & 2) {
+		if (obj.flags & Object::FLAG_VALID) {
+			if (obj.flags & Object::FLAG_HASACTION) {
 				if (obj.pos == pos && obj.blk == id) {
 					removeObjectByIDMarkDirty(obj.y);
 					if (obj.y != obj.x)
 						removeObjectByIDMarkDirty(obj.x);
-					/* if (obj.flags & 8)
+					/* if (obj.flags & Object::FLAG_STORAGE)
 					    obj.storage.clear(); */
 					removeSubtitles(&obj);
 					removeObject(&obj);
@@ -1830,7 +1830,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 				}
 			} else {
 				if (mode && obj.fld_4 == pos && obj.fld_5 == id &&
-				        obj.pos == 0xff && obj.blk == 0xff && (obj.flags & 0x40) == 0) {
+				        obj.pos == 0xff && obj.blk == 0xff && (obj.flags & Object::FLAG_FREECOORDS) == 0) {
 
 					removeObjectMarkDirty(&obj);
 					if (multidel)
@@ -1852,7 +1852,7 @@ Object *GamosEngine::getFreeObject() {
 	Object *obj = nullptr;
 	for (uint i = 0; i < _objects.size(); i++) {
 		Object &rObj = _objects[i];
-		if ((rObj.flags & 1) == 0) {
+		if ((rObj.flags & Object::FLAG_VALID) == 0) {
 			obj = &rObj;
 			break;
 		}
@@ -1864,7 +1864,7 @@ Object *GamosEngine::getFreeObject() {
 		obj->index = _objects.size() - 1;
 	}
 
-	obj->flags = 1;
+	obj->flags = Object::FLAG_VALID;
 	obj->sprId = -1;
 	obj->seqId = -1;
 	obj->frame = -1;
@@ -1897,7 +1897,7 @@ void GamosEngine::removeObject(Object *obj) {
 }
 
 void GamosEngine::removeObjectMarkDirty(Object *obj) {
-	if (obj->flags & 0x80)
+	if (obj->flags & Object::FLAG_GRAPHIC)
 		addDirtRectOnObject(obj);
 	removeObject(obj);
 }
@@ -1951,17 +1951,17 @@ bool GamosEngine::FUN_00402fb4() {
 	for (int32 objIdx = pobj->index; objIdx < _objects.size(); objIdx++) {
 		pobj = &_objects[objIdx];
 
-		if ((pobj->flags & 3) == 3) {
+		if (pobj->isActionObject()) {
 			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7)))) {
 				if (pobj->fld_3 & 1) {
 					pobj->fld_3 &= ~1;
 				} else {
-					if ((pobj->flags & 4) == 0) {
+					if ((pobj->flags & Object::FLAG_TRANSITION) == 0) {
 						if (pobj->y != -1 && FUN_00402f34(true, false, &_objects[pobj->y])) {
 							pobj->y = pobj->x;
 							if (pobj->x != -1) {
 								Object &o = _objects[pobj->x];
-								o.flags |= 0x80;
+								o.flags |= Object::FLAG_GRAPHIC;
 								o.fld_4 = pobj->pos;
 								o.fld_5 = pobj->blk;
 								FUN_0040921c(&o);
@@ -1973,13 +1973,13 @@ bool GamosEngine::FUN_00402fb4() {
 							pobj->y = pobj->x;
 							if (pobj->x != -1) {
 								Object &o = _objects[pobj->x];
-								o.flags |= 0x80;
+								o.flags |= Object::FLAG_GRAPHIC;
 								o.fld_4 = pobj->pos;
 								o.fld_5 = pobj->blk;
 								FUN_0040921c(&o);
 								addDirtRectOnObject(&o);
 							}
-							pobj->flags &= ~4;
+							pobj->flags &= ~Object::FLAG_TRANSITION;
 						} else {
 							if (pobj == DAT_00412204) {
 								goto exit;
@@ -2059,7 +2059,7 @@ bool GamosEngine::FUN_00402fb4() {
 				}
 			}
 		} else {
-			if (!PTR_00417388 && (pobj->flags & 0x83) == 0x81 && pobj->pos == 0xff && pobj->blk == 0xff)
+			if (!PTR_00417388 && pobj->isGraphicObject() && pobj->pos == 0xff && pobj->blk == 0xff)
 				FUN_00402f34(true, false, pobj);
 		}
 continue_to_next_object:
@@ -2074,7 +2074,7 @@ exit:
 
 bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 	if (obj->fld_2 < 2) {
-		if (p2 || (obj->flags & 4)) {
+		if (p2 || (obj->flags & Object::FLAG_DIRTRECT)) {
 			addDirtRectOnObject(obj);
 			if (p1)
 				removeObject(obj);
@@ -2089,7 +2089,7 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 			obj->actID = 0;
 			obj->frame = 0;
 			obj->pImg = &_sprites[obj->sprId].sequences[obj->seqId]->operator[](obj->frame);
-			if (p2 || (obj->flags & 4)) {
+			if (p2 || (obj->flags & Object::FLAG_DIRTRECT)) {
 				addDirtRectOnObject(obj);
 				if (p1)
 					removeObject(obj);
@@ -2099,7 +2099,7 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 			obj->pImg = &_sprites[obj->sprId].sequences[obj->seqId]->operator[](obj->frame);
 		}
 
-		if ((obj->flags & 0x40) == 0)
+		if ((obj->flags & Object::FLAG_FREECOORDS) == 0)
 			FUN_0040921c(obj);
 
 		addDirtRectOnObject(obj);
@@ -2116,19 +2116,19 @@ void GamosEngine::FUN_0040921c(Object *obj) {
 
 	if (obj->pos != 255 && obj->blk != 255) {
 		Object *o = &_objects[(obj->blk * 0x100) + obj->pos];
-		if (o->flags & 4) {
+		if (o->flags & Object::FLAG_TRANSITION) {
 			int t = obj->frame + 1;
 			x += (o->pos - obj->fld_4) * _gridCellW * t / obj->fld_2;
 			y += (o->blk - obj->fld_5) * _gridCellH * t / obj->fld_2;
 		}
 	}
 
-	if (obj->flags & 8)
+	if (obj->flags & Object::FLAG_FLIPH)
 		obj->x = x - (img->surface.w - _gridCellW - imgPos->xoffset);
 	else
 		obj->x = x - imgPos->xoffset;
 
-	if (obj->flags & 0x10)
+	if (obj->flags & Object::FLAG_FLIPV)
 		obj->y = y - (img->surface.h - _gridCellH - imgPos->yoffset);
 	else
 		obj->y = y - imgPos->yoffset;
@@ -2139,7 +2139,7 @@ void GamosEngine::addDirtRectOnObject(Object *obj) {
 	Common::Rect rect;
 	rect.left = obj->x;
 	rect.top = obj->y;
-	if (obj->flags & 0x40) {
+	if (obj->flags & Object::FLAG_FREECOORDS) {
 		rect.left -= imgPos->xoffset;
 		rect.top -= imgPos->yoffset;
 	}
@@ -2201,7 +2201,7 @@ void GamosEngine::doDraw() {
 	int cnt = 0;
 	for (int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
-		if ((obj.flags & 0x83) == 0x81) {
+		if ( obj.isGraphicObject() ) {
 			drawList[cnt] = &obj;
 			cnt++;
 		}
@@ -2246,7 +2246,7 @@ void GamosEngine::doDraw() {
 				s.left = o->x - _scrollX;
 				s.top = o->y - _scrollY;
 
-				if (o->flags & 0x40) {
+				if (o->flags & Object::FLAG_FREECOORDS) {
 					s.left -= o->pImg->xoffset;
 					s.top -= o->pImg->yoffset;
 				}
@@ -2263,9 +2263,9 @@ void GamosEngine::doDraw() {
 				Common::Rect ssrc(sdirt.origin() - s.origin(), sdirt.width(), sdirt.height());
 
 				uint flip = 0;
-				if (o->flags & 8)
+				if (o->flags & Object::FLAG_FLIPH)
 					flip |= Graphics::FLIP_H;
-				if (o->flags & 0x10)
+				if (o->flags & Object::FLAG_FLIPV)
 					flip |= Graphics::FLIP_V;
 
 				Blitter::blit(&o->pImg->image->surface, ssrc, _screen->surfacePtr(), sdirt, flip);
@@ -3029,10 +3029,10 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 	Sprite &spr = _sprites[id];
 	Object *pobj = getFreeObject();
 
-	pobj->flags |= 0x80;
+	pobj->flags |= Object::FLAG_GRAPHIC;
 
 	if (spr.field_1 & 1)
-		pobj->flags |= 4;
+		pobj->flags |= Object::FLAG_DIRTRECT;
 
 	pobj->fld_2 = spr.field_3;
 	int32 idx = 0xffff;
@@ -3052,13 +3052,13 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 			if (PTR_00417218->y != -1) {
 				Object *oobj = &_objects[PTR_00417218->y];
 				addDirtRectOnObject(oobj);
-				oobj->flags &= 0x7f;
+				oobj->flags &= ~Object::FLAG_GRAPHIC;
 				if (PTR_00417218->x != PTR_00417218->y)
 					removeObject(oobj);
 			}
 
 			PTR_00417218->y = index;
-			if (!(pobj->flags & 4)) {
+			if (!(pobj->flags & Object::FLAG_DIRTRECT)) {
 				if (PTR_00417218->x != -1)
 					removeObject(&_objects[PTR_00417218->x]);
 				PTR_00417218->x = index;
@@ -3066,7 +3066,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 			pobj->fld_3 = PTR_00417218->fld_5;
 			if (DAT_00417220 != DAT_00417228 || DAT_00417224 != DAT_0041722c) {
-				PTR_00417218->flags |= 4;
+				PTR_00417218->flags |= Object::FLAG_TRANSITION;
 			}
 		}
 	} else {
@@ -3080,7 +3080,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 }
 
 void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
-	obj->flags &= ~0x18;
+	obj->flags &= ~(Object::FLAG_FLIPH | Object::FLAG_FLIPV);
 	obj->actID = 0;
 	obj->frame = 0;
 	obj->sprId = sprId;
@@ -3092,9 +3092,9 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 		obj->pImg = &spr.sequences[0]->operator[](0);
 		if (BYTE_004177f6 == 8) {
 			if (spr.field_1 & 2)
-				obj->flags |= 8;
+				obj->flags |= Object::FLAG_FLIPH;
 		} else if (BYTE_004177f6 == 4 && (spr.field_1 & 4)) {
-			obj->flags |= 0x10;
+			obj->flags |= Object::FLAG_FLIPV;
 		}
 	} else {
 		int frm = 0;
@@ -3110,7 +3110,7 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 				frm = 4;
 				if (spr.field_1 & 4) {
 					frm = 2;
-					obj->flags |= 0x10;
+					obj->flags |= Object::FLAG_FLIPV;
 				}
 			} else if (DAT_00417220 == DAT_00417228 && (spr.field_1 & 8))
 				frm = 0;
@@ -3120,7 +3120,7 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 				frm = 0;
 			else if (spr.field_1 & 4) {
 				frm = 1;
-				obj->flags |= 0x10;
+				obj->flags |= Object::FLAG_FLIPV;
 			}
 		} else {
 			frm = 7;
@@ -3129,28 +3129,28 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 					frm = 0;
 				else if (spr.field_1 & 2) {
 					frm = 3;
-					obj->flags |= 8;
+					obj->flags |= Object::FLAG_FLIPH;
 				}
 			} else {
 				if (DAT_0041722c < DAT_00417224) {
 					frm = 8;
 					if (spr.field_1 & 2) {
 						frm = 2;
-						obj->flags |= 8;
+						obj->flags |= Object::FLAG_FLIPH;
 					}
 				} else {
 					frm = 6;
 					if (spr.field_1 & 4) {
 						frm = 8;
-						obj->flags |= 0x10;
+						obj->flags |= Object::FLAG_FLIPV;
 
 						if (spr.field_1 & 2) {
 							frm = 2;
-							obj->flags |= 8;
+							obj->flags |= Object::FLAG_FLIPH;
 						}
 					} else if (spr.field_1 & 2) {
 						frm = 4;
-						obj->flags |= 8;
+						obj->flags |= Object::FLAG_FLIPH;
 					}
 				}
 			}
@@ -3164,7 +3164,7 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 		obj->fld_5 = DAT_0041722c;
 		FUN_0040921c(obj);
 	} else {
-		obj->flags |= 0x40;
+		obj->flags |= Object::FLAG_FREECOORDS;
 	}
 
 	addDirtRectOnObject(obj);
@@ -3175,7 +3175,7 @@ void GamosEngine::FUN_004095a0(Object *obj) {
 		Object &yobj = _objects[obj->y];
 		addDirtRectOnObject(&yobj);
 		if (DAT_00417228 != DAT_00417220 || DAT_0041722c != DAT_00417224)
-			obj->flags |= 4;
+			obj->flags |= Object::FLAG_TRANSITION;
 		FUN_00409378(yobj.sprId, &yobj, false);
 	}
 }
@@ -3186,7 +3186,7 @@ void GamosEngine::removeSubtitles(Object *obj) {
 		//for (int index = obj->index; index < _objects.size(); index++) {
 		for (int index = 0; index < _objects.size(); index++) {
 			Object *pobj = &_objects[index];
-			if ((pobj->flags & 0xe3) == 0xe1 && ((pobj->blk << 8) | pobj->pos) == obj->index)
+			if (pobj->isOverlayObject() && ((pobj->blk << 8) | pobj->pos) == obj->index)
 				removeObjectMarkDirty(pobj);
 		}
 	}
@@ -3207,7 +3207,7 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 			if (robj.index > objIndex)
 				n++;
 
-			if ((robj.flags & 3) == 3 && (_objectActions[robj.actID].unk1 & 0xff) == 3) {
+			if (robj.isActionObject() && (_objectActions[robj.actID].unk1 & 0xff) == 3) {
 				if (n) {
 					PTR_004121b4 = &robj;
 					break;
@@ -3261,7 +3261,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 
 	for (int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
-		if ((obj.flags & 3) == 3) {
+		if (obj.isActionObject()) {
 			ObjectAction &action = _objectActions[obj.actID];
 			uint8 tp = action.unk1 & 0xff;
 			if (tp == 1)
@@ -3434,7 +3434,7 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 
 Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y) {
 	Object *obj = getFreeObject();
-	obj->flags |= 0xe0;
+	obj->flags |= Object::FLAG_GRAPHIC | Object::FLAG_OVERLAY | Object::FLAG_FREECOORDS;
 	obj->actID = 0;
 	obj->fld_2 = 1;
 	obj->fld_3 = PTR_00417218->fld_5;
@@ -4017,7 +4017,7 @@ void GamosEngine::FUN_004025d0() {
 
 		for (int i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];
-			if ((obj.flags & 0xC1) == 0x81 &&
+			if (obj.isStaticObject() &&
 			        obj.pos == 0xff && obj.blk == 0xff &&
 			        obj.fld_4 == PTR_00417218->pos &&
 			        obj.fld_5 == PTR_00417218->blk) {
@@ -4376,7 +4376,7 @@ void GamosEngine::txtInputEraseBack(int n) {
 bool GamosEngine::onTxtInputUpdate(uint8 c) {
 	for(int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
-		if ((obj.flags & 0x87) == 0x81) {
+		if ((obj.flags & (Object::FLAG_GRAPHIC | Object::FLAG_VALID | Object::FLAG_HASACTION | Object::FLAG_TRANSITION)) == (Object::FLAG_GRAPHIC | Object::FLAG_VALID)) {
 			if ((obj.frame + 1 == obj.fld_2) && obj.pos != 255 && obj.blk != 255) {
 				int32 idx = (obj.blk << 8) | obj.pos;
 				obj.fld_4 = _objects[idx].pos;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 5c0a747c57f..58c8f412a3b 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -193,20 +193,28 @@ struct ObjectAction {
 };
 
 struct Object {
+	enum {
+		FLAG_VALID = 1,
+
+		/* Action objects */
+		FLAG_HASACTION = 2,
+		FLAG_TRANSITION = 4, /* transition between logic cells */
+		FLAG_STORAGE = 8, /* in original engine used to indicate allocated storage */
+
+		/* Graphic objects */
+		FLAG_GRAPHIC = 0x80,
+		FLAG_FREECOORDS = 0x40, /* coords not binded to grid */
+		FLAG_OVERLAY = 0x20, /* gfx object like titles and etc */
+		FLAG_FLIPV = 0x10,
+		FLAG_FLIPH = 8,
+		FLAG_DIRTRECT = 4,
+	};
 	/* additional data */
 	int16 index = 0;
 	int32 sprId = -1;
 	int32 seqId = -1;
 	int32 frame = -1;
 
-	/* 80 - drawable
-	   40 -
-	   20 -
-	   10 -
-	   8 - has storage
-	   4 -
-	   2 -
-	   1 - used */
 	uint8 flags = 0;
 	uint8 actID = 0;
 	uint8 fld_2 = 0;
@@ -219,6 +227,12 @@ struct Object {
 	int16 y = 0;
 	ImagePos *pImg = nullptr;
 	Common::Array<byte> storage;
+
+	inline bool isActionObject() const { return (flags & (FLAG_HASACTION | FLAG_VALID)) == (FLAG_HASACTION | FLAG_VALID); };
+	inline bool isGraphicObject() const { return (flags & (FLAG_GRAPHIC | FLAG_VALID | FLAG_HASACTION)) == (FLAG_GRAPHIC | FLAG_VALID); };
+	inline bool isOverlayObject() const { return (flags & (FLAG_GRAPHIC | FLAG_OVERLAY | FLAG_FREECOORDS | FLAG_VALID | FLAG_HASACTION)) ==
+												          (FLAG_GRAPHIC | FLAG_OVERLAY | FLAG_FREECOORDS | FLAG_VALID); };
+	inline bool isStaticObject() const { return (flags & (FLAG_GRAPHIC | FLAG_FREECOORDS | FLAG_VALID)) == (FLAG_GRAPHIC | FLAG_VALID); };
 };
 
 struct SubtitlePoint {


Commit: 0ef434666e1b7876861fdb6b2dc91b19df13e2f4
    https://github.com/scummvm/scummvm/commit/0ef434666e1b7876861fdb6b2dc91b19df13e2f4
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:55+01:00

Commit Message:
GAMOS: Move keycodes into engine class to eliminate global object

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/keycodes.cpp
    engines/gamos/keycodes.h
    engines/gamos/proc.cpp
    engines/gamos/proc.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index b18abe16150..499b751d5fb 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -53,7 +53,7 @@ const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x8
                                         };
 
 GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
-	_gameDescription(gameDesc), _randomSource("Gamos") {
+	_gameDescription(gameDesc), _randomSource("Gamos"), _messageProc(this) {
 	g_engine = this;
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 58c8f412a3b..4b75524acef 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -303,7 +303,7 @@ struct VmTxtFmtAccess : VM::ValAddr {
 	}
 };
 
-class GamosEngine : public Engine {
+class GamosEngine : public Engine, public KeyCodes {
 	friend class MoviePlayer;
 
 private:
diff --git a/engines/gamos/keycodes.cpp b/engines/gamos/keycodes.cpp
index 850a4aa48ab..95afeb1bc26 100644
--- a/engines/gamos/keycodes.cpp
+++ b/engines/gamos/keycodes.cpp
@@ -22,8 +22,6 @@
 #include "gamos/gamos.h"
 namespace Gamos {
 
-KeyCodes KeyCodes::_instance;
-
 KeyCodes::KeyCodes() {
 	for (int16 i = 0; i < Common::KEYCODE_LAST; i++) {
 		_winCodes[i] = WIN_INVALID;
diff --git a/engines/gamos/keycodes.h b/engines/gamos/keycodes.h
index 5952cb27160..51a31608d82 100644
--- a/engines/gamos/keycodes.h
+++ b/engines/gamos/keycodes.h
@@ -260,20 +260,18 @@ public:
 	};
 
 private:
-	static KeyCodes _instance;
-
 	uint8 _winCodes[Common::KEYCODE_LAST];
 	uint16 _scummCodes[256];
 
-private:
+protected:
 	KeyCodes();
 
 public:
-	static uint8 GetWinCode(uint16 code) {
-		return _instance._winCodes[code];
+	uint8 GetWinCode(uint16 code) {
+		return _winCodes[code];
 	};
-	static uint16 GetScummCode(uint8 code) {
-		return _instance._scummCodes[code];
+	uint16 GetScummCode(uint8 code) {
+		return _scummCodes[code];
 	};
 };
 
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index a8274242855..6ea45ad99e5 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -36,7 +36,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 		if (ev.kbd.ascii)
 			_rawKeyCode = ev.kbd.ascii;
 
-		winKey = KeyCodes::GetWinCode(ev.kbd.keycode);
+		winKey = _codesConverter->GetWinCode(ev.kbd.keycode);
 
 		if (winKey == _keyCodes[0])
 			_act1 = 0;
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index 14de8f6aea4..0c5abb43aa1 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -38,10 +38,13 @@ enum ACT2 {
 
 class SystemProc {
 public:
+	SystemProc(KeyCodes *conv) : _codesConverter(conv) {};
 
 	void processMessage(const Common::Event &ev);
 
 public:
+	KeyCodes *_codesConverter = nullptr;
+
 	uint8 _act1 = 0;
 	uint8 _act2 = 0;
 


Commit: 58d6c92358a840616ea343d75ee4054dffd7a51c
    https://github.com/scummvm/scummvm/commit/58d6c92358a840616ea343d75ee4054dffd7a51c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:55+01:00

Commit Message:
GAMOS: Change of VM class for eliminating global objects

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp
    engines/gamos/vm.cpp
    engines/gamos/vm.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 499b751d5fb..3058be14a51 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -43,9 +43,6 @@
 
 namespace Gamos {
 
-GamosEngine *g_engine;
-
-
 const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c,
                                          0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47,
                                          0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
@@ -53,9 +50,10 @@ const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x8
                                         };
 
 GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
-	_gameDescription(gameDesc), _randomSource("Gamos"), _messageProc(this) {
-	g_engine = this;
-}
+	_gameDescription(gameDesc), _randomSource("Gamos"),
+	_messageProc(this),
+	_vm(this, callbackVMCallDispatcher),
+	_txtInputVMAccess(_vm) {}
 
 GamosEngine::~GamosEngine() {
 	freeImages();
@@ -97,9 +95,6 @@ Common::Error GamosEngine::run() {
 	// Set the engine's debugger console
 	setDebugger(new Console());
 
-	VM::_callFuncs = callbackVMCallDispatcher;
-	VM::_callingObject = this;
-
 	// If a savegame was selected from the launcher, load it
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot != -1)
@@ -439,16 +434,16 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		_addrKeyCode = _loadedDataSize + 3;
 		_addrCurrentFrame = _loadedDataSize + 4;
 
-		VM::memory().setU8(_addrBlk12, dataStream.readByte());
+		_vm.memory().setU8(_addrBlk12, dataStream.readByte());
 		dataStream.skip(1);
-		VM::memory().setU8(_addrFPS, _fps);
-		VM::memory().setU8(_addrKeyDown, dataStream.readByte());
-		VM::memory().setU8(_addrKeyCode, dataStream.readByte());
-		VM::memory().setU32(_addrCurrentFrame, dataStream.readUint32LE());
+		_vm.memory().setU8(_addrFPS, _fps);
+		_vm.memory().setU8(_addrKeyDown, dataStream.readByte());
+		_vm.memory().setU8(_addrKeyCode, dataStream.readByte());
+		_vm.memory().setU32(_addrCurrentFrame, dataStream.readUint32LE());
 
 		setFPS(_fps);
 	} else if (tp == RESTP_13) {
-		VM::writeMemory(_loadedDataSize, data, dataSize);
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
 	} else if (tp == RESTP_18) {
 		loadRes18(pid, data, dataSize);
 	} else if (tp == RESTP_19) {
@@ -474,11 +469,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 			return false;
 		_objectActions[pid].unk1 = getU32(data);
 	} else if (tp == RESTP_21) {
-		VM::writeMemory(_loadedDataSize, data, dataSize);
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onCreateAddress = _loadedDataSize + p3;
 		//warning("RESTP_21 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_22) {
-		VM::writeMemory(_loadedDataSize, data, dataSize);
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onDeleteAddress = _loadedDataSize + p3;
 		//warning("RESTP_22 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
 	} else if (tp == RESTP_23) {
@@ -489,11 +484,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		Actions &scr = _objectActions[pid].actions[p1];
 		scr.parse(data, dataSize);
 	} else if (tp == RESTP_2B) {
-		VM::writeMemory(_loadedDataSize, data, dataSize);
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].actions[p1].conditionAddress = _loadedDataSize + p3;
 		//warning("RESTP_2B %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_2C) {
-		VM::writeMemory(_loadedDataSize, data, dataSize);
+		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].actions[p1].functionAddress = _loadedDataSize + p3;
 		//warning("RESTP_2C %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
@@ -734,7 +729,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_subtitlePoints.resize(dat6xCount);
 
 	_loadedDataSize = 0;
-	VM::clearMemory();
+	_vm.clearMemory();
 }
 
 void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
@@ -1221,7 +1216,7 @@ void GamosEngine::changeVolume() {
 
 uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
 	_needReload = false;
-	VM::_interrupt = false;
+	_vm._interrupt = false;
 
 	if (_d2_fld16 == 0) {
 		act1 = ACT_NONE;
@@ -2316,79 +2311,79 @@ bool GamosEngine::loadImage(Image *img) {
 }
 
 uint32 GamosEngine::doScript(uint32 scriptAddress) {
-	uint32 res = VM::doScript(scriptAddress, PTR_004173e8);
+	uint32 res = _vm.doScript(scriptAddress, PTR_004173e8);
 	return res;
 }
 
 
-void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
+void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	uint32 arg1 = 0, arg2 = 0;
 
 	switch (funcID) {
 	case 0:
 		DAT_004177ff = true;
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 	case 1:
-		vm->EAX.setVal( PTR_00417218->y == -1 ? 1 : 0 );
+		ctx->EAX.setVal( PTR_00417218->y == -1 ? 1 : 0 );
 		break;
 
 	case 2:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (PTR_00417218->x == -1)
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 		else
-			vm->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
+			ctx->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
 		break;
 	case 3:
-		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
 		break;
 	case 4:
-		vm->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
 		break;
 	case 5:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
 		break;
 	case 6:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
 		break;
 	case 7:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if ((PTR_00417218->fld_4 & 0x40) == 0 || (PTR_00417218->fld_4 & 8) != (arg1 & 8))
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 		else
-			vm->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->fld_4 & 7) ? 1 : 0 );
+			ctx->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->fld_4 & 7) ? 1 : 0 );
 		break;
 	case 8:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( PTR_00417218->fld_5 == arg1 ? 1 : 0 );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( PTR_00417218->fld_5 == arg1 ? 1 : 0 );
 		break;
 	case 9:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
 	case 10:
-		vm->EAX.setVal( PTR_00417218->fld_2 == 0xfe ? 1 : 0 );
+		ctx->EAX.setVal( PTR_00417218->fld_2 == 0xfe ? 1 : 0 );
 		break;
 	case 11:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( PTR_00417218->fld_2 == arg1 ? 1 : 0 );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( PTR_00417218->fld_2 == arg1 ? 1 : 0 );
 		break;
 	case 12:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( (1 << (PTR_00417218->fld_2 & 7)) & _thing2[arg1].field_0[PTR_00417218->fld_2 >> 3] );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( (1 << (PTR_00417218->fld_2 & 7)) & _thing2[arg1].field_0[PTR_00417218->fld_2 >> 3] );
 		break;
 	case 13: {
-		VM::ValAddr regRef = vm->popReg();
-		Common::String str = vm->getString(regRef);
+		VM::ValAddr regRef = ctx->popReg();
+		Common::String str = ctx->getString(regRef);
 
-		vm->EAX.setVal(0);
+		ctx->EAX.setVal(0);
 
 		for(uint i = 0; i < str.size(); i++) {
 			if (str[i] == RawKeyCode) {
-				vm->EAX.setVal(1);
+				ctx->EAX.setVal(1);
 				break;
 			}
 		}
@@ -2396,79 +2391,79 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	}
 
 	case 14:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		loadModule(arg1);
 		setNeedReload();
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 15:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		switchToGameScreen(arg1, false);
 		setNeedReload();
 		break;
 
 	case 16:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( scriptFunc16(arg1) );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( scriptFunc16(arg1) );
 		break;
 
 	case 17:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		playSound(arg1);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 18:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( scriptFunc18(arg1) ? 1 : 0 );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( scriptFunc18(arg1) ? 1 : 0 );
 		break;
 
 	case 19:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( scriptFunc19(arg1) );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( scriptFunc19(arg1) );
 		break;
 
 	case 20: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		for (const SubtitlePoint &d : _subtitlePoints[arg1]) {
 			FUN_0040738c(d.sprId, d.x, d.y, true);
 		}
-		vm->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
+		ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 	} break;
 
 	case 21: {
-		VM::ValAddr regRef = vm->popReg();
-		arg2 = vm->pop32();
-		vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH) );
+		VM::ValAddr regRef = ctx->popReg();
+		arg2 = ctx->pop32();
+		ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH) );
 	} break;
 
 	case 22: {
-		VM::ValAddr regRef = vm->popReg();
-		arg2 = vm->pop32();
+		VM::ValAddr regRef = ctx->popReg();
+		arg2 = ctx->pop32();
 		const SubtitlePoint &d = _subtitlePoints[arg2][0];
-		vm->EAX.setVal( txtInputBegin(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y) );
+		ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y) );
 	} break;
 
 	case 23: {
-		VM::ValAddr regRef = vm->popReg();
-		arg2 = vm->pop32();
-		addSubtitles(vm, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH);
-		vm->EAX.setVal(1);
+		VM::ValAddr regRef = ctx->popReg();
+		arg2 = ctx->pop32();
+		addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 24: {
-		VM::ValAddr regRef = vm->popReg();
-		arg2 = vm->pop32();
+		VM::ValAddr regRef = ctx->popReg();
+		arg2 = ctx->pop32();
 		const SubtitlePoint &d = _subtitlePoints[arg2][0];
-		addSubtitles(vm, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y);
+		addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), d.sprId, d.x, d.y);
 
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	}
 	break;
 
 	case 25: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (PTR_00417218->fld_5 != arg1) {
 			PTR_00417218->fld_5 = arg1;
 			if (PTR_00417218->x != -1) {
@@ -2481,30 +2476,30 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 				addDirtRectOnObject(&obj);
 			}
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	}
 	break;
 
 	case 26:
 		removeSubtitles(PTR_00417218);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 27:
 		FUN_004025d0();
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 28:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		FUN_0040279c(arg1, false);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 29:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		FUN_0040279c(arg1, true);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 30: {
@@ -2517,29 +2512,29 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	} break;
 
 	case 31:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		setCursor(arg1, true);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 32:
 		setCursor(0, false);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 33:
 		PTR_00417218->fld_5 = _statesHeight - PTR_00417218->blk;
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 34: {
-		VM::ValAddr regRef = vm->popReg();
-		vm->setMem8(regRef, PTR_00417218->fld_5);
-		vm->EAX.setVal(1);
+		VM::ValAddr regRef = ctx->popReg();
+		ctx->setMem8(regRef, PTR_00417218->fld_5);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 35: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		uint ret = 0;
 		switch (arg1) {
 		case 3:
@@ -2581,12 +2576,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		default:
 			break;
 		}
-		vm->EAX.setVal(ret);
+		ctx->EAX.setVal(ret);
 	} break;
 
 	case 36: {
-		arg1 = vm->pop32();
-		arg2 = vm->pop32();
+		arg1 = ctx->pop32();
+		arg2 = ctx->pop32();
 
 		uint ret = 0;
 		switch (arg1) {
@@ -2637,12 +2632,12 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		default:
 			break;
 		}
-		vm->EAX.setVal(ret);
+		ctx->EAX.setVal(ret);
 	} break;
 
 	case 37: {
-		arg1 = vm->pop32();
-		arg2 = vm->pop32();
+		arg1 = ctx->pop32();
+		arg2 = ctx->pop32();
 
 		uint ret = 0;
 		switch (arg1) {
@@ -2693,43 +2688,43 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		default:
 			break;
 		}
-		vm->EAX.setVal(ret);
+		ctx->EAX.setVal(ret);
 	} break;
 
 	case 38:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412ca0)
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 		else
-			vm->EAX.setVal(1);
+			ctx->EAX.setVal(1);
 		break;
 
 	case 39:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412c9c)
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 		else
-			vm->EAX.setVal(1);
+			ctx->EAX.setVal(1);
 		break;
 
 	case 40:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412ca0) != 0)
-			vm->EAX.setVal(1);
+			ctx->EAX.setVal(1);
 		else
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 		break;
 
 	case 41:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412c9c) != 0)
-			vm->EAX.setVal(1);
+			ctx->EAX.setVal(1);
 		else
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 		break;
 
 	case 42: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804 != 0) {
 			if (arg1 == 0) {
 				DAT_00417804 = 0;
@@ -2752,11 +2747,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 				FUN_00402a68(tmp);
 			}
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 43: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804) {
 			ActEntry tmp;
 			tmp.value = arg1;
@@ -2764,11 +2759,11 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			tmp.flags = 0;
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 44: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (DAT_00417804) {
 			ActEntry tmp;
 			tmp.value = arg1;
@@ -2776,45 +2771,45 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			tmp.flags = 1;
 			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 45:
-		arg1 = vm->pop32();
-		vm->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
 		break;
 
 	case 46: {
-		VM::ValAddr a1 = vm->popReg();
-		VM::ValAddr a2 = vm->popReg();
-		Common::String s = vm->getString(a1);
+		VM::ValAddr a1 = ctx->popReg();
+		VM::ValAddr a2 = ctx->popReg();
+		Common::String s = ctx->getString(a1);
 		for(int i = 0; i <= s.size(); i++) {
-			vm->setMem8(a2.getMemType(), a2.getOffset() + i, s.c_str()[i]);
+			ctx->setMem8(a2.getMemType(), a2.getOffset() + i, s.c_str()[i]);
 		}
 	} break;
 
 	case 47: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 
 		switch (arg1) {
 		case 0:
-			vm->EAX.setVal(_d2_fld16 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_d2_fld16 != 0 ? 1 : 0);
 			break;
 
 		case 1:
-			vm->EAX.setVal(_d2_fld14 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_d2_fld14 != 0 ? 1 : 0);
 			break;
 
 		case 2:
-			vm->EAX.setVal(1); //BYTE_004177fb != 0 ? 1 : 0;
+			ctx->EAX.setVal(1); //BYTE_004177fb != 0 ? 1 : 0;
 			break;
 
 		case 3:
-			vm->EAX.setVal(_d2_fld17 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_d2_fld17 != 0 ? 1 : 0);
 			break;
 
 		case 4:
-			vm->EAX.setVal(_d2_fld18 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_d2_fld18 != 0 ? 1 : 0);
 			break;
 
 		default:
@@ -2824,7 +2819,7 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 	break;
 
 	case 48: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 
 		switch (arg1) {
 		case 0:
@@ -2866,51 +2861,51 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 		default:
 			break;
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 49: {
-		arg1 = vm->pop32();
-		arg2 = vm->pop32();
+		arg1 = ctx->pop32();
+		arg2 = ctx->pop32();
 
 		warning("Do save-load %d %d", arg1, arg2);
 	}
 	break;
 
 	case 50:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		PTR_00417388 = _thing2[arg1].field_0.data();
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 51:
 		PTR_00417388 = nullptr;
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 52:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		/* HELP */
 		//FUN_0040c614(arg1);
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 53: {
-		arg1 = vm->pop32();
-		VM::ValAddr adr = vm->popReg();
-		uint kode = vm->getMem8(adr);
+		arg1 = ctx->pop32();
+		VM::ValAddr adr = ctx->popReg();
+		uint kode = ctx->getMem8(adr);
 		_messageProc._keyCodes[arg1] = kode;
-		vm->EAX.setVal(kode);
+		ctx->EAX.setVal(kode);
 	} break;
 
 	case 54:
-		arg1 = vm->pop32();
-		vm->EAX.setVal(rndRange16(arg1));
+		arg1 = ctx->pop32();
+		ctx->EAX.setVal(rndRange16(arg1));
 		break;
 
 	case 55: {
-		VM::ValAddr regRef = vm->popReg(); //implement
-		Common::String str = vm->getString(regRef);
+		VM::ValAddr regRef = ctx->popReg(); //implement
+		Common::String str = ctx->getString(regRef);
 
 		char buffer[256];
 		int a = 0, b = 0, c = 0, d = 0;
@@ -2928,52 +2923,52 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 				scriptFunc16(_midiTrack);
 			}
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	}
 	break;
 
 	case 56: {
-		VM::ValAddr regRef = vm->popReg(); //implement
-		Common::String str = vm->getString(regRef);
+		VM::ValAddr regRef = ctx->popReg(); //implement
+		Common::String str = ctx->getString(regRef);
 		warning("Create process: %s", str.c_str());
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 57: {
-		VM::ValAddr regRef = vm->popReg(); //implement
-		Common::String str = vm->getString(regRef);
+		VM::ValAddr regRef = ctx->popReg(); //implement
+		Common::String str = ctx->getString(regRef);
 		if (_keySeq.find(str) != Common::String::npos) {
 			_keySeq.clear();
-			vm->EAX.setVal(1);
+			ctx->EAX.setVal(1);
 		} else
-			vm->EAX.setVal(0);
+			ctx->EAX.setVal(0);
 	} break;
 
 	case 58: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		/* CD AUDIO */
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 59: {
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		/* CD AUDIO */
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	case 60:
-		arg1 = vm->pop32();
+		arg1 = ctx->pop32();
 		if (arg1 == 0)
 			_scrollTrackObj = -1;
 		else
 			_scrollTrackObj = _curObjIndex;
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 		break;
 
 	case 61: {
-		arg1 = vm->pop32();
-		VM::ValAddr adr = vm->popReg();
-		Common::String tmp = vm->getString(adr);
+		arg1 = ctx->pop32();
+		VM::ValAddr adr = ctx->popReg();
+		Common::String tmp = ctx->getString(adr);
 
 		int val1 = 0, val2 = 0, val3 = 0, val4 = 0;
 		sscanf(tmp.c_str(), "%d %d %d %d", &val1, &val2, &val3, &val4);
@@ -2988,19 +2983,19 @@ void GamosEngine::vmCallDispatcher(VM *vm, uint32 funcID) {
 			_scrollCutoff = val2;
 			_scrollSpeedReduce = val3;
 		}
-		vm->EAX.setVal(1);
+		ctx->EAX.setVal(1);
 	} break;
 
 	default:
 		warning("Call Dispatcher %d", funcID);
-		vm->EAX.setVal(0);
+		ctx->EAX.setVal(0);
 		break;
 	}
 }
 
-void GamosEngine::callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID) {
+void GamosEngine::callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint32 funcID) {
 	GamosEngine *gamos = (GamosEngine *)engine;
-	gamos->vmCallDispatcher(vm, funcID);
+	gamos->vmCallDispatcher(ctx, funcID);
 }
 
 uint32 GamosEngine::scriptFunc19(uint32 id) {
@@ -3353,25 +3348,25 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 	return res;
 }
 
-void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
+void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
 	removeSubtitles(PTR_00417218);
 	PTR_00417218->fld_3 |= 2;
 
 	while (true) {
-		uint8 ib = vm->getMem8(memtype, offset);
+		uint8 ib = ctx->getMem8(memtype, offset);
 		offset++;
 
 		if (ib == 0)
 			break;
 
 		if (ib == 0xf) {
-			byte flg = vm->getMem8(memtype, offset);
+			byte flg = ctx->getMem8(memtype, offset);
 			offset++;
-			byte b2 = vm->getMem8(memtype, offset);
+			byte b2 = ctx->getMem8(memtype, offset);
 			offset++;
 
 			if ((flg & 0x70) == 0x20) {
-				byte funcid = vm->getMem8(memtype, offset);
+				byte funcid = ctx->getMem8(memtype, offset);
 				offset++;
 				warning("CHECKIT and write funcid %d", funcid);
 			} else {
@@ -3383,37 +3378,37 @@ void GamosEngine::addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId,
 						btp = VM::REF_EBX;
 
 					if ((flg & 0x80) == 0) {
-						boff = vm->getMem8(memtype, offset);
+						boff = ctx->getMem8(memtype, offset);
 						offset++;
 					} else {
-						boff = vm->getMem32(memtype, offset);
+						boff = ctx->getMem32(memtype, offset);
 						offset += 4;
 					}
 
 					Common::String tmp;
 					switch (flg & 7) {
 					case 0:
-						tmp = gamos_itoa((int32)(int8)vm->getMem8(btp, boff), 10);
+						tmp = gamos_itoa((int32)(int8)ctx->getMem8(btp, boff), 10);
 						break;
 
 					case 1: {
 						VM::ValAddr addr;
-						addr.setVal( vm->getMem32(btp, boff) );
-						tmp = vm->getString(addr, b2);
+						addr.setVal( ctx->getMem32(btp, boff) );
+						tmp = ctx->getString(addr, b2);
 					} break;
 
 					case 2:
-						tmp = vm->getString(btp, boff, b2);
+						tmp = ctx->getString(btp, boff, b2);
 						break;
 
 					case 3:
-						tmp = gamos_itoa(vm->getMem32(btp, boff), 10);
+						tmp = gamos_itoa(ctx->getMem32(btp, boff), 10);
 						break;
 
 					case 4: {
 						VM::ValAddr addr;
-						addr.setVal( vm->getMem32(btp, boff) );
-						tmp = gamos_itoa(vm->getMem32(addr), 10);
+						addr.setVal( ctx->getMem32(btp, boff) );
+						tmp = gamos_itoa(ctx->getMem32(addr), 10);
 					} break;
 
 					case 5:
@@ -3457,27 +3452,27 @@ Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32
 
 bool GamosEngine::FUN_00402bc4() {
 	if (RawKeyCode == ACT_NONE) {
-		VM::memory().setU8(_addrKeyCode, 0);
-		VM::memory().setU8(_addrKeyDown, 0);
+		_vm.memory().setU8(_addrKeyCode, 0);
+		_vm.memory().setU8(_addrKeyDown, 0);
 	} else {
-		VM::memory().setU8(_addrKeyCode, RawKeyCode);
-		VM::memory().setU8(_addrKeyDown, 1);
+		_vm.memory().setU8(_addrKeyCode, RawKeyCode);
+		_vm.memory().setU8(_addrKeyDown, 1);
 	}
 
-	if (VM::memory().getU8(_addrBlk12) != 0)
+	if (_vm.memory().getU8(_addrBlk12) != 0)
 		return false;
 
-	uint32 frameval = VM::memory().getU32(_addrCurrentFrame);
-	VM::memory().setU32(_addrCurrentFrame, frameval + 1);
+	uint32 frameval = _vm.memory().getU32(_addrCurrentFrame);
+	_vm.memory().setU32(_addrCurrentFrame, frameval + 1);
 
-	uint8 fpsval = VM::memory().getU8(_addrFPS);
+	uint8 fpsval = _vm.memory().getU8(_addrFPS);
 
 	if (fpsval == 0) {
 		fpsval = 1;
-		VM::memory().setU8(_addrFPS, 1);
+		_vm.memory().setU8(_addrFPS, 1);
 	} else if (fpsval > 50) {
 		fpsval = 50;
-		VM::memory().setU8(_addrFPS, 50);
+		_vm.memory().setU8(_addrFPS, 50);
 	}
 
 	if (fpsval != _fps) {
@@ -4201,7 +4196,7 @@ bool GamosEngine::FUN_0040705c(int a, int b) {
 	return ((a + v * 2) & 7) == b;
 }
 
-int GamosEngine::txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
+int GamosEngine::txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int sprId, int32 x, int32 y) {
 	if (memtype != VM::REF_EDI) {
 		error("Unsupported memtype");
 		return 0;
@@ -4242,7 +4237,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 			}
 			_txtInputActive = true;
 			_txtInputTyped = false;
-			ib = VM::memory().getU8(_txtInputVmOffset);
+			ib = _vm.memory().getU8(_txtInputVmOffset);
 			_txtInputVmOffset++;
 			continue;
 		} else if (ib == KeyCodes::WIN_BACK) {
@@ -4260,7 +4255,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 						break;
 
 					case 1: {
-						VmTxtFmtAccess adr;
+						VmTxtFmtAccess adr(_vm);
 						adr.setVal( _txtInputVMAccess.getU32() );
 						adr.write(_txtInputBuffer, _txtInputLength + 1);
 					} break;
@@ -4274,21 +4269,21 @@ void GamosEngine::txtInputProcess(uint8 c) {
 						break;
 
 					case 4: {
-						VmTxtFmtAccess adr;
+						VmTxtFmtAccess adr(_vm);
 						adr.setVal( _txtInputVMAccess.getU32() );
 						adr.setU32( atoi((char *)_txtInputBuffer) );
 					} break;
 				}
 
 				_txtInputTyped = false;
-				ib = VM::memory().getU8(_txtInputVmOffset);
+				ib = _vm.memory().getU8(_txtInputVmOffset);
 				_txtInputVmOffset++;
 				continue;
 			}
 		} else if (ib == 0xf) {
-			_txtInputFlags = VM::memory().getU8(_txtInputVmOffset);
+			_txtInputFlags = _vm.memory().getU8(_txtInputVmOffset);
 			_txtInputVmOffset++;
-			_txtInputMaxLength = VM::memory().getU8(_txtInputVmOffset);
+			_txtInputMaxLength = _vm.memory().getU8(_txtInputVmOffset);
 			_txtInputVmOffset++;
 
 			if ((_txtInputFlags & 0x70) == 0 || (_txtInputFlags & 0x70) == 0x10) {
@@ -4298,10 +4293,10 @@ void GamosEngine::txtInputProcess(uint8 c) {
 					_txtInputVMAccess.objMem = PTR_004173e8;
 				}
 				if ( (_txtInputFlags & 0x80) == 0 ) {
-					_txtInputVMAccess.setOffset( VM::memory().getU8(_txtInputVmOffset) );
+					_txtInputVMAccess.setOffset( _vm.memory().getU8(_txtInputVmOffset) );
 					_txtInputVmOffset++;
 				} else {
-					_txtInputVMAccess.setOffset( VM::memory().getU32(_txtInputVmOffset) );
+					_txtInputVMAccess.setOffset( _vm.memory().getU32(_txtInputVmOffset) );
 					_txtInputVmOffset += 4;
 				}
 				switch (_txtInputFlags & 7) {
@@ -4335,7 +4330,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 				}
 				_txtInputActive = true;
 				_txtInputTyped = false;
-				ib = VM::memory().getU8(_txtInputVmOffset);
+				ib = _vm.memory().getU8(_txtInputVmOffset);
 				_txtInputVmOffset++;
 				continue;
 			}
@@ -4357,7 +4352,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 			return;
 		} else {
 			addSubtitleImage(ib, _txtInputSpriteID, &_txtInputX, _txtInputY);
-			ib = VM::memory().getU8(_txtInputVmOffset);
+			ib = _vm.memory().getU8(_txtInputVmOffset);
 			_txtInputVmOffset++;
 		}
 	}
@@ -4422,12 +4417,12 @@ void GamosEngine::dumpActions() {
 	for (ObjectAction &act : _objectActions) {
 		f.writeString(Common::String::format("Act %d : %x\n", i, act.unk1));
 		if (act.onCreateAddress != -1) {
-			t = VM::disassembly(act.onCreateAddress);
+			t = _vm.disassembly(act.onCreateAddress);
 			f.writeString(Common::String::format("Script1 : \n%s\n", t.c_str()));
 		}
 
 		if (act.onDeleteAddress != -1) {
-			t = VM::disassembly(act.onDeleteAddress);
+			t = _vm.disassembly(act.onDeleteAddress);
 			f.writeString(Common::String::format("Script2 : \n%s\n", t.c_str()));
 		}
 
@@ -4436,12 +4431,12 @@ void GamosEngine::dumpActions() {
 			f.writeString(Common::String::format("subscript %d : \n", j));
 
 			if (sc.conditionAddress != -1) {
-				t = VM::disassembly(sc.conditionAddress);
+				t = _vm.disassembly(sc.conditionAddress);
 				f.writeString(Common::String::format("condition : \n%s\n", t.c_str()));
 			}
 
 			if (sc.functionAddress != -1) {
-				t = VM::disassembly(sc.functionAddress);
+				t = _vm.disassembly(sc.functionAddress);
 				f.writeString(Common::String::format("action : \n%s\n", t.c_str()));
 			}
 
@@ -4457,12 +4452,12 @@ void GamosEngine::dumpActions() {
 	i = 0;
 	for (const Actions &act : _subtitleActions) {
 		if (act.flags & Actions::HAS_CONDITION) {
-			t = VM::disassembly(act.conditionAddress);
+			t = _vm.disassembly(act.conditionAddress);
 			f.writeString(Common::String::format("SubAct %d condition : \n%s\n", i, t.c_str()));
 		}
 
 		if (act.flags & Actions::HAS_FUNCTION) {
-			t = VM::disassembly(act.functionAddress);
+			t = _vm.disassembly(act.functionAddress);
 			f.writeString(Common::String::format("SubAct %d action : \n%s\n", i, t.c_str()));
 		}
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4b75524acef..3025dcc4017 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -254,6 +254,8 @@ struct GameScreen {
 };
 
 struct VmTxtFmtAccess : VM::ValAddr {
+	VmTxtFmtAccess(VM &vm): _vm(vm) {};
+	VM &_vm;
 	byte *objMem = nullptr;
 
 	inline bool isObjMem() const { return getMemType() == VM::REF_EBX;}
@@ -266,40 +268,40 @@ struct VmTxtFmtAccess : VM::ValAddr {
 			return s;
 		}
 
-		return VM::readMemString(getOffset(), maxLen);
+		return _vm.readMemString(getOffset(), maxLen);
 	}
 
 	inline uint8 getU8() const {
 		if (isObjMem())
 			return objMem[getOffset()];
-		return VM::memory().getU8(getOffset());
+		return _vm.memory().getU8(getOffset());
 	}
 
 	inline uint32 getU32() const {
 		if (isObjMem())
-			return VM::getU32(objMem + getOffset());
-		return VM::memory().getU32(getOffset());
+			return _vm.getU32(objMem + getOffset());
+		return _vm.memory().getU32(getOffset());
 	}
 
 	inline void write(byte *src, uint len) {
 		if (isObjMem())
 			memcpy(objMem + getOffset(), src, len);
 		else
-			VM::writeMemory(getOffset(), src, len);
+			_vm.writeMemory(getOffset(), src, len);
 	}
 
 	inline void setU8(uint8 v) {
 		if (isObjMem())
 			objMem[getOffset()] = v;
 		else
-			VM::memory().setU8(getOffset(), v);
+			_vm.memory().setU8(getOffset(), v);
 	}
 
 	inline void setU32(uint32 v) {
 		if (isObjMem())
-			VM::setU32(objMem + getOffset(), v);
+			_vm.setU32(objMem + getOffset(), v);
 		else
-			VM::memory().setU32(getOffset(), v);
+			_vm.memory().setU32(getOffset(), v);
 	}
 };
 
@@ -534,6 +536,8 @@ private:
 
 	Common::Array<Common::Rect> _dirtyRects;
 
+	VM _vm;
+
 	bool _needReload = false;
 
 protected:
@@ -663,11 +667,11 @@ protected:
 
 	void setNeedReload() {
 		_needReload = true;
-		VM::_interrupt = true;
+		_vm._interrupt = true;
 	};
 
 	Object *addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y);
-	void addSubtitles(VM *vm, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
+	void addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
 
 	void FUN_00407db8(uint8 p);
 	byte FUN_00408648(uint8 p1, uint8 p2, uint8 p3);
@@ -690,7 +694,7 @@ protected:
 	void FUN_004025d0();
 	bool FUN_0040705c(int a, int b);
 
-	int txtInputBegin(VM *vm, byte memtype, int32 offset, int sprId, int32 x, int32 y);
+	int txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int sprId, int32 x, int32 y);
 	void txtInputProcess(uint8 c);
 	void txtInputEraseBack(int n);
 
@@ -713,12 +717,12 @@ protected:
 	bool loadStateFile();
 	void loadStateData(Common::SeekableReadStream *stream);
 
-	void vmCallDispatcher(VM *vm, uint32 funcID);
+	void vmCallDispatcher(VM::Context *ctx, uint32 funcID);
 
 
 	void dumpActions();
 
-	static void callbackVMCallDispatcher(void *engine, VM *vm, uint32 funcID);
+	static void callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint32 funcID);
 
 
 	static Common::String gamos_itoa(int value, uint radix);
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 4363fefbd06..71e62d99a93 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -276,7 +276,7 @@ void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
 
 void GamosEngine::writeVMData(Common::SeekableWriteStream *stream, const Common::Array<XorArg> &seq) {
 	for (const XorArg &xarg : seq) {
-		Common::Array<byte> tmp = VM::readMemBlocks(xarg.pos, xarg.len);
+		Common::Array<byte> tmp = _vm.readMemBlocks(xarg.pos, xarg.len);
 
 		//xor data in tmp
 		//...
@@ -296,13 +296,13 @@ void GamosEngine::readVMData(Common::SeekableReadStream *stream, const Common::A
 		//...
 
 		// and write it
-		VM::writeMemory(xarg.pos, buf.data(), xarg.len);
+		_vm.writeMemory(xarg.pos, buf.data(), xarg.len);
 	}
 }
 
 void GamosEngine::zeroVMData(const Common::Array<XorArg> &seq) {
 	for (const XorArg &xarg : seq)
-		VM::zeroMemory(xarg.pos, xarg.len);
+		_vm.zeroMemory(xarg.pos, xarg.len);
 }
 
 }
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index ac20fa4b8e3..f5aa829232e 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -23,23 +23,9 @@
 
 namespace Gamos {
 
-VM::CallDispatcher VM::_callFuncs = nullptr;
-void *VM::_callingObject = nullptr;
-
-Common::HashMap<uint32, VM::MemoryBlock> VM::_memMap;
-bool VM::_interrupt = false;
-
-VM VM::_threads[THREADS_COUNT];
-
-VM::MemAccess VM::_memAccess;
-
-
-
-
-
 uint8 VM::MemAccess::getU8(uint32 address) {
 	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-		_currentBlock = findMemoryBlock(address);
+		_currentBlock = _vm.findMemoryBlock(address);
 
 	if (!_currentBlock)
 		return 0; // ERROR!
@@ -49,7 +35,7 @@ uint8 VM::MemAccess::getU8(uint32 address) {
 
 uint32 VM::MemAccess::getU32(uint32 address) {
 	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-		_currentBlock = findMemoryBlock(address);
+		_currentBlock = _vm.findMemoryBlock(address);
 
 	if (!_currentBlock)
 		return 0; // ERROR!
@@ -63,7 +49,7 @@ uint32 VM::MemAccess::getU32(uint32 address) {
 	for (int i = 1; i < 4; i++) {
 		pos++;
 		if (pos >= 0x100) {
-			block = findMemoryBlock(address + i);
+			block = _vm.findMemoryBlock(address + i);
 			if (!block)
 				break;
 			pos = 0;
@@ -76,20 +62,20 @@ uint32 VM::MemAccess::getU32(uint32 address) {
 
 void VM::MemAccess::setU8(uint32 address, uint8 val) {
 	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-		_currentBlock = findMemoryBlock(address);
+		_currentBlock = _vm.findMemoryBlock(address);
 
 	if (!_currentBlock)
-		_currentBlock = createBlock(address);
+		_currentBlock = _vm.createBlock(address);
 
 	_currentBlock->data[ address - _currentBlock->address ] = val;
 }
 
 void VM::MemAccess::setU32(uint32 address, uint32 val) {
 	if (!_currentBlock || address < _currentBlock->address || address >= (_currentBlock->address + 0x100))
-		_currentBlock = findMemoryBlock(address);
+		_currentBlock = _vm.findMemoryBlock(address);
 
 	if (!_currentBlock)
-		_currentBlock = createBlock(address);
+		_currentBlock = _vm.createBlock(address);
 
 	uint32 pos = address - _currentBlock->address;
 
@@ -105,7 +91,7 @@ void VM::MemAccess::setU32(uint32 address, uint32 val) {
 	for (int i = 1; i < 4; i++) {
 		pos++;
 		if (pos >= 0x100) {
-			block = createBlock(address + i);
+			block = _vm.createBlock(address + i);
 			if (!block)
 				break;
 			pos = 0;
@@ -118,7 +104,7 @@ void VM::MemAccess::setU32(uint32 address, uint32 val) {
 
 
 
-uint32 VM::execute(uint32 scriptAddress, byte *storage) {
+uint32 VM::Context::execute(uint32 scriptAddress, byte *storage) {
 	//Common::String disasm = disassembly(scriptAddress);
 
 	ESI = scriptAddress;
@@ -133,7 +119,7 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 
 	bool loop = true;
 	while (loop) {
-		if (_interrupt)
+		if (_vm._interrupt)
 			return 0;
 
 		byte op = _readAccess.getU8(ESI);
@@ -415,8 +401,8 @@ uint32 VM::execute(uint32 scriptAddress, byte *storage) {
 		case OP_CALL_FUNC:
 			EAX.setVal( _readAccess.getU32(ESI) );
 			ESI += 4;
-			if (_callFuncs)
-				_callFuncs(_callingObject, this, EAX.getVal());
+			if (_vm._callFuncs)
+				_vm._callFuncs(_vm._callingObject, this, EAX.getVal());
 			break;
 
 		case OP_PUSH_ESI_SET_EDX_EDI:
@@ -443,7 +429,7 @@ uint32 VM::doScript(uint32 scriptAddress, byte *storage) {
 		}
 	}
 
-	VM *tmpcontext = new VM();
+	Context *tmpcontext = new Context(*this);
 	uint32 res = tmpcontext->execute(scriptAddress, storage);
 	delete tmpcontext;
 	return res;
@@ -469,30 +455,30 @@ void VM::setU32(void *mem, uint32 val) {
 	mem8[3] = (val >> 24) & 0xff;
 }
 
-void VM::push32(uint32 val) {
+void VM::Context::push32(uint32 val) {
 	SP -= 4;
 	setU32(_stack + SP, val);
 }
 
-uint32 VM::pop32() {
+uint32 VM::Context::pop32() {
 	uint32 val = getU32(_stack + SP);
 	SP += 4;
 	return val;
 }
 
-void VM::pushReg(ValAddr reg) {
+void VM::Context::pushReg(ValAddr reg) {
 	SP -= 4;
 	setU32(_stack + SP, reg.getVal());
 }
 
-VM::ValAddr VM::popReg() {
+VM::ValAddr VM::Context::popReg() {
 	ValAddr tmp;
 	tmp.setVal( getU32(_stack + SP) );
 	SP += 4;
 	return tmp;
 }
 
-uint32 VM::getMem32(int memtype, uint32 offset) {
+uint32 VM::Context::getMem32(int memtype, uint32 offset) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
@@ -509,11 +495,11 @@ uint32 VM::getMem32(int memtype, uint32 offset) {
 	}
 }
 
-uint32 VM::getMem32(const ValAddr &addr) {
+uint32 VM::Context::getMem32(const ValAddr &addr) {
     return getMem32(addr.getMemType(), addr.getOffset());
 }
 
-uint8 VM::getMem8(int memtype, uint32 offset) {
+uint8 VM::Context::getMem8(int memtype, uint32 offset) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
@@ -530,11 +516,11 @@ uint8 VM::getMem8(int memtype, uint32 offset) {
 	}
 }
 
-uint8 VM::getMem8(const ValAddr &addr) {
+uint8 VM::Context::getMem8(const ValAddr &addr) {
     return getMem8(addr.getMemType(), addr.getOffset());
 }
 
-void VM::setMem32(int memtype, uint32 offset, uint32 val) {
+void VM::Context::setMem32(int memtype, uint32 offset, uint32 val) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
@@ -552,11 +538,11 @@ void VM::setMem32(int memtype, uint32 offset, uint32 val) {
 	}
 }
 
-void VM::setMem32(const ValAddr &addr, uint32 val) {
+void VM::Context::setMem32(const ValAddr &addr, uint32 val) {
     setMem32(addr.getMemType(), addr.getOffset(), val);
 }
 
-void VM::setMem8(int memtype, uint32 offset, uint8 val) {
+void VM::Context::setMem8(int memtype, uint32 offset, uint8 val) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
@@ -574,7 +560,7 @@ void VM::setMem8(int memtype, uint32 offset, uint8 val) {
 	}
 }
 
-void VM::setMem8(const ValAddr &addr, uint8 val) {
+void VM::Context::setMem8(const ValAddr &addr, uint8 val) {
     setMem8(addr.getMemType(), addr.getOffset(), val);
 }
 
@@ -706,7 +692,7 @@ Common::String VM::readMemString(uint32 address, uint32 maxLen) {
 	return s;
 }
 
-Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
+Common::String VM::Context::getString(int memtype, uint32 offset, uint32 maxLen) {
 	switch (memtype) {
 	default:
 	case REF_UNK:
@@ -726,11 +712,11 @@ Common::String VM::getString(int memtype, uint32 offset, uint32 maxLen) {
 	}
 
 	case REF_EDI:
-		return readMemString(offset, maxLen);
+		return _vm.readMemString(offset, maxLen);
 	}
 }
 
-Common::String VM::getString(const ValAddr &addr, uint32 maxLen) {
+Common::String VM::Context::getString(const ValAddr &addr, uint32 maxLen) {
     return getString(addr.getMemType(), addr.getOffset(), maxLen);
 }
 
@@ -738,7 +724,7 @@ Common::String VM::getString(const ValAddr &addr, uint32 maxLen) {
 Common::String VM::decodeOp(uint32 address, int *size) {
 	Common::String tmp;
 
-	MemAccess readmem;
+	MemAccess readmem(*this);
 
 	int sz = 1;
 	byte op = readmem.getU8(address);
@@ -998,7 +984,7 @@ Common::String VM::disassembly(uint32 address) {
 	Common::String tmp;
 
 	uint32 addr = address;
-	MemAccess readmem;
+	MemAccess readmem(*this);
 
 	while (true) {
 		tmp += Common::String::format("%08x: ", addr);
diff --git a/engines/gamos/vm.h b/engines/gamos/vm.h
index e1a11c56c31..58afae1ef2c 100644
--- a/engines/gamos/vm.h
+++ b/engines/gamos/vm.h
@@ -117,8 +117,6 @@ public:
         inline void setAddress(uint tp, uint32 offset) { value = (offset & ADDRESS_MASK) | ((tp & 3) << MEMTYPE_SHIFT); };
     };
 
-    typedef void (* CallDispatcher)(void *object, VM *state, uint32 funcID);
-
     struct MemoryBlock {
         uint32 address = 0;
         byte data[256];
@@ -136,6 +134,9 @@ public:
     };
 
     struct MemAccess {
+        MemAccess(VM &vm): _vm(vm) {};
+
+        VM &_vm;
         MemoryBlock *_currentBlock = nullptr;
 
         uint8 getU8(uint32 address);
@@ -149,85 +150,100 @@ public:
         }
     };
 
-public:
-    inline static MemAccess &memory() {
-        return _memAccess;
-    };
+    class Context {
+    public:
+        Context(VM &vm): _vm(vm), _readAccess(vm), _writeAccess(vm) {};
 
-    static void clearMemory();
-    static void writeMemory(uint32 address, const byte* data, uint32 dataSize);
+        Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
+        Common::String getString(const ValAddr &addr, uint32 maxLen = 256);
 
-    static void zeroMemory(uint32 address, uint32 count);
+        uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
 
-    static MemoryBlock *findMemoryBlock(uint32 address);
+        void push32(uint32 val);
+        uint32 pop32();
 
-    static MemoryBlock *createBlock(uint32 address);
+        void pushReg(ValAddr reg);
+        ValAddr popReg();
 
-    static Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
-    static void readMemBlocks(byte *dst, uint32 address, uint32 count);
+        uint32 getMem32(int memtype, uint32 offset);
+        uint32 getMem32(const ValAddr& addr);
+        uint8 getMem8(int memtype, uint32 offset);
+        uint8 getMem8(const ValAddr& addr);
 
-    static Common::String readMemString(uint32 address, uint32 maxLen = 256);
+        void setMem32(int memtype, uint32 offset, uint32 val);
+        void setMem32(const ValAddr& addr, uint32 val);
+        void setMem8(int memtype, uint32 offset, uint8 val);
+        void setMem8(const ValAddr& addr, uint8 val);
 
-    Common::String getString(int memtype, uint32 offset, uint32 maxLen = 256);
-    Common::String getString(const ValAddr &addr, uint32 maxLen = 256);
+    public:
+        VM &_vm;
+        bool _inUse = false;
 
-    uint32 execute(uint32 scriptAddress, byte *storage = nullptr);
+        uint32 ESI = 0;
+        byte *EBX = nullptr;
+        ValAddr EAX;
+        ValAddr EDX;
+        ValAddr ECX;
+        uint32 SP = 0;
+        byte _stack[STACK_SIZE];
 
-    static uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
+    private:
+        MemAccess _readAccess;
+        MemAccess _writeAccess;
+    };
 
-    static int32 getS32(const void *);
-    static uint32 getU32(const void *);
-    static void setU32(void *, uint32 val);
+    typedef void (* CallDispatcher)(void *object, Context *state, uint32 funcID);
 
-    void push32(uint32 val);
-    uint32 pop32();
+public:
+    friend class Context;
 
-    void pushReg(ValAddr reg);
-    ValAddr popReg();
+public:
+    VM(void *obj, CallDispatcher dispatcher): _memAccess(*this), _threads{*this, *this}, _callFuncs(dispatcher), _callingObject(obj) {};
 
-    uint32 getMem32(int memtype, uint32 offset);
-    uint32 getMem32(const ValAddr& addr);
-    uint8 getMem8(int memtype, uint32 offset);
-    uint8 getMem8(const ValAddr& addr);
+    inline MemAccess &memory() {
+        return _memAccess;
+    };
 
-    void setMem32(int memtype, uint32 offset, uint32 val);
-    void setMem32(const ValAddr& addr, uint32 val);
-    void setMem8(int memtype, uint32 offset, uint8 val);
-    void setMem8(const ValAddr& addr, uint8 val);
+    void clearMemory();
+    void writeMemory(uint32 address, const byte* data, uint32 dataSize);
 
-    static Common::String decodeOp(uint32 address, int *size = nullptr);
-    static Common::String disassembly(uint32 address);
+    void zeroMemory(uint32 address, uint32 count);
 
-    static Common::String opLog(const Common::Array<OpLog> &log);
+    MemoryBlock *findMemoryBlock(uint32 address);
 
-    static void printDisassembly(uint32 address);
+    MemoryBlock *createBlock(uint32 address);
 
-private:
+    Common::Array<byte> readMemBlocks(uint32 address, uint32 count);
+    void readMemBlocks(byte *dst, uint32 address, uint32 count);
 
-public:
-    bool _inUse = false;
+    Common::String readMemString(uint32 address, uint32 maxLen = 256);
+
+    uint32 doScript(uint32 scriptAddress, byte *storage = nullptr);
 
-    uint32 ESI = 0;
-    byte *EBX = nullptr;
-    ValAddr EAX;
-    ValAddr EDX;
-    ValAddr ECX;
-    uint32 SP = 0;
-    byte _stack[STACK_SIZE];
+    static int32 getS32(const void *);
+    static uint32 getU32(const void *);
+    static void setU32(void *, uint32 val);
 
-private:
-    MemAccess _readAccess;
-    MemAccess _writeAccess;
+    Common::String decodeOp(uint32 address, int *size = nullptr);
+    Common::String disassembly(uint32 address);
 
-public:
-    static CallDispatcher _callFuncs;
-    static void *_callingObject;
+    Common::String opLog(const Common::Array<OpLog> &log);
 
-    static Common::HashMap<uint32, MemoryBlock> _memMap;
-    static bool _interrupt;
+    void printDisassembly(uint32 address);
+
+protected:
+    Common::HashMap<uint32, MemoryBlock> _memMap;
+
+    MemAccess _memAccess;
+
+    Context _threads[THREADS_COUNT];
+
+    CallDispatcher const _callFuncs = nullptr;
+    void * const _callingObject = nullptr;
+
+public:
 
-    static VM _threads[THREADS_COUNT];
-    static MemAccess _memAccess;
+    bool _interrupt = false;
 };
 
 


Commit: b40eb2cfc261bf4920c78bde6713f07be629ca61
    https://github.com/scummvm/scummvm/commit/b40eb2cfc261bf4920c78bde6713f07be629ca61
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:56+01:00

Commit Message:
GAMOS: Fix compiler warnings

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 3058be14a51..9ca419c1159 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -199,8 +199,8 @@ bool GamosEngine::loader2() {
 		} else if (curByte == 2) {
 			p2 = dataStream.readSint32LE();
 		} else if (curByte == 7) {
-			int32 needsz = dataStream.readSint32LE(); // check free mem ?
-			//warning("7777 want %d", needsz);
+			/*int32 needsz = dataStream.readSint32LE(); // check free mem ? */
+			dataStream.skip(4);
 		} else if (curByte == 0x40) {
 			resSize = 4;
 			resType = 0x40;
@@ -1050,7 +1050,7 @@ bool GamosEngine::usePalette(const byte *pal, int num, int fade, bool winColors)
 
 					if (eventsSkip()) {
 						j = 8;
-						uint16 color = _screen->getPalette().findBestColor(0, 0, 0);
+						color = _screen->getPalette().findBestColor(0, 0, 0);
 						_screen->fillRect(_screen->getBounds(), color);
 						_screen->update();
 						break;
@@ -1382,6 +1382,9 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 					return 0;
 				}
 			}
+
+			if (fastSkipAll)
+				break;
 		}
 	}
 
@@ -4008,7 +4011,6 @@ void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
 void GamosEngine::FUN_004025d0() {
 	if (PTR_00417218->fld_2 != 0xfe) {
 		ObjectAction &act = _objectActions[PTR_00417218->fld_2];
-		PTR_00417218->pos;
 
 		for (int i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];


Commit: 280bebc77b9e0b6fc7fdb103d51eb85e8f77df8b
    https://github.com/scummvm/scummvm/commit/280bebc77b9e0b6fc7fdb103d51eb85e8f77df8b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:56+01:00

Commit Message:
GAMOS: Disable unused field in file.h

Changed paths:
    engines/gamos/file.h


diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index 5a660f08474..1b2d2a9ed28 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -76,8 +76,7 @@ private:
 
 	Common::Array<ArchiveDir> _directories;
 
-
-	bool _error;
+	//bool _error;
 };
 
 


Commit: 6b366abfc3062c24501fa7a4daa0a30825225617
    https://github.com/scummvm/scummvm/commit/6b366abfc3062c24501fa7a4daa0a30825225617
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:56+01:00

Commit Message:
GAMOS: Refactor object structure and split fields by their purpose

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 9ca419c1159..1bc5465259c 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1277,8 +1277,8 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 	Common::Array<Common::Point> ARR_00412208(512);
 
 	if (!absolute) {
-		DAT_00417228 = PTR_00417218->pos;
-		DAT_0041722c = PTR_00417218->blk;
+		DAT_00417228 = PTR_00417218->cell.x;
+		DAT_0041722c = PTR_00417218->cell.y;
 	} else {
 		PTR_00417218 = nullptr;
 		_curObjIndex = -1;
@@ -1405,13 +1405,13 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 	if (a.flags & Actions::HAS_FUNCTION) {
 		uint32 fldsv;
 		if (PTR_00417218)
-			fldsv = PTR_00417218->fld_5;
+			fldsv = PTR_00417218->priority;
 		if (a.functionAddress != -1)
 			doScript(a.functionAddress);
 		if (_needReload)
 			return 0;
-		if (BYTE_004177fc == 0 && BYTE_00412200 == 0 && PTR_00417218 && PTR_00417218->fld_5 != fldsv && PTR_00417218->y != -1)
-			addDirtRectOnObject(&_objects[PTR_00417218->y]);
+		if (BYTE_004177fc == 0 && BYTE_00412200 == 0 && PTR_00417218 && PTR_00417218->priority != fldsv && PTR_00417218->curObjectId != -1)
+			addDirtRectOnObject(&_objects[PTR_00417218->curObjectId]);
 	}
 
 	if (BYTE_004177fc == 0 && BYTE_00412200 != 0)
@@ -1677,19 +1677,17 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
 		DAT_00417220 = (e.x + DAT_00417220 + _statesWidth) % _statesWidth;
 		DAT_00417224 = (e.y + DAT_00417224 + _statesHeight) % _statesHeight;
 
-		uint8 t = PTR_00417218->fld_3;
-
-		_states.at(DAT_00417228, DAT_0041722c) = ((PTR_00417218->fld_3 & 0xf0) << 8) | PTR_00417218->fld_2;
+		uint16 t = PTR_00417218->state;
+		_states.at(DAT_00417228, DAT_0041722c) = PTR_00417218->state & 0xf0ff;
 
 		FUN_00402654(0, DAT_00417224, DAT_00417220);
 
-		PTR_00417218->pos = DAT_00417220;
-		PTR_00417218->blk = DAT_00417224;
+		PTR_00417218->cell.x = DAT_00417220;
+		PTR_00417218->cell.y = DAT_00417224;
 
 		uint16 &rthing = _states.at(DAT_00417220, DAT_00417224);
 
-		PTR_00417218->fld_2 = rthing & 0xff;
-		PTR_00417218->fld_3 = (t & 0xf) | ((rthing >> 8) & 0xf0);
+		PTR_00417218->state = (t & 0xf00) | (rthing & 0xf0ff);
 
 		rthing = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
 
@@ -1757,16 +1755,15 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 		obj = getFreeObject();
 		obj->flags = (e.t << 4) | Object::FLAG_VALID | Object::FLAG_HASACTION;
 		obj->actID = oid;
-		obj->fld_4 = 0;
-		obj->fld_5 = (act.unk1 >> 16) & 0xff;
-		obj->pos = x;
-		obj->blk = y;
-		obj->x = -1;
-		obj->y = -1;
-		obj->fld_2 = rthing & 0xff;
-		obj->fld_3 = (rthing >> 8) & 0xff;
+		obj->inputFlag = 0;
+		obj->priority = (act.unk1 >> 16) & 0xff;
+		obj->cell.x = x;
+		obj->cell.y = y;
+		obj->tgtObjectId = -1;
+		obj->curObjectId = -1;
+		obj->state = rthing;
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
-			obj->fld_3 |= 1;
+			obj->state |= 0x100;
 
 		int storageSize = ((act.unk1 >> 24) & 0xff) + 1;
 		// if (storageSize < 5) {
@@ -1811,10 +1808,10 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 		Object &obj = _objects[i];
 		if (obj.flags & Object::FLAG_VALID) {
 			if (obj.flags & Object::FLAG_HASACTION) {
-				if (obj.pos == pos && obj.blk == id) {
-					removeObjectByIDMarkDirty(obj.y);
-					if (obj.y != obj.x)
-						removeObjectByIDMarkDirty(obj.x);
+				if (obj.cell.x == pos && obj.cell.y == id) {
+					removeObjectByIDMarkDirty(obj.curObjectId);
+					if (obj.curObjectId != obj.tgtObjectId)
+						removeObjectByIDMarkDirty(obj.tgtObjectId);
 					/* if (obj.flags & Object::FLAG_STORAGE)
 					    obj.storage.clear(); */
 					removeSubtitles(&obj);
@@ -1827,8 +1824,8 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 					multidel = true;
 				}
 			} else {
-				if (mode && obj.fld_4 == pos && obj.fld_5 == id &&
-				        obj.pos == 0xff && obj.blk == 0xff && (obj.flags & Object::FLAG_FREECOORDS) == 0) {
+				if (mode && obj.cell.x == pos && obj.cell.y == id &&
+				        obj.actObjIndex == -1 && (obj.flags & Object::FLAG_FREECOORDS) == 0) {
 
 					removeObjectMarkDirty(&obj);
 					if (multidel)
@@ -1841,7 +1838,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	}
 
 	if (povar4)
-		rthing = ((povar4->fld_3 & 0xf0) << 8) | (povar4->fld_2 & 0xff);
+		rthing = povar4->state & 0xf0ff;
 
 	executeScript(rthing >> 12, id, pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
 }
@@ -1863,19 +1860,24 @@ Object *GamosEngine::getFreeObject() {
 	}
 
 	obj->flags = Object::FLAG_VALID;
+	obj->priority = 0;
+	obj->cell.x = 0;
+	obj->cell.y = 0;
+
 	obj->sprId = -1;
 	obj->seqId = -1;
 	obj->frame = -1;
+	obj->frameMax = -1;
+	obj->position.x = 0;
+	obj->position.y = 0;
+	obj->actObjIndex = -1;
 
 	obj->actID = 0;
-	obj->fld_2 = 0;
-	obj->fld_3 = 0;
-	obj->fld_4 = 0;
-	obj->fld_5 = 0;
-	obj->pos = 0xff;
-	obj->blk = 0xff;
-	obj->x = 0;
-	obj->y = 0;
+	obj->state = 0;
+	obj->inputFlag = 0;
+	obj->tgtObjectId = -1;
+	obj->curObjectId = -1;
+
 	obj->pImg = nullptr;
 	return obj;
 }
@@ -1901,7 +1903,7 @@ void GamosEngine::removeObjectMarkDirty(Object *obj) {
 }
 
 
-void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, ObjectAction *act, int32 scriptAddr) {
+void GamosEngine::executeScript(uint8 p1, uint32 celly, uint32 cellx, byte *storage, int32 index, Object *pobj, ObjectAction *act, int32 scriptAddr) {
 	if (scriptAddr == -1)
 		return;
 
@@ -1917,10 +1919,10 @@ void GamosEngine::executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage,
 
 	BYTE_004177f6 = p1;
 	PTR_004173e8 = storage;
-	DAT_0041722c = id;
-	DAT_00417228 = pos;
-	DAT_00417224 = id;
-	DAT_00417220 = pos;
+	DAT_0041722c = celly;
+	DAT_00417228 = cellx;
+	DAT_00417224 = celly;
+	DAT_00417220 = cellx;
 	_curObjIndex = index;
 	PTR_00417218 = pobj;
 	PTR_00417214 = act;
@@ -1951,29 +1953,27 @@ bool GamosEngine::FUN_00402fb4() {
 
 		if (pobj->isActionObject()) {
 			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7)))) {
-				if (pobj->fld_3 & 1) {
-					pobj->fld_3 &= ~1;
+				if (pobj->state & 0x100) {
+					pobj->state &= ~0x100;
 				} else {
 					if ((pobj->flags & Object::FLAG_TRANSITION) == 0) {
-						if (pobj->y != -1 && FUN_00402f34(true, false, &_objects[pobj->y])) {
-							pobj->y = pobj->x;
-							if (pobj->x != -1) {
-								Object &o = _objects[pobj->x];
+						if (pobj->curObjectId != -1 && FUN_00402f34(true, false, &_objects[pobj->curObjectId])) {
+							pobj->curObjectId = pobj->tgtObjectId;
+							if (pobj->tgtObjectId != -1) {
+								Object &o = _objects[pobj->tgtObjectId];
 								o.flags |= Object::FLAG_GRAPHIC;
-								o.fld_4 = pobj->pos;
-								o.fld_5 = pobj->blk;
+								o.cell = pobj->cell;
 								FUN_0040921c(&o);
 								addDirtRectOnObject(&o);
 							}
 						}
 					} else {
-						if (FUN_00402f34(pobj->y != pobj->x, true, &_objects[pobj->y])) {
-							pobj->y = pobj->x;
-							if (pobj->x != -1) {
-								Object &o = _objects[pobj->x];
+						if (FUN_00402f34(pobj->curObjectId != pobj->tgtObjectId, true, &_objects[pobj->curObjectId])) {
+							pobj->curObjectId = pobj->tgtObjectId;
+							if (pobj->tgtObjectId != -1) {
+								Object &o = _objects[pobj->tgtObjectId];
 								o.flags |= Object::FLAG_GRAPHIC;
-								o.fld_4 = pobj->pos;
-								o.fld_5 = pobj->blk;
+								o.cell = pobj->cell;
 								FUN_0040921c(&o);
 								addDirtRectOnObject(&o);
 							}
@@ -2057,7 +2057,7 @@ bool GamosEngine::FUN_00402fb4() {
 				}
 			}
 		} else {
-			if (!PTR_00417388 && pobj->isGraphicObject() && pobj->pos == 0xff && pobj->blk == 0xff)
+			if (!PTR_00417388 && pobj->isGraphicObject() && pobj->actObjIndex == -1)
 				FUN_00402f34(true, false, pobj);
 		}
 continue_to_next_object:
@@ -2071,7 +2071,7 @@ exit:
 }
 
 bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
-	if (obj->fld_2 < 2) {
+	if (obj->frameMax < 2) {
 		if (p2 || (obj->flags & Object::FLAG_DIRTRECT)) {
 			addDirtRectOnObject(obj);
 			if (p1)
@@ -2080,11 +2080,9 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 		}
 	} else {
 		addDirtRectOnObject(obj);
-		obj->actID++;
 		obj->frame++;
 
-		if (obj->frame == obj->fld_2) {
-			obj->actID = 0;
+		if (obj->frame == obj->frameMax) {
 			obj->frame = 0;
 			obj->pImg = &_sprites[obj->sprId].sequences[obj->seqId]->operator[](obj->frame);
 			if (p2 || (obj->flags & Object::FLAG_DIRTRECT)) {
@@ -2105,38 +2103,38 @@ bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
 	return false;
 }
 
-void GamosEngine::FUN_0040921c(Object *obj) {
-	ImagePos *imgPos = obj->pImg;
+void GamosEngine::FUN_0040921c(Object *gfxObj) {
+	ImagePos *imgPos = gfxObj->pImg;
 	Image *img = imgPos->image;
 
-	int32 x = obj->fld_4 * _gridCellW;
-	int32 y = obj->fld_5 * _gridCellH;
+	int32 x = gfxObj->cell.x * _gridCellW;
+	int32 y = gfxObj->cell.y * _gridCellH;
 
-	if (obj->pos != 255 && obj->blk != 255) {
-		Object *o = &_objects[(obj->blk * 0x100) + obj->pos];
+	if (gfxObj->actObjIndex != -1) {
+		Object *o = &_objects[ gfxObj->actObjIndex ];
 		if (o->flags & Object::FLAG_TRANSITION) {
-			int t = obj->frame + 1;
-			x += (o->pos - obj->fld_4) * _gridCellW * t / obj->fld_2;
-			y += (o->blk - obj->fld_5) * _gridCellH * t / obj->fld_2;
+			int t = gfxObj->frame + 1;
+			x += (o->cell.x - gfxObj->cell.x) * _gridCellW * t / gfxObj->frameMax;
+			y += (o->cell.y - gfxObj->cell.y) * _gridCellH * t / gfxObj->frameMax;
 		}
 	}
 
-	if (obj->flags & Object::FLAG_FLIPH)
-		obj->x = x - (img->surface.w - _gridCellW - imgPos->xoffset);
+	if (gfxObj->flags & Object::FLAG_FLIPH)
+		gfxObj->position.x = x - (img->surface.w - _gridCellW - imgPos->xoffset);
 	else
-		obj->x = x - imgPos->xoffset;
+		gfxObj->position.x = x - imgPos->xoffset;
 
-	if (obj->flags & Object::FLAG_FLIPV)
-		obj->y = y - (img->surface.h - _gridCellH - imgPos->yoffset);
+	if (gfxObj->flags & Object::FLAG_FLIPV)
+		gfxObj->position.y = y - (img->surface.h - _gridCellH - imgPos->yoffset);
 	else
-		obj->y = y - imgPos->yoffset;
+		gfxObj->position.y = y - imgPos->yoffset;
 }
 
 void GamosEngine::addDirtRectOnObject(Object *obj) {
 	ImagePos *imgPos = obj->pImg;
 	Common::Rect rect;
-	rect.left = obj->x;
-	rect.top = obj->y;
+	rect.left = obj->position.x;
+	rect.top = obj->position.y;
 	if (obj->flags & Object::FLAG_FREECOORDS) {
 		rect.left -= imgPos->xoffset;
 		rect.top -= imgPos->yoffset;
@@ -2212,7 +2210,7 @@ void GamosEngine::doDraw() {
 			for (int j = i + 1; j < drawList.size(); j++) {
 				Object *o1 = drawList[i];
 				Object *o2 = drawList[j];
-				if (o1->fld_3 < o2->fld_3) {
+				if (o1->priority < o2->priority) {
 					drawList[i] = o2;
 					drawList[j] = o1;
 				}
@@ -2241,8 +2239,8 @@ void GamosEngine::doDraw() {
 			if (o->pImg && loadImage(o->pImg->image)) {
 
 				Common::Rect s;
-				s.left = o->x - _scrollX;
-				s.top = o->y - _scrollY;
+				s.left = o->position.x - _scrollX;
+				s.top = o->position.y - _scrollY;
 
 				if (o->flags & Object::FLAG_FREECOORDS) {
 					s.left -= o->pImg->xoffset;
@@ -2328,55 +2326,55 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		ctx->EAX.setVal(1);
 		break;
 	case 1:
-		ctx->EAX.setVal( PTR_00417218->y == -1 ? 1 : 0 );
+		ctx->EAX.setVal( PTR_00417218->curObjectId == -1 ? 1 : 0 );
 		break;
 
 	case 2:
 		arg1 = ctx->pop32();
-		if (PTR_00417218->x == -1)
+		if (PTR_00417218->tgtObjectId == -1)
 			ctx->EAX.setVal(0);
 		else
-			ctx->EAX.setVal( _objects[ PTR_00417218->x ].sprId == arg1 ? 1 : 0 );
+			ctx->EAX.setVal( _objects[ PTR_00417218->tgtObjectId ].sprId == arg1 ? 1 : 0 );
 		break;
 	case 3:
-		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0x90) == 0x10 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0x90) == 0x10 ? 1 : 0 );
 		break;
 	case 4:
-		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0xa0) == 0x20 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0xa0) == 0x20 ? 1 : 0 );
 		break;
 	case 5:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0xb0) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0xb0) == arg1 ? 1 : 0 );
 		break;
 	case 6:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (PTR_00417218->fld_4 & 0x4f) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0x4f) == arg1 ? 1 : 0 );
 		break;
 	case 7:
 		arg1 = ctx->pop32();
-		if ((PTR_00417218->fld_4 & 0x40) == 0 || (PTR_00417218->fld_4 & 8) != (arg1 & 8))
+		if ((PTR_00417218->inputFlag & 0x40) == 0 || (PTR_00417218->inputFlag & 8) != (arg1 & 8))
 			ctx->EAX.setVal(0);
 		else
-			ctx->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->fld_4 & 7) ? 1 : 0 );
+			ctx->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->inputFlag & 7) ? 1 : 0 );
 		break;
 	case 8:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( PTR_00417218->fld_5 == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( PTR_00417218->priority == arg1 ? 1 : 0 );
 		break;
 	case 9:
 		arg1 = ctx->pop32();
 		ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
 	case 10:
-		ctx->EAX.setVal( PTR_00417218->fld_2 == 0xfe ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->state & 0xff) == 0xfe ? 1 : 0 );
 		break;
 	case 11:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( PTR_00417218->fld_2 == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (PTR_00417218->state & 0xff) == arg1 ? 1 : 0 );
 		break;
 	case 12:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (1 << (PTR_00417218->fld_2 & 7)) & _thing2[arg1].field_0[PTR_00417218->fld_2 >> 3] );
+		ctx->EAX.setVal( _thing2[arg1].field_0[ (PTR_00417218->state >> 3) & 0x1f ] & (1 << (PTR_00417218->state & 7)) );
 		break;
 	case 13: {
 		VM::ValAddr regRef = ctx->popReg();
@@ -2467,15 +2465,15 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 25: {
 		arg1 = ctx->pop32();
-		if (PTR_00417218->fld_5 != arg1) {
-			PTR_00417218->fld_5 = arg1;
-			if (PTR_00417218->x != -1) {
-				Object &obj = _objects[PTR_00417218->x];
-				obj.fld_3 = arg1;
+		if (PTR_00417218->priority != arg1) {
+			PTR_00417218->priority = arg1;
+			if (PTR_00417218->tgtObjectId != -1) {
+				Object &obj = _objects[PTR_00417218->tgtObjectId];
+				obj.priority = arg1;
 			}
-			if (PTR_00417218->y != -1) {
-				Object &obj = _objects[PTR_00417218->y];
-				obj.fld_3 = arg1;
+			if (PTR_00417218->curObjectId != -1) {
+				Object &obj = _objects[PTR_00417218->curObjectId];
+				obj.priority = arg1;
 				addDirtRectOnObject(&obj);
 			}
 		}
@@ -2506,10 +2504,10 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 
 	case 30: {
-		if (PTR_00417218->y != -1) {
-			Object *obj = &_objects[PTR_00417218->y];
-			PTR_00417218->x = -1;
-			PTR_00417218->y = -1;
+		if (PTR_00417218->curObjectId != -1) {
+			Object *obj = &_objects[PTR_00417218->curObjectId];
+			PTR_00417218->tgtObjectId = -1;
+			PTR_00417218->curObjectId = -1;
 			removeObjectMarkDirty(obj);
 		}
 	} break;
@@ -2526,13 +2524,13 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 
 	case 33:
-		PTR_00417218->fld_5 = _statesHeight - PTR_00417218->blk;
+		PTR_00417218->priority = _statesHeight - PTR_00417218->cell.y;
 		ctx->EAX.setVal(1);
 		break;
 
 	case 34: {
 		VM::ValAddr regRef = ctx->popReg();
-		ctx->setMem8(regRef, PTR_00417218->fld_5);
+		ctx->setMem8(regRef, PTR_00417218->priority);
 		ctx->EAX.setVal(1);
 	} break;
 
@@ -3025,55 +3023,54 @@ uint32 GamosEngine::scriptFunc16(uint32 id) {
 
 bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 	Sprite &spr = _sprites[id];
-	Object *pobj = getFreeObject();
+	Object *gfxObj = getFreeObject();
 
-	pobj->flags |= Object::FLAG_GRAPHIC;
+	gfxObj->flags |= Object::FLAG_GRAPHIC;
 
 	if (spr.field_1 & 1)
-		pobj->flags |= Object::FLAG_DIRTRECT;
+		gfxObj->flags |= Object::FLAG_DIRTRECT;
 
-	pobj->fld_2 = spr.field_3;
-	int32 idx = 0xffff;
+	gfxObj->frameMax = spr.field_3;
+	int16 idx = -1;
 	if (!p)
 		idx = _curObjIndex;
 
-	pobj->pos = idx & 0xff;
-	pobj->blk = (idx >> 8) & 0xff;
-	pobj->x = x;
-	pobj->y = y;
+	gfxObj->actObjIndex = idx;
+	gfxObj->position.x = x;
+	gfxObj->position.y = y;
 
 	if (!p) {
 		if (!PTR_00417218) {
-			pobj->fld_3 = (PTR_00417214->unk1 >> 16) & 0xFF;
+			gfxObj->priority = (PTR_00417214->unk1 >> 16) & 0xFF;
 		} else {
-			int32 index = pobj->index;
-			if (PTR_00417218->y != -1) {
-				Object *oobj = &_objects[PTR_00417218->y];
-				addDirtRectOnObject(oobj);
-				oobj->flags &= ~Object::FLAG_GRAPHIC;
-				if (PTR_00417218->x != PTR_00417218->y)
-					removeObject(oobj);
+			int32 index = gfxObj->index;
+			if (PTR_00417218->curObjectId != -1) {
+				Object *pgObj = &_objects[PTR_00417218->curObjectId];
+				addDirtRectOnObject(pgObj);
+				pgObj->flags &= ~Object::FLAG_GRAPHIC;
+				if (PTR_00417218->tgtObjectId != PTR_00417218->curObjectId)
+					removeObject(pgObj);
 			}
 
-			PTR_00417218->y = index;
-			if (!(pobj->flags & Object::FLAG_DIRTRECT)) {
-				if (PTR_00417218->x != -1)
-					removeObject(&_objects[PTR_00417218->x]);
-				PTR_00417218->x = index;
+			PTR_00417218->curObjectId = index;
+			if (!(gfxObj->flags & Object::FLAG_DIRTRECT)) {
+				if (PTR_00417218->tgtObjectId != -1)
+					removeObject(&_objects[PTR_00417218->tgtObjectId]);
+				PTR_00417218->tgtObjectId = index;
 			}
 
-			pobj->fld_3 = PTR_00417218->fld_5;
+			gfxObj->priority = PTR_00417218->priority;
 			if (DAT_00417220 != DAT_00417228 || DAT_00417224 != DAT_0041722c) {
 				PTR_00417218->flags |= Object::FLAG_TRANSITION;
 			}
 		}
 	} else {
-		pobj->fld_3 = PTR_00417218->fld_5;
-		pobj->fld_4 = 0xff;
-		pobj->fld_5 = 0xff;
+		gfxObj->priority = PTR_00417218->priority;
+		gfxObj->cell.x = -1;
+		gfxObj->cell.y = -1;
 	}
 
-	FUN_00409378(id, pobj, p);
+	FUN_00409378(id, gfxObj, p);
 	return true;
 }
 
@@ -3082,11 +3079,12 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 	obj->actID = 0;
 	obj->frame = 0;
 	obj->sprId = sprId;
+	obj->seqId = 0;
 
 	Sprite &spr = _sprites[sprId];
 
+
 	if (spr.field_2 == 1) {
-		obj->seqId = 0;
 		obj->pImg = &spr.sequences[0]->operator[](0);
 		if (BYTE_004177f6 == 8) {
 			if (spr.field_1 & 2)
@@ -3095,71 +3093,68 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 			obj->flags |= Object::FLAG_FLIPV;
 		}
 	} else {
-		int frm = 0;
 		if (BYTE_004177f6 == 1) {
-			frm = 1;
+			obj->seqId = 1;
 			if (DAT_00417224 == DAT_0041722c && (spr.field_1 & 8))
-				frm = 0;
+				obj->seqId = 0;
 		} else if (BYTE_004177f6 == 2) {
-			frm = 3;
+			obj->seqId = 3;
 			if (DAT_0041722c < DAT_00417224)
-				frm = 2;
+				obj->seqId = 2;
 			else if (DAT_0041722c > DAT_00417224) {
-				frm = 4;
+				obj->seqId = 4;
 				if (spr.field_1 & 4) {
-					frm = 2;
+					obj->seqId = 2;
 					obj->flags |= Object::FLAG_FLIPV;
 				}
 			} else if (DAT_00417220 == DAT_00417228 && (spr.field_1 & 8))
-				frm = 0;
+				obj->seqId = 0;
 		} else if (BYTE_004177f6 == 4) {
-			frm = 5;
+			obj->seqId = 5;
 			if (DAT_00417224 == DAT_0041722c && (spr.field_1 & 8))
-				frm = 0;
+				obj->seqId = 0;
 			else if (spr.field_1 & 4) {
-				frm = 1;
+				obj->seqId = 1;
 				obj->flags |= Object::FLAG_FLIPV;
 			}
 		} else {
-			frm = 7;
+			obj->seqId = 7;
 			if (DAT_00417224 == DAT_0041722c) {
 				if ((spr.field_1 & 8) && DAT_00417220 == DAT_00417228)
-					frm = 0;
+					obj->seqId = 0;
 				else if (spr.field_1 & 2) {
-					frm = 3;
+					obj->seqId = 3;
 					obj->flags |= Object::FLAG_FLIPH;
 				}
 			} else {
 				if (DAT_0041722c < DAT_00417224) {
-					frm = 8;
+					obj->seqId = 8;
 					if (spr.field_1 & 2) {
-						frm = 2;
+						obj->seqId = 2;
 						obj->flags |= Object::FLAG_FLIPH;
 					}
 				} else {
-					frm = 6;
+					obj->seqId = 6;
 					if (spr.field_1 & 4) {
-						frm = 8;
+						obj->seqId = 8;
 						obj->flags |= Object::FLAG_FLIPV;
 
 						if (spr.field_1 & 2) {
-							frm = 2;
+							obj->seqId = 2;
 							obj->flags |= Object::FLAG_FLIPH;
 						}
 					} else if (spr.field_1 & 2) {
-						frm = 4;
+						obj->seqId = 4;
 						obj->flags |= Object::FLAG_FLIPH;
 					}
 				}
 			}
 		}
-
-		obj->pImg = &spr.sequences[frm]->operator[](0);
-		obj->seqId = frm;
+		obj->pImg = &spr.sequences[obj->seqId]->operator[](0);
 	}
 	if (!p) {
-		obj->fld_4 = DAT_00417228;
-		obj->fld_5 = DAT_0041722c;
+		obj->cell.x = DAT_00417228;
+		obj->cell.y = DAT_0041722c;
 		FUN_0040921c(obj);
 	} else {
 		obj->flags |= Object::FLAG_FREECOORDS;
@@ -3169,8 +3164,8 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 }
 
 void GamosEngine::FUN_004095a0(Object *obj) {
-	if (obj->y != -1) {
-		Object &yobj = _objects[obj->y];
+	if (obj->curObjectId != -1) {
+		Object &yobj = _objects[obj->curObjectId];
 		addDirtRectOnObject(&yobj);
 		if (DAT_00417228 != DAT_00417220 || DAT_0041722c != DAT_00417224)
 			obj->flags |= Object::FLAG_TRANSITION;
@@ -3179,12 +3174,12 @@ void GamosEngine::FUN_004095a0(Object *obj) {
 }
 
 void GamosEngine::removeSubtitles(Object *obj) {
-	if (obj->fld_3 & 2) {
-		obj->fld_3 &= ~2;
+	if (obj->state & 0x200) {
+		obj->state &= ~0x200;
 		//for (int index = obj->index; index < _objects.size(); index++) {
 		for (int index = 0; index < _objects.size(); index++) {
 			Object *pobj = &_objects[index];
-			if (pobj->isOverlayObject() && ((pobj->blk << 8) | pobj->pos) == obj->index)
+			if (pobj->isOverlayObject() && pobj->actObjIndex == obj->index)
 				removeObjectMarkDirty(pobj);
 		}
 	}
@@ -3228,11 +3223,11 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 
 
 bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
-	if (obj->y == -1)
+	if (obj->curObjectId == -1)
 		return false;
 
-	Object &robj = _objects[obj->y];
-	if (Common::Rect(robj.x, robj.y, robj.x + robj.pImg->image->surface.w, robj.y + robj.pImg->image->surface.h).contains(pos))
+	Object &gfxobj = _objects[obj->curObjectId];
+	if (Common::Rect(gfxobj.position.x, gfxobj.position.y, gfxobj.position.x + gfxobj.pImg->image->surface.w, gfxobj.position.y + gfxobj.pImg->image->surface.h).contains(pos))
 		return true;
 	return false;
 }
@@ -3263,19 +3258,19 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 			ObjectAction &action = _objectActions[obj.actID];
 			uint8 tp = action.unk1 & 0xff;
 			if (tp == 1)
-				obj.fld_4 = tmpb;
+				obj.inputFlag = tmpb;
 			else if (tp == 2)
-				obj.fld_4 = tmpb & 0x4f;
+				obj.inputFlag = tmpb & 0x4f;
 			else if (tp == 3) {
 				if (&obj == PTR_004121b4)
-					obj.fld_4 = tmpb & 0x4f;
+					obj.inputFlag = tmpb & 0x4f;
 				else
-					obj.fld_4 = 0;
+					obj.inputFlag = 0;
 			}
 
-			if ((!pobj || obj.fld_5 <= pobjF5) && FUN_00409600(&obj, actPos)) {
+			if ((!pobj || obj.priority <= pobjF5) && FUN_00409600(&obj, actPos)) {
 				actT = tp;
-				pobjF5 = obj.fld_5;
+				pobjF5 = obj.priority;
 				pobj = &obj;
 			}
 		}
@@ -3293,14 +3288,14 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 			else if (act2 == ACT2_81)
 				tmpb |= 0x20;
 
-			pobj->fld_4 = tmpb;
+			pobj->inputFlag = tmpb;
 		} else if (actT == 3 && (tmpb == 0x90 || tmpb == 0xa0)) {
 			PTR_004121b4 = pobj;
-			pobj->fld_4 = tmpb;
+			pobj->inputFlag = tmpb;
 		}
 
-		DAT_004173f4 = pobj->pos;
-		DAT_004173f0 = pobj->blk;
+		DAT_004173f4 = pobj->cell.x;
+		DAT_004173f0 = pobj->cell.y;
 	}
 
 	DAT_00417805 = act2;
@@ -3353,7 +3348,7 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 
 void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
 	removeSubtitles(PTR_00417218);
-	PTR_00417218->fld_3 |= 2;
+	PTR_00417218->state |= 0x200;
 
 	while (true) {
 		uint8 ib = ctx->getMem8(memtype, offset);
@@ -3431,26 +3426,25 @@ void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int
 }
 
 Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y) {
-	Object *obj = getFreeObject();
-	obj->flags |= Object::FLAG_GRAPHIC | Object::FLAG_OVERLAY | Object::FLAG_FREECOORDS;
-	obj->actID = 0;
-	obj->fld_2 = 1;
-	obj->fld_3 = PTR_00417218->fld_5;
-	obj->fld_4 = 0xff;
-	obj->fld_5 = 0xff;
-	obj->pos = _curObjIndex & 0xff;
-	obj->blk = (_curObjIndex >> 8) & 0xff;
-	obj->x = *pX;
-	obj->y = y;
-	obj->sprId = spr;
-	obj->seqId = 0;
-	obj->frame = frame - _sprites[spr].field_1;
-	obj->pImg = &_sprites[spr].sequences[obj->seqId]->operator[](obj->frame);
-
-	*pX += obj->pImg->image->surface.w - obj->pImg->xoffset;
-
-	addDirtRectOnObject(obj);
-	return obj;
+	Object *gfxObj = getFreeObject();
+	gfxObj->flags |= Object::FLAG_GRAPHIC | Object::FLAG_OVERLAY | Object::FLAG_FREECOORDS;
+	gfxObj->frame = 0;
+	gfxObj->frameMax = 1;
+	gfxObj->priority = PTR_00417218->priority;
+	gfxObj->cell.x = -1;
+	gfxObj->cell.y = -1;
+	gfxObj->actObjIndex = _curObjIndex;
+	gfxObj->position.x = *pX;
+	gfxObj->position.y = y;
+	gfxObj->sprId = spr;
+	gfxObj->seqId = 0;
+	gfxObj->frame = frame - _sprites[spr].field_1;
+	gfxObj->pImg = &_sprites[spr].sequences[gfxObj->seqId]->operator[](gfxObj->frame);
+
+	*pX += gfxObj->pImg->image->surface.w - gfxObj->pImg->xoffset;
+
+	addDirtRectOnObject(gfxObj);
+	return gfxObj;
 }
 
 bool GamosEngine::FUN_00402bc4() {
@@ -3494,8 +3488,8 @@ void GamosEngine::FUN_00407db8(uint8 p) {
 		DAT_00412c94 = DAT_004173f4;
 		DAT_00412c98 = DAT_004173f0;
 	}
-	DAT_00412c8c = (uint)PTR_00417218->pos;
-	DAT_00412c90 = (uint)PTR_00417218->blk;
+	DAT_00412c8c = PTR_00417218->cell.x;
+	DAT_00412c90 = PTR_00417218->cell.y;
 	INT_00412ca0 = -1;
 	INT_00412c9c = -1;
 	DAT_00417804 = 0;
@@ -4001,32 +3995,30 @@ void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
 	if (rnd)
 		val = _thing2[val].field_1[ 1 + rndRange16(_thing2[val].field_1[0]) ];
 
-	PTR_00417218->fld_2 = val;
-	PTR_00417218->fld_3 = 0x10;
+	PTR_00417218->state = 0x1000 | val;
 
 	ObjectAction &act = _objectActions[val];
-	executeScript(1, PTR_00417218->blk, PTR_00417218->pos, nullptr, -1, nullptr, &act, act.onCreateAddress);
+	executeScript(1, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onCreateAddress);
 }
 
 void GamosEngine::FUN_004025d0() {
-	if (PTR_00417218->fld_2 != 0xfe) {
-		ObjectAction &act = _objectActions[PTR_00417218->fld_2];
+	if ((PTR_00417218->state & 0xff) != 0xfe) {
+		ObjectAction &act = _objectActions[PTR_00417218->state & 0xff];
 
 		for (int i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];
 			if (obj.isStaticObject() &&
-			        obj.pos == 0xff && obj.blk == 0xff &&
-			        obj.fld_4 == PTR_00417218->pos &&
-			        obj.fld_5 == PTR_00417218->blk) {
+			        obj.actObjIndex == -1 &&
+			        obj.cell.x == PTR_00417218->cell.x &&
+			        obj.cell.y == PTR_00417218->cell.y) {
 
 				removeObjectMarkDirty(&obj);
 				break;
 			}
 		}
 
-		executeScript(PTR_00417218->fld_3 >> 4, PTR_00417218->blk, PTR_00417218->pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
-		PTR_00417218->fld_2 = 0xfe;
-		PTR_00417218->fld_3 = 0xf0;
+		executeScript(PTR_00417218->state >> 12, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+		PTR_00417218->state = 0xf0fe;
 	}
 }
 
@@ -4065,7 +4057,7 @@ bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
 bool GamosEngine::scrollAndDraw() {
 	if (_scrollTrackObj != -1) {
 		Object &obj = _objects[_scrollTrackObj];
-		Common::Point objPos(obj.pos * _gridCellW, obj.blk * _gridCellH);
+		Common::Point objPos(obj.cell.x * _gridCellW, obj.cell.y * _gridCellH);
 
 		Common::Rect objArea;
 		objArea.right = _scrollX + _width - (_scrollBorderR + 1) * _gridCellW;
@@ -4206,7 +4198,7 @@ int GamosEngine::txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int
 
 	if (_txtInputActive == false) {
 		removeSubtitles(PTR_00417218);
-		PTR_00417218->fld_3 |= 2;
+		PTR_00417218->state |= 0x200;
 		_txtInputVmOffset = offset;
 		_txtInputSpriteID = sprId;
 		_txtInputX = x;
@@ -4374,10 +4366,8 @@ bool GamosEngine::onTxtInputUpdate(uint8 c) {
 	for(int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if ((obj.flags & (Object::FLAG_GRAPHIC | Object::FLAG_VALID | Object::FLAG_HASACTION | Object::FLAG_TRANSITION)) == (Object::FLAG_GRAPHIC | Object::FLAG_VALID)) {
-			if ((obj.frame + 1 == obj.fld_2) && obj.pos != 255 && obj.blk != 255) {
-				int32 idx = (obj.blk << 8) | obj.pos;
-				obj.fld_4 = _objects[idx].pos;
-				obj.fld_5 = _objects[idx].blk;
+			if ((obj.frame + 1 == obj.frameMax) && obj.actObjIndex != -1) {
+				obj.cell = _objects[ obj.actObjIndex ].cell;
 			}
 			FUN_00402f34(false, false, &obj);
 		}
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 3025dcc4017..bbd25fc80db 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -209,25 +209,60 @@ struct Object {
 		FLAG_FLIPH = 8,
 		FLAG_DIRTRECT = 4,
 	};
-	/* additional data */
+
 	int16 index = 0;
+
+	uint8 flags = 0;
+	uint8 priority = 0;
+	Common::Point cell;
+
+	/* gfx */
 	int32 sprId = -1;
 	int32 seqId = -1;
-	int32 frame = -1;
+	int16 frame = -1;
+	int16 frameMax = -1;
+	Common::Point position;
+	int16 actObjIndex = -1;
 
-	uint8 flags = 0;
+	/* action */
 	uint8 actID = 0;
-	uint8 fld_2 = 0;
-	uint8 fld_3 = 0;
-	uint8 fld_4 = 0;
-	uint8 fld_5 = 0;
-	uint8 pos = 0xff;
-	uint8 blk = 0xff;
-	int16 x = 0;
-	int16 y = 0;
+	int16 state = 0;
+	uint8 inputFlag = 0;
+	int16 tgtObjectId = -1;
+	int16 curObjectId = -1;
+
 	ImagePos *pImg = nullptr;
 	Common::Array<byte> storage;
 
+
+	/*
+	Original object structures:
+
+	action:
+	flags   0
+	actID   1
+	state   2
+	inputFlag 4
+	priority  5
+	cell.x 6
+	cell.y 7
+	tgtObjectId 8
+	curObjectId 10
+	pStorage 12
+
+	gfx:
+	flags   0
+	frame   1
+	frameMax  2
+	priority  3
+	cell.x  4
+	cell.y  5
+	actObjIndex  6
+	position.x   8
+	position.y   10
+	pImg 12
+	*/
+
 	inline bool isActionObject() const { return (flags & (FLAG_HASACTION | FLAG_VALID)) == (FLAG_HASACTION | FLAG_VALID); };
 	inline bool isGraphicObject() const { return (flags & (FLAG_GRAPHIC | FLAG_VALID | FLAG_HASACTION)) == (FLAG_GRAPHIC | FLAG_VALID); };
 	inline bool isOverlayObject() const { return (flags & (FLAG_GRAPHIC | FLAG_OVERLAY | FLAG_FREECOORDS | FLAG_VALID | FLAG_HASACTION)) ==
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 71e62d99a93..0a908ff3672 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -33,7 +33,7 @@ void GamosEngine::storeToGameScreen(int id) {
 	int objCount = 0;
 	for (int i = 0; i < _objects.size(); i++) {
 		const Object &obj = _objects[i];
-		if ((obj.flags & 3) == 3 || (obj.flags & 7) == 1)
+		if ((obj.flags & 3) == 3 || (obj.flags & 7) == Object::FLAG_VALID)
 			objCount++;
 	}
 
@@ -42,23 +42,22 @@ void GamosEngine::storeToGameScreen(int id) {
 	for (int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 
-		if ((obj.flags & 3) == 3) {
+		if (obj.isActionObject()) {
 			const int refObjIdx = idx;
-			if (obj.x == -1) {
+			if (obj.tgtObjectId == -1) {
 				gs._savedObjects[idx] = obj;
 				gs._savedObjects[idx].index = idx;
 				obj.flags = 0;
 				idx++;
 			} else {
-				Object &drawObj = _objects[ obj.x ];
+				Object &drawObj = _objects[ obj.tgtObjectId ];
 				gs._savedObjects[idx] = obj;
 				gs._savedObjects[idx].index = idx;
-				gs._savedObjects[idx].x = idx + 1;
-				gs._savedObjects[idx].y = idx + 1;
+				gs._savedObjects[idx].tgtObjectId = idx + 1;
+				gs._savedObjects[idx].curObjectId = idx + 1;
 				gs._savedObjects[idx + 1] = drawObj;
 				gs._savedObjects[idx + 1].index = idx + 1;
-				gs._savedObjects[idx + 1].pos = idx & 0xff;
-				gs._savedObjects[idx + 1].blk = (idx >> 8) & 0xff;
+				gs._savedObjects[idx + 1].actObjIndex = idx;
 				obj.flags = 0;
 				drawObj.flags = 0;
 				idx += 2;
@@ -66,16 +65,15 @@ void GamosEngine::storeToGameScreen(int id) {
 
 			for (int j = 0; j < _objects.size(); j++) {
 				Object &lobj = _objects[ j ];
-				if ((lobj.flags & 7) == 1 && ((lobj.blk << 8) | lobj.pos) == obj.index) {
+				if ((lobj.flags & 7) == Object::FLAG_VALID && lobj.actObjIndex == obj.index) {
 					gs._savedObjects[idx] = lobj;
 					gs._savedObjects[idx].index = idx;
-					gs._savedObjects[idx].pos = refObjIdx & 0xff;
-					gs._savedObjects[idx].blk = (refObjIdx >> 8) & 0xff;
+					gs._savedObjects[idx].actObjIndex = refObjIdx;
 					lobj.flags = 0;
 					idx++;
 				}
 			}
-		} else if ((obj.flags & 7) == 1 && obj.pos == 0xff && obj.blk == 0xff) {
+		} else if ((obj.flags & 7) == Object::FLAG_VALID && obj.actObjIndex == -1) {
 			gs._savedObjects[idx] = obj;
 			gs._savedObjects[idx].index = idx;
 			obj.flags = 0;


Commit: f49fed5af90b110cdc567b12bd60237f08b41f16
    https://github.com/scummvm/scummvm/commit/f49fed5af90b110cdc567b12bd60237f08b41f16
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:57+01:00

Commit Message:
GAMOS: Rename FUN_00402654 to removeObjectAtCoords

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 1bc5465259c..6eecd984f5e 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1680,7 +1680,7 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
 		uint16 t = PTR_00417218->state;
 		_states.at(DAT_00417228, DAT_0041722c) = PTR_00417218->state & 0xf0ff;
 
-		FUN_00402654(0, DAT_00417224, DAT_00417220);
+		removeObjectAtCoords(Common::Point(DAT_00417220, DAT_00417224), false);
 
 		PTR_00417218->cell.x = DAT_00417220;
 		PTR_00417218->cell.y = DAT_00417224;
@@ -1712,7 +1712,7 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 
 	if ((e.flags & 1) == 0) {
 		if (oid == 0xfe) {
-			FUN_00402654(1, y, x);
+			removeObjectAtCoords(Common::Point(x, y), true);
 			if (_needReload)
 				return;
 
@@ -1742,14 +1742,14 @@ void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
 
 	ObjectAction &act = _objectActions[oid];
 	if ((act.unk1 & 0xff) == 0) {
-		FUN_00402654(1, y, x);
+		removeObjectAtCoords(Common::Point(x, y), true);
 		if (_needReload)
 			return;
 		obj = nullptr;
 		index = -1;
 		odat = nullptr;
 	} else {
-		FUN_00402654(0, y, x);
+		removeObjectAtCoords(Common::Point(x, y), false);
 		if (_needReload)
 			return;
 		obj = getFreeObject();
@@ -1792,8 +1792,8 @@ void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
 }
 
 
-void GamosEngine::FUN_00402654(int mode, int id, int pos) {
-	uint16 &rthing = _states.at(pos, id);
+void GamosEngine::removeObjectAtCoords(Common::Point cell, bool deleteGfxObj) {
+	uint16 &rthing = _states.at(cell);
 
 	uint8 actid = rthing & 0xff;
 
@@ -1808,7 +1808,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 		Object &obj = _objects[i];
 		if (obj.flags & Object::FLAG_VALID) {
 			if (obj.flags & Object::FLAG_HASACTION) {
-				if (obj.cell.x == pos && obj.cell.y == id) {
+				if (obj.cell == cell) {
 					removeObjectByIDMarkDirty(obj.curObjectId);
 					if (obj.curObjectId != obj.tgtObjectId)
 						removeObjectByIDMarkDirty(obj.tgtObjectId);
@@ -1818,13 +1818,13 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 					removeObject(&obj);
 					FUN_0040255c(&obj);
 					povar4 = &obj;
-					if (!mode || multidel)
+					if (!deleteGfxObj || multidel)
 						break;
 
 					multidel = true;
 				}
 			} else {
-				if (mode && obj.cell.x == pos && obj.cell.y == id &&
+				if (deleteGfxObj && obj.cell == cell &&
 				        obj.actObjIndex == -1 && (obj.flags & Object::FLAG_FREECOORDS) == 0) {
 
 					removeObjectMarkDirty(&obj);
@@ -1840,7 +1840,7 @@ void GamosEngine::FUN_00402654(int mode, int id, int pos) {
 	if (povar4)
 		rthing = povar4->state & 0xf0ff;
 
-	executeScript(rthing >> 12, id, pos, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+	executeScript(rthing >> 12, cell.y, cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
 }
 
 Object *GamosEngine::getFreeObject() {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index bbd25fc80db..fb7e70de428 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -656,7 +656,7 @@ protected:
 
 	void FUN_0040283c(ActEntry e, int32 x, int32 y);
 
-	void FUN_00402654(int mode, int id, int pos);
+	void removeObjectAtCoords(Common::Point cell, bool deleteGfxObj);
 
 	Object *getFreeObject();
 	void removeObject(Object *obj);


Commit: bc1a40d6939768481d8c47898d2e908485ffc131
    https://github.com/scummvm/scummvm/commit/bc1a40d6939768481d8c47898d2e908485ffc131
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:57+01:00

Commit Message:
GAMOS: Replace variables with Common::Point

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 6eecd984f5e..654bdf09583 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1277,23 +1277,20 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 	Common::Array<Common::Point> ARR_00412208(512);
 
 	if (!absolute) {
-		DAT_00417228 = PTR_00417218->cell.x;
-		DAT_0041722c = PTR_00417218->cell.y;
+		DAT_00417228 = PTR_00417218->cell;
 	} else {
 		PTR_00417218 = nullptr;
 		_curObjIndex = -1;
 		PTR_00417214 = nullptr;
 		//DAT_00417238 = 0;
 		//DAT_0041723c = -1;
-		DAT_0041722c = 0;
-		DAT_00417228 = 0;
+		DAT_00417228 = Common::Point();
 		BYTE_004177f6 = 1;
 		_preprocDataId = 0;
 		PTR_004173e8 = nullptr;
 	}
 
 	DAT_00417220 = DAT_00417228;
-	DAT_00417224 = DAT_0041722c;
 
 	int32 spos = -1;
 	int32 sbuf[6];
@@ -1337,8 +1334,8 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 				uint16 fb = 0;
 				if (!absolute) {
 					Common::Point xy;
-					xy.x = (e.x + DAT_00417220 + _statesWidth) % _statesWidth;
-					xy.y = (e.y + DAT_00417224 + _statesHeight) % _statesHeight;
+					xy.x = (e.x + DAT_00417220.x + _statesWidth) % _statesWidth;
+					xy.y = (e.y + DAT_00417220.y + _statesHeight) % _statesHeight;
 					fb = _states.at(xy);
 				} else {
 					fb = _states.at(e.x, e.y);
@@ -1660,32 +1657,31 @@ void GamosEngine::preprocessDataB1(int id, ActEntry *e) {
 int GamosEngine::processData(ActEntry e, bool absolute) {
 	preprocessData(_preprocDataId, &e);
 	if (!absolute) {
-		FUN_0040283c(e,
-		             (e.x + DAT_00417220 + _statesWidth) % _statesWidth,
-		             (e.y + DAT_00417224 + _statesHeight) % _statesHeight);
+		createActiveObject(e,
+		             (e.x + DAT_00417220.x + _statesWidth) % _statesWidth,
+		             (e.y + DAT_00417220.y + _statesHeight) % _statesHeight);
 		if (_needReload)
 			return 0;
 		return e.x == 0 && e.y == 0;
 	} else {
-		FUN_0040283c(e, e.x, e.y);
+		createActiveObject(e, e.x, e.y);
 		return 0;
 	}
 }
 
 void GamosEngine::FUN_00402a68(ActEntry e) {
 	if (e.x != 0 || e.y != 0) {
-		DAT_00417220 = (e.x + DAT_00417220 + _statesWidth) % _statesWidth;
-		DAT_00417224 = (e.y + DAT_00417224 + _statesHeight) % _statesHeight;
+		DAT_00417220.x = (e.x + DAT_00417220.x + _statesWidth) % _statesWidth;
+		DAT_00417220.y = (e.y + DAT_00417220.y + _statesHeight) % _statesHeight;
 
 		uint16 t = PTR_00417218->state;
-		_states.at(DAT_00417228, DAT_0041722c) = PTR_00417218->state & 0xf0ff;
+		_states.at(DAT_00417228) = PTR_00417218->state & 0xf0ff;
 
-		removeObjectAtCoords(Common::Point(DAT_00417220, DAT_00417224), false);
+		removeObjectAtCoords(DAT_00417220, false);
 
-		PTR_00417218->cell.x = DAT_00417220;
-		PTR_00417218->cell.y = DAT_00417224;
+		PTR_00417218->cell = DAT_00417220;
 
-		uint16 &rthing = _states.at(DAT_00417220, DAT_00417224);
+		uint16 &rthing = _states.at(DAT_00417220);
 
 		PTR_00417218->state = (t & 0xf00) | (rthing & 0xf0ff);
 
@@ -1698,14 +1694,14 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
 		BYTE_004177f6 = e.t;
 		PTR_00417218->flags = (PTR_00417218->flags & 0xf) | (e.t << 4);
 
-		uint16 &tref = _states.at(DAT_00417220, DAT_00417224);
+		uint16 &tref = _states.at(DAT_00417220);
 		tref = (tref & 0xff) | (BYTE_004177f6 << 12);
 
 		BYTE_00412200 = 1;
 	}
 }
 
-void GamosEngine::FUN_0040283c(ActEntry e, int32 x, int32 y) {
+void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 	uint16 &rthing = _states.at(x, y);
 
 	uint8 oid = e.value;
@@ -1909,20 +1905,18 @@ void GamosEngine::executeScript(uint8 p1, uint32 celly, uint32 cellx, byte *stor
 
 	uint8 sv1 = BYTE_004177f6;
 	byte *sv2 = PTR_004173e8;
-	int32 sv3 = DAT_0041722c;
-	int32 sv4 = DAT_00417228;
-	int32 sv5 = DAT_00417224;
-	int32 sv6 = DAT_00417220;
+	Common::Point sv4 = DAT_00417228;
+	Common::Point sv6 = DAT_00417220;
 	int32 sv7 = _curObjIndex;
 	Object *sv8 = PTR_00417218;
 	ObjectAction *sv9 = PTR_00417214;
 
 	BYTE_004177f6 = p1;
 	PTR_004173e8 = storage;
-	DAT_0041722c = celly;
-	DAT_00417228 = cellx;
-	DAT_00417224 = celly;
-	DAT_00417220 = cellx;
+	DAT_00417228.y = celly;
+	DAT_00417228.x = cellx;
+	DAT_00417220.y = celly;
+	DAT_00417220.x = cellx;
 	_curObjIndex = index;
 	PTR_00417218 = pobj;
 	PTR_00417214 = act;
@@ -1931,9 +1925,7 @@ void GamosEngine::executeScript(uint8 p1, uint32 celly, uint32 cellx, byte *stor
 
 	BYTE_004177f6 = sv1;
 	PTR_004173e8 = sv2;
-	DAT_0041722c = sv3;
-	DAT_00417228 = sv4 ;
-	DAT_00417224 = sv5;
+	DAT_00417228 = sv4;
 	DAT_00417220 = sv6;
 	_curObjIndex = sv7;
 	PTR_00417218 = sv8;
@@ -2436,7 +2428,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	case 21: {
 		VM::ValAddr regRef = ctx->popReg();
 		arg2 = ctx->pop32();
-		ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH) );
+		ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH) );
 	} break;
 
 	case 22: {
@@ -2449,7 +2441,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	case 23: {
 		VM::ValAddr regRef = ctx->popReg();
 		arg2 = ctx->pop32();
-		addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH);
+		addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH);
 		ctx->EAX.setVal(1);
 	} break;
 
@@ -2737,14 +2729,14 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 				tmp.value = 0xfe;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
-				FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
+				createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
 			} else if (arg1 == 2) {
 				ActEntry tmp;
 				tmp.value = 0;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
-				tmp.x = DAT_00412c94 - DAT_00412c8c;
-				tmp.y = DAT_00412c98 - DAT_00412c90;
+				tmp.x = DAT_00412c94.x - DAT_00412c8c.x;
+				tmp.y = DAT_00412c94.y - DAT_00412c8c.y;
 				FUN_00402a68(tmp);
 			}
 		}
@@ -2758,7 +2750,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			tmp.value = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 0;
-			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
+			createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
 		}
 		ctx->EAX.setVal(1);
 	} break;
@@ -2770,7 +2762,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			tmp.value = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 1;
-			FUN_0040283c(tmp, DAT_00412c94, DAT_00412c98);
+			createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
 		}
 		ctx->EAX.setVal(1);
 	} break;
@@ -3001,7 +2993,7 @@ void GamosEngine::callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint3
 
 uint32 GamosEngine::scriptFunc19(uint32 id) {
 	BYTE_004177fc = 1;
-	FUN_0040738c(id, DAT_00417220 * _gridCellW, DAT_00417224 * _gridCellH, false);
+	FUN_0040738c(id, DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH, false);
 
 	return 1;
 }
@@ -3060,7 +3052,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 			}
 
 			gfxObj->priority = PTR_00417218->priority;
-			if (DAT_00417220 != DAT_00417228 || DAT_00417224 != DAT_0041722c) {
+			if (DAT_00417220 != DAT_00417228) {
 				PTR_00417218->flags |= Object::FLAG_TRANSITION;
 			}
 		}
@@ -3095,23 +3087,23 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 	} else {
 		if (BYTE_004177f6 == 1) {
 			obj->seqId = 1;
-			if (DAT_00417224 == DAT_0041722c && (spr.field_1 & 8))
+			if (DAT_00417220.y == DAT_00417228.y && (spr.field_1 & 8))
 				obj->seqId = 0;
 		} else if (BYTE_004177f6 == 2) {
 			obj->seqId = 3;
-			if (DAT_0041722c < DAT_00417224)
+			if (DAT_00417228.y < DAT_00417220.y)
 				obj->seqId = 2;
-			else if (DAT_0041722c > DAT_00417224) {
+			else if (DAT_00417228.y > DAT_00417220.y) {
 				obj->seqId = 4;
 				if (spr.field_1 & 4) {
 					obj->seqId = 2;
 					obj->flags |= Object::FLAG_FLIPV;
 				}
-			} else if (DAT_00417220 == DAT_00417228 && (spr.field_1 & 8))
+			} else if (DAT_00417220.x == DAT_00417228.x && (spr.field_1 & 8))
 				obj->seqId = 0;
 		} else if (BYTE_004177f6 == 4) {
 			obj->seqId = 5;
-			if (DAT_00417224 == DAT_0041722c && (spr.field_1 & 8))
+			if (DAT_00417220.y == DAT_00417228.y && (spr.field_1 & 8))
 				obj->seqId = 0;
 			else if (spr.field_1 & 4) {
 				obj->seqId = 1;
@@ -3119,15 +3111,15 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 			}
 		} else {
 			obj->seqId = 7;
-			if (DAT_00417224 == DAT_0041722c) {
-				if ((spr.field_1 & 8) && DAT_00417220 == DAT_00417228)
+			if (DAT_00417220.y == DAT_00417228.y) {
+				if ((spr.field_1 & 8) && DAT_00417220.x == DAT_00417228.x)
 					obj->seqId = 0;
 				else if (spr.field_1 & 2) {
 					obj->seqId = 3;
 					obj->flags |= Object::FLAG_FLIPH;
 				}
 			} else {
-				if (DAT_0041722c < DAT_00417224) {
+				if (DAT_00417228.y < DAT_00417220.y) {
 					obj->seqId = 8;
 					if (spr.field_1 & 2) {
 						obj->seqId = 2;
@@ -3153,8 +3145,7 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 		obj->pImg = &spr.sequences[obj->seqId]->operator[](0);
 	}
 	if (!p) {
-		obj->cell.x = DAT_00417228;
-		obj->cell.y = DAT_0041722c;
+		obj->cell = DAT_00417228;
 		FUN_0040921c(obj);
 	} else {
 		obj->flags |= Object::FLAG_FREECOORDS;
@@ -3167,7 +3158,7 @@ void GamosEngine::FUN_004095a0(Object *obj) {
 	if (obj->curObjectId != -1) {
 		Object &yobj = _objects[obj->curObjectId];
 		addDirtRectOnObject(&yobj);
-		if (DAT_00417228 != DAT_00417220 || DAT_0041722c != DAT_00417224)
+		if (DAT_00417228 != DAT_00417220)
 			obj->flags |= Object::FLAG_TRANSITION;
 		FUN_00409378(yobj.sprId, &yobj, false);
 	}
@@ -3277,9 +3268,9 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	}
 
 	if (!pobj) {
-		DAT_004173f4 = actPos.x / _gridCellW;
-		DAT_004173f0 = actPos.y / _gridCellH;
-		DAT_00417803 = _states.at(DAT_004173f4, DAT_004173f0) & 0xff;
+		DAT_004173f0.x = actPos.x / _gridCellW;
+		DAT_004173f0.y = actPos.y / _gridCellH;
+		DAT_00417803 = _states.at(DAT_004173f0) & 0xff;
 	} else {
 		DAT_00417803 = actT;
 		if (actT == 2) {
@@ -3294,15 +3285,13 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 			pobj->inputFlag = tmpb;
 		}
 
-		DAT_004173f4 = pobj->cell.x;
-		DAT_004173f0 = pobj->cell.y;
+		DAT_004173f0 = pobj->cell;
 	}
 
 	DAT_00417805 = act2;
 	if (act2 == ACT2_82 || act2 == ACT2_83) {
 		DAT_004177fe = act2;
 		DAT_004177fd = DAT_00417803;
-		DAT_004173fc = DAT_004173f4;
 		DAT_004173f8 = DAT_004173f0;
 	} else {
 		if (act2 == ACT2_81)
@@ -3319,10 +3308,8 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 	//uVar11 = DAT_0041723c;
 	//uVar10 = DAT_00417238;
 	uint8 sv6 = _preprocDataId;
-	int32 sv7 = DAT_0041722c;
-	int32 sv8 = DAT_00417228;
-	int32 sv9 = DAT_00417224;
-	int32 sv10 = DAT_00417220;
+	Common::Point sv8 = DAT_00417228;
+	Common::Point sv10 = DAT_00417220;
 	int sv11 = _curObjIndex;
 	Object *sv12 = PTR_00417218;
 	ObjectAction *sv13 = PTR_00417214;
@@ -3335,9 +3322,7 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 	//DAT_0041723c = uVar11;
 	//DAT_00417238 = uVar10;
 	_preprocDataId = sv6;
-	DAT_0041722c = sv7;
 	DAT_00417228 = sv8;
-	DAT_00417224 = sv9;
 	DAT_00417220 = sv10;
 	_curObjIndex = sv11;
 	PTR_00417218 = sv12;
@@ -3481,15 +3466,12 @@ bool GamosEngine::FUN_00402bc4() {
 }
 
 void GamosEngine::FUN_00407db8(uint8 p) {
-	if ((p == 0x82) || (p == 0x83)) {
-		DAT_00412c94 = DAT_004173fc;
-		DAT_00412c98 = DAT_004173f8;
-	} else {
-		DAT_00412c94 = DAT_004173f4;
-		DAT_00412c98 = DAT_004173f0;
-	}
-	DAT_00412c8c = PTR_00417218->cell.x;
-	DAT_00412c90 = PTR_00417218->cell.y;
+	if ((p == 0x82) || (p == 0x83))
+		DAT_00412c94 = DAT_004173f8;
+	else
+		DAT_00412c94 = DAT_004173f0;
+
+	DAT_00412c8c = PTR_00417218->cell;
 	INT_00412ca0 = -1;
 	INT_00412c9c = -1;
 	DAT_00417804 = 0;
@@ -3562,7 +3544,7 @@ byte GamosEngine::FUN_0040856c() {
 				_pathMap.at(i, j) = 3;
 		}
 	}
-	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
+	_pathMap.at(DAT_00412c94) = 2;
 	return FUN_0040841c(false);
 }
 
@@ -3577,12 +3559,12 @@ byte GamosEngine::FUN_004085d8(uint8 p) {
 				_pathMap.at(i, j) = 3;
 		}
 	}
-	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
+	_pathMap.at(DAT_00412c94) = 2;
 	return FUN_0040841c(false);
 }
 
 byte GamosEngine::FUN_0040841c(bool p) {
-	_pathMap.at(DAT_00412c8c, DAT_00412c90) = 6;
+	_pathMap.at(DAT_00412c8c.x, DAT_00412c8c.y) = 6;
 
 	while (true) {
 		byte res = FUN_004081b8(6, 4);
@@ -3618,11 +3600,11 @@ byte GamosEngine::FUN_0040841c(bool p) {
 }
 
 byte GamosEngine::FUN_00407e2c() {
-	int32 iVar2 = DAT_00412c8c - DAT_00412c94;
+	int32 iVar2 = DAT_00412c8c.x - DAT_00412c94.x;
 	if (iVar2 < 1)
 		iVar2 = -iVar2;
 
-	int32 iVar1 = DAT_00412c90 - DAT_00412c98;
+	int32 iVar1 = DAT_00412c8c.y - DAT_00412c94.y;
 	if (iVar1 < 1)
 		iVar1 = -iVar1;
 
@@ -3632,39 +3614,39 @@ byte GamosEngine::FUN_00407e2c() {
 	if ((iVar2 == 0) || (iVar1 / iVar2) > 3) {
 		if (iVar1 > 1) {
 			INT_00412c9c = 4;
-			if (DAT_00412c98 <= DAT_00412c90)
+			if (DAT_00412c94.y <= DAT_00412c8c.y)
 				INT_00412c9c = 0;
 		}
 		INT_00412ca0 = 4;
-		if (DAT_00412c98 <= DAT_00412c90)
+		if (DAT_00412c94.y <= DAT_00412c8c.y)
 			INT_00412ca0 = 0;
 	} else if ((iVar1 == 0) || (iVar2 / iVar1) > 3) {
 		if (iVar2 > 1) {
 			INT_00412c9c = 2;
-			if (DAT_00412c94 <= DAT_00412c8c)
+			if (DAT_00412c94.x <= DAT_00412c8c.x)
 				INT_00412c9c = 6;
 		}
 		INT_00412ca0 = 2;
-		if (DAT_00412c94 <= DAT_00412c8c)
+		if (DAT_00412c94.x <= DAT_00412c8c.x)
 			INT_00412ca0 = 6;
 	} else {
-		if (DAT_00412c8c < DAT_00412c94) {
+		if (DAT_00412c8c.x < DAT_00412c94.x) {
 			INT_00412c9c = 3;
-			if (DAT_00412c98 <= DAT_00412c90)
+			if (DAT_00412c94.y <= DAT_00412c8c.y)
 				INT_00412c9c = 1;
 		} else {
 			INT_00412c9c = 5;
-			if (DAT_00412c98 <= DAT_00412c90)
+			if (DAT_00412c94.y <= DAT_00412c8c.y)
 				INT_00412c9c = 7;
 		}
 
 		if (iVar1 < iVar2) {
 			INT_00412ca0 = 2;
-			if (DAT_00412c94 <= DAT_00412c8c)
+			if (DAT_00412c94.x <= DAT_00412c8c.x)
 				INT_00412ca0 = 6;
 		} else {
 			INT_00412ca0 = 4;
-			if (DAT_00412c98 <= DAT_00412c90)
+			if (DAT_00412c94.y <= DAT_00412c8c.y)
 				INT_00412ca0 = 0;
 		}
 	}
@@ -3674,16 +3656,16 @@ byte GamosEngine::FUN_00407e2c() {
 }
 
 byte GamosEngine::FUN_00407f70(uint8 p) {
-	int32 x = DAT_00412c94;
-	int32 y = DAT_00412c98;
+	int32 x = DAT_00412c94.x;
+	int32 y = DAT_00412c94.y;
 	int32 px = -1;
 	int32 py = -1;
 
 	while (true) {
-		int32 xdist = DAT_00412c8c - x;
+		int32 xdist = DAT_00412c8c.x - x;
 		if (xdist < 1)
 			xdist = -xdist;
-		int32 ydist = DAT_00412c90 - y;
+		int32 ydist = DAT_00412c8c.y - y;
 		if (ydist < 1)
 			ydist = -ydist;
 
@@ -3728,7 +3710,7 @@ byte GamosEngine::FUN_00407f70(uint8 p) {
 			}
 		}
 
-		if (xx == DAT_00412c8c && yy == DAT_00412c90) {
+		if (xx == DAT_00412c8c.x && yy == DAT_00412c8c.y) {
 			INT_00412ca0 = 2;
 			if (x <= xx) {
 				INT_00412ca0 = 6;
@@ -3797,8 +3779,8 @@ byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
 				        (x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
 				        (y > 0 && _pathMap.at(x, y - 1) == cv) ||
 				        (y < _pathBottom && _pathMap.at(x, y + 1) == cv)) {
-					DAT_00412c94 = x;
-					DAT_00412c98 = y;
+					DAT_00412c94.x = x;
+					DAT_00412c94.y = y;
 					return 1;
 				}
 			}
@@ -3875,7 +3857,7 @@ byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
 				_pathMap.at(i, j) = 0;
 		}
 	}
-	_pathMap.at(DAT_00412c94, DAT_00412c98) = 2;
+	_pathMap.at(DAT_00412c94) = 2;
 	return FUN_0040841c(false);
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index fb7e70de428..7a5731930c2 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -513,20 +513,17 @@ private:
 
 	byte *PTR_004173e8 = nullptr;
 
-	int32 DAT_00417220 = 0;
-	int32 DAT_00417224 = 0;
-	int32 DAT_00417228 = 0;
-	int32 DAT_0041722c = 0;
+	Common::Point DAT_00417220;
+	Common::Point DAT_00417228;
 
 	byte *PTR_00417388 = nullptr;
 
 	int32 _curObjIndex = 0;
 
 
-	int32 DAT_004173f0 = 0;
-	int32 DAT_004173f4 = 0;
-	int32 DAT_004173f8 = 0;
-	int32 DAT_004173fc = 0;
+	Common::Point DAT_004173f0;
+	Common::Point DAT_004173f8;
+
 	uint8 DAT_00417803 = 0;
 	uint8 DAT_00417804 = 0;
 	uint8 DAT_00417805 = 0;
@@ -557,12 +554,10 @@ private:
 
 
 	/* path find ? */
-	int32 DAT_00412c8c = 0;
-	int32 DAT_00412c90 = 0;
-	int32 DAT_00412c94 = 0;
-	int32 DAT_00412c98 = 0;
-	int32 INT_00412c9c = 0;
-	int32 INT_00412ca0 = 0;
+	Common::Point DAT_00412c8c;
+	Common::Point DAT_00412c94;
+	int8 INT_00412c9c = 0;
+	int8 INT_00412ca0 = 0;
 
 	Array2D<uint8> _pathMap;
 	uint32 _statesCount = 0;
@@ -654,7 +649,7 @@ protected:
 
 	void FUN_00402a68(ActEntry e);
 
-	void FUN_0040283c(ActEntry e, int32 x, int32 y);
+	void createActiveObject(ActEntry e, int32 x, int32 y);
 
 	void removeObjectAtCoords(Common::Point cell, bool deleteGfxObj);
 


Commit: 4cbb3774bff18677d60ba0cedc1362f8363c2f68
    https://github.com/scummvm/scummvm/commit/4cbb3774bff18677d60ba0cedc1362f8363c2f68
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:58+01:00

Commit Message:
GAMOS: Split field in ObjectAction

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 654bdf09583..c4ba0a4e6ac 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -467,7 +467,10 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_20) {
 		if (dataSize != 4)
 			return false;
-		_objectActions[pid].unk1 = getU32(data);
+		_objectActions[pid].actType = data[0];
+		_objectActions[pid].mask = data[1];
+		_objectActions[pid].priority = data[2];
+		_objectActions[pid].storageSize = data[3] + 1;
 	} else if (tp == RESTP_21) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onCreateAddress = _loadedDataSize + p3;
@@ -1737,7 +1740,7 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 	byte *odat = nullptr;
 
 	ObjectAction &act = _objectActions[oid];
-	if ((act.unk1 & 0xff) == 0) {
+	if (act.actType == 0) {
 		removeObjectAtCoords(Common::Point(x, y), true);
 		if (_needReload)
 			return;
@@ -1752,7 +1755,7 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 		obj->flags = (e.t << 4) | Object::FLAG_VALID | Object::FLAG_HASACTION;
 		obj->actID = oid;
 		obj->inputFlag = 0;
-		obj->priority = (act.unk1 >> 16) & 0xff;
+		obj->priority = act.priority;
 		obj->cell.x = x;
 		obj->cell.y = y;
 		obj->tgtObjectId = -1;
@@ -1761,7 +1764,6 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
 			obj->state |= 0x100;
 
-		int storageSize = ((act.unk1 >> 24) & 0xff) + 1;
 		// if (storageSize < 5) {
 		//  obj->pImg = nullptr;
 		//  odat = &obj->pImg;
@@ -1771,10 +1773,10 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 		//  obj->flags |= 8;
 		// }
 		obj->storage.clear();
-		obj->storage.resize(storageSize, 0);
+		obj->storage.resize(act.storageSize, 0);
 		odat = obj->storage.data();
 		index = obj->index;
-		if ((act.unk1 & 0xff) == 3 && PTR_004121b4 == nullptr)
+		if (act.actType == 3 && PTR_004121b4 == nullptr)
 			PTR_004121b4 = obj;
 	}
 
@@ -1997,7 +1999,7 @@ bool GamosEngine::FUN_00402fb4() {
 
 						bool tmp = false;
 						for (int i = 0; i < 8; i++) {
-							if ((PTR_00417214->unk1 >> 8) & (1 << i)) {
+							if (PTR_00417214->mask & (1 << i)) {
 								int fncid = ((i & 3) + ivr8) & 3;
 								if (i > 3)
 									fncid += 4;
@@ -3033,7 +3035,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 	if (!p) {
 		if (!PTR_00417218) {
-			gfxObj->priority = (PTR_00417214->unk1 >> 16) & 0xFF;
+			gfxObj->priority = PTR_00417214->priority;
 		} else {
 			int32 index = gfxObj->index;
 			if (PTR_00417218->curObjectId != -1) {
@@ -3191,7 +3193,7 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 			if (robj.index > objIndex)
 				n++;
 
-			if (robj.isActionObject() && (_objectActions[robj.actID].unk1 & 0xff) == 3) {
+			if (robj.isActionObject() && _objectActions[robj.actID].actType == 3) {
 				if (n) {
 					PTR_004121b4 = &robj;
 					break;
@@ -3241,18 +3243,17 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 
 	Object *pobj = nullptr;
 	uint8 actT = 0;
-	uint8 pobjF5 = 0xff;
+	uint8 pobjF5 = 255;
 
 	for (int i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if (obj.isActionObject()) {
 			ObjectAction &action = _objectActions[obj.actID];
-			uint8 tp = action.unk1 & 0xff;
-			if (tp == 1)
+			if (action.actType == 1)
 				obj.inputFlag = tmpb;
-			else if (tp == 2)
+			else if (action.actType == 2)
 				obj.inputFlag = tmpb & 0x4f;
-			else if (tp == 3) {
+			else if (action.actType == 3) {
 				if (&obj == PTR_004121b4)
 					obj.inputFlag = tmpb & 0x4f;
 				else
@@ -3260,7 +3261,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 			}
 
 			if ((!pobj || obj.priority <= pobjF5) && FUN_00409600(&obj, actPos)) {
-				actT = tp;
+				actT = action.actType;
 				pobjF5 = obj.priority;
 				pobj = &obj;
 			}
@@ -4389,7 +4390,7 @@ void GamosEngine::dumpActions() {
 
 	int i = 0;
 	for (ObjectAction &act : _objectActions) {
-		f.writeString(Common::String::format("Act %d : %x\n", i, act.unk1));
+		f.writeString(Common::String::format("Act %d : actType %x mask %x priority %x storage size %x\n", i, act.actType, act.mask, act.priority, act.storageSize));
 		if (act.onCreateAddress != -1) {
 			t = _vm.disassembly(act.onCreateAddress);
 			f.writeString(Common::String::format("Script1 : \n%s\n", t.c_str()));
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 7a5731930c2..f8af39780b9 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -186,7 +186,10 @@ struct Actions {
 };
 
 struct ObjectAction {
-	uint32 unk1;
+	uint8 actType = 0; // input action type?
+	uint8 mask = 0;
+	uint8 priority = 0;
+	uint8 storageSize = 0;
 	int32 onCreateAddress = -1;
 	Common::Array< Actions > actions;
 	int32 onDeleteAddress = -1;


Commit: 56f2a5d8fbe805cdd3941e254fcec5d45c0373a9
    https://github.com/scummvm/scummvm/commit/56f2a5d8fbe805cdd3941e254fcec5d45c0373a9
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:58+01:00

Commit Message:
GAMOS: Split states uint16 into structure

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index c4ba0a4e6ac..45d6557c962 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -449,7 +449,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_19) {
 		if (BYTE_004177f7 == 0) {
 			for (int i = 0; i < _states.size(); i++)
-				_states.at(i) = 0xf0fe;
+				_states.at(i) = ObjState(0xfe, 0, 0xf);
 
 			DAT_004177f8 = 1;
 
@@ -1334,7 +1334,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 
 				preprocessData(_preprocDataId, &e);
 
-				uint16 fb = 0;
+				ObjState fb;
 				if (!absolute) {
 					Common::Point xy;
 					xy.x = (e.x + DAT_00417220.x + _statesWidth) % _statesWidth;
@@ -1344,24 +1344,21 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 					fb = _states.at(e.x, e.y);
 				}
 
-				uint8 lb = fb & 0xff;
-				uint8 hb = (fb >> 8) & 0xff;
-
 				int cval = 0;
 				int fnc = e.t;
 				if ((e.flags & 1) == 0) {
-					if (e.value == lb && ((hb >> 4) & e.t)) {
+					if (e.actid == fb.actid && (fb.t & e.t)) {
 						cval = 2;
 					}
-				} else if (lb != 0xfe &&
-				           (_thing2[e.value].field_0[(fb & 0xff) >> 3] & (1 << (fb & 7))) != 0) {
+				} else if (fb.actid != 0xfe &&
+				           (_thing2[e.actid].field_0[(fb.actid) >> 3] & (1 << (fb.actid & 7))) != 0) {
 
-					if (!_thing2[e.value].field_2.empty()) {
-						e.t = _thing2[e.value].field_2[lb] >> 4;
+					if (!_thing2[e.actid].field_2.empty()) {
+						e.t = _thing2[e.actid].field_2[fb.actid] >> 4;
 						preprocessData(fnc + 8, &e);
 					}
 
-					if ((hb >> 4) & e.t) {
+					if (fb.t & e.t) {
 						cval = 2;
 					}
 				}
@@ -1677,37 +1674,37 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
 		DAT_00417220.x = (e.x + DAT_00417220.x + _statesWidth) % _statesWidth;
 		DAT_00417220.y = (e.y + DAT_00417220.y + _statesHeight) % _statesHeight;
 
-		uint16 t = PTR_00417218->state;
-		_states.at(DAT_00417228) = PTR_00417218->state & 0xf0ff;
+		ObjState st = PTR_00417218->state;
+		_states.at(DAT_00417228) = ObjState(st.actid, 0, st.t);
 
 		removeObjectAtCoords(DAT_00417220, false);
 
 		PTR_00417218->cell = DAT_00417220;
 
-		uint16 &rthing = _states.at(DAT_00417220);
-
-		PTR_00417218->state = (t & 0xf00) | (rthing & 0xf0ff);
+		ObjState rthing = _states.at(DAT_00417220);
+		PTR_00417218->state = ObjState(rthing.actid, st.flags, rthing.t);
 
-		rthing = ((PTR_00417218->flags & 0xf0) << 8) | PTR_00417218->actID;
+		_states.at(DAT_00417220) = ObjState(PTR_00417218->actID, 0, PTR_00417218->t);
 
 		BYTE_00412200 = 1;
 	}
 
 	if (e.t != BYTE_004177f6) {
 		BYTE_004177f6 = e.t;
-		PTR_00417218->flags = (PTR_00417218->flags & 0xf) | (e.t << 4);
+		PTR_00417218->t = e.t;
 
-		uint16 &tref = _states.at(DAT_00417220);
-		tref = (tref & 0xff) | (BYTE_004177f6 << 12);
+		ObjState &stref = _states.at(DAT_00417220);
+		stref.flags = 0;
+		stref.t = BYTE_004177f6;
 
 		BYTE_00412200 = 1;
 	}
 }
 
 void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
-	uint16 &rthing = _states.at(x, y);
+	ObjState &stref = _states.at(x, y);
 
-	uint8 oid = e.value;
+	uint8 oid = e.actid;
 
 	if ((e.flags & 1) == 0) {
 		if (oid == 0xfe) {
@@ -1715,7 +1712,7 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 			if (_needReload)
 				return;
 
-			rthing = (e.t << 12) | (e.flags << 8) | e.value;
+			stref = e;
 			return;
 		}
 	} else {
@@ -1752,7 +1749,8 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 		if (_needReload)
 			return;
 		obj = getFreeObject();
-		obj->flags = (e.t << 4) | Object::FLAG_VALID | Object::FLAG_HASACTION;
+		obj->flags = Object::FLAG_VALID | Object::FLAG_HASACTION;
+		obj->t = e.t;
 		obj->actID = oid;
 		obj->inputFlag = 0;
 		obj->priority = act.priority;
@@ -1760,9 +1758,9 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 		obj->cell.y = y;
 		obj->tgtObjectId = -1;
 		obj->curObjectId = -1;
-		obj->state = rthing;
+		obj->state = stref;
 		if (PTR_00417218 && obj->index > PTR_00417218->index)
-			obj->state |= 0x100;
+			obj->state.flags |= 1;
 
 		// if (storageSize < 5) {
 		//  obj->pImg = nullptr;
@@ -1780,7 +1778,7 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 			PTR_004121b4 = obj;
 	}
 
-	rthing = (e.t << 12) | (e.flags << 8) | oid;
+	stref = ObjState(oid, e.flags, e.t);
 	executeScript(e.t, y, x, odat, index, obj, &act, act.onCreateAddress);
 }
 
@@ -1791,9 +1789,9 @@ void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
 
 
 void GamosEngine::removeObjectAtCoords(Common::Point cell, bool deleteGfxObj) {
-	uint16 &rthing = _states.at(cell);
+	ObjState &stref = _states.at(cell);
 
-	uint8 actid = rthing & 0xff;
+	uint8 actid = stref.actid;
 
 	if (actid == 0xfe)
 		return;
@@ -1836,9 +1834,9 @@ void GamosEngine::removeObjectAtCoords(Common::Point cell, bool deleteGfxObj) {
 	}
 
 	if (povar4)
-		rthing = povar4->state & 0xf0ff;
+		stref = ObjState(povar4->state.actid, 0, povar4->state.t);
 
-	executeScript(rthing >> 12, cell.y, cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+	executeScript(stref.t, cell.y, cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
 }
 
 Object *GamosEngine::getFreeObject() {
@@ -1871,7 +1869,8 @@ Object *GamosEngine::getFreeObject() {
 	obj->actObjIndex = -1;
 
 	obj->actID = 0;
-	obj->state = 0;
+	obj->t = 0;
+	obj->state = ObjState();
 	obj->inputFlag = 0;
 	obj->tgtObjectId = -1;
 	obj->curObjectId = -1;
@@ -1947,8 +1946,8 @@ bool GamosEngine::FUN_00402fb4() {
 
 		if (pobj->isActionObject()) {
 			if (!PTR_00417388 || (PTR_00417388[ pobj->actID >> 3 ] & (1 << (pobj->actID & 7)))) {
-				if (pobj->state & 0x100) {
-					pobj->state &= ~0x100;
+				if (pobj->state.flags & 1) {
+					pobj->state.flags &= ~1;
 				} else {
 					if ((pobj->flags & Object::FLAG_TRANSITION) == 0) {
 						if (pobj->curObjectId != -1 && FUN_00402f34(true, false, &_objects[pobj->curObjectId])) {
@@ -1987,7 +1986,7 @@ bool GamosEngine::FUN_00402fb4() {
 
 					DAT_00417804 = 0;
 					for (Actions &scr : PTR_00417214->actions) {
-						BYTE_004177f6 = PTR_00417218->flags >> 4;
+						BYTE_004177f6 = PTR_00417218->t;
 
 						int ivr8 = 0;
 						if (BYTE_004177f6 == 2)
@@ -2360,15 +2359,15 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
 	case 10:
-		ctx->EAX.setVal( (PTR_00417218->state & 0xff) == 0xfe ? 1 : 0 );
+		ctx->EAX.setVal( PTR_00417218->state.actid == 0xfe ? 1 : 0 );
 		break;
 	case 11:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (PTR_00417218->state & 0xff) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( PTR_00417218->state.actid == arg1 ? 1 : 0 );
 		break;
 	case 12:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( _thing2[arg1].field_0[ (PTR_00417218->state >> 3) & 0x1f ] & (1 << (PTR_00417218->state & 7)) );
+		ctx->EAX.setVal( _thing2[arg1].field_0[ PTR_00417218->state.actid >> 3 ] & (1 << (PTR_00417218->state.actid & 7)) );
 		break;
 	case 13: {
 		VM::ValAddr regRef = ctx->popReg();
@@ -2728,13 +2727,13 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 				DAT_004177fd = 255;
 			} else if (arg1 == 1) {
 				ActEntry tmp;
-				tmp.value = 0xfe;
+				tmp.actid = 0xfe;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
 				createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
 			} else if (arg1 == 2) {
 				ActEntry tmp;
-				tmp.value = 0;
+				tmp.actid = 0;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
 				tmp.x = DAT_00412c94.x - DAT_00412c8c.x;
@@ -2749,7 +2748,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		arg1 = ctx->pop32();
 		if (DAT_00417804) {
 			ActEntry tmp;
-			tmp.value = arg1;
+			tmp.actid = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 0;
 			createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
@@ -2761,7 +2760,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		arg1 = ctx->pop32();
 		if (DAT_00417804) {
 			ActEntry tmp;
-			tmp.value = arg1;
+			tmp.actid = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 1;
 			createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
@@ -2771,7 +2770,9 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 45:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (PTR_00417218->flags & arg1) ? 1 : 0 );
+		// Seems here needed only ->t ?
+		// In AiTi arg1 0x20, 0x40, 0x80
+		ctx->EAX.setVal( ((PTR_00417218->flags | (PTR_00417218->t << 4)) & arg1) ? 1 : 0 );
 		break;
 
 	case 46: {
@@ -3167,8 +3168,8 @@ void GamosEngine::FUN_004095a0(Object *obj) {
 }
 
 void GamosEngine::removeSubtitles(Object *obj) {
-	if (obj->state & 0x200) {
-		obj->state &= ~0x200;
+	if (obj->state.flags & 2) {
+		obj->state.flags &= ~2;
 		//for (int index = obj->index; index < _objects.size(); index++) {
 		for (int index = 0; index < _objects.size(); index++) {
 			Object *pobj = &_objects[index];
@@ -3271,7 +3272,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	if (!pobj) {
 		DAT_004173f0.x = actPos.x / _gridCellW;
 		DAT_004173f0.y = actPos.y / _gridCellH;
-		DAT_00417803 = _states.at(DAT_004173f0) & 0xff;
+		DAT_00417803 = _states.at(DAT_004173f0).actid;
 	} else {
 		DAT_00417803 = actT;
 		if (actT == 2) {
@@ -3334,7 +3335,7 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 
 void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
 	removeSubtitles(PTR_00417218);
-	PTR_00417218->state |= 0x200;
+	PTR_00417218->state.flags |= 2;
 
 	while (true) {
 		uint8 ib = ctx->getMem8(memtype, offset);
@@ -3508,8 +3509,8 @@ byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
 byte GamosEngine::FUN_004084bc(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
-			if ((th1 & 0xff) != p)
+			const uint8 id = _states.at(i, j).actid;
+			if (id != p)
 				_pathMap.at(i, j) = 0;
 			else
 				_pathMap.at(i, j) = 2;
@@ -3521,11 +3522,11 @@ byte GamosEngine::FUN_004084bc(uint8 p) {
 byte GamosEngine::FUN_00408510(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
+			const uint8 id = _states.at(i, j).actid;
 
-			if ((th1 & 0xff) == 0xfe)
+			if (id == 0xfe)
 				_pathMap.at(i, j) = 0;
-			else if ((th1 & 0xff) == p)
+			else if (id == p)
 				_pathMap.at(i, j) = 2;
 			else
 				_pathMap.at(i, j) = 3;
@@ -3537,9 +3538,9 @@ byte GamosEngine::FUN_00408510(uint8 p) {
 byte GamosEngine::FUN_0040856c() {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
+			uint8 id = _states.at(i, j).actid;
 
-			if ((th1 & 0xff) == 0xfe)
+			if (id == 0xfe)
 				_pathMap.at(i, j) = 0;
 			else
 				_pathMap.at(i, j) = 3;
@@ -3552,9 +3553,9 @@ byte GamosEngine::FUN_0040856c() {
 byte GamosEngine::FUN_004085d8(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
+			uint8 id = _states.at(i, j).actid;
 
-			if ((th1 & 0xff) == p)
+			if (id == p)
 				_pathMap.at(i, j) = 0;
 			else
 				_pathMap.at(i, j) = 3;
@@ -3822,9 +3823,9 @@ byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
 byte GamosEngine::FUN_004086e4(const Common::Array<byte> &arr) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
+			const uint8 id = _states.at(i, j).actid;
 
-			if ( ((arr[th1 >> 3]) & (1 << (th1 & 7))) == 0 )
+			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
 				_pathMap.at(i, j) = 0;
 			else
 				_pathMap.at(i, j) = 2;
@@ -3836,9 +3837,9 @@ byte GamosEngine::FUN_004086e4(const Common::Array<byte> &arr) {
 byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
+			const uint8 id = _states.at(i, j).actid;
 
-			if ( ((arr[th1 >> 3]) & (1 << (th1 & 7))) == 0 )
+			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
 				_pathMap.at(i, j) = 3;
 			else
 				_pathMap.at(i, j) = 2;
@@ -3850,9 +3851,9 @@ byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
 byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
-			uint16 th1 = _states.at(i, j);
+			const uint8 id = _states.at(i, j).actid;
 
-			if ( ((arr[th1 >> 3]) & (1 << (th1 & 7))) == 0 )
+			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
 				_pathMap.at(i, j) = 3;
 			else
 				_pathMap.at(i, j) = 0;
@@ -3879,7 +3880,7 @@ void Actions::parse(const byte *data, size_t dataSize) {
 	flags = rstream.readByte();
 
 	uint8 tmp = rstream.readByte();
-	act_4.value = 0;
+	act_4.actid = 0;
 	act_4.flags = 0;
 	act_4.t = tmp >> 4;
 	act_4.x = rstream.readSByte();
@@ -3905,7 +3906,7 @@ void Actions::parse(const byte *data, size_t dataSize) {
 
 			for (uint16 i = 0; i < num; i++) {
 				ActEntry &a = entrie.entries[i];
-				a.value = rstream.readByte();
+				a.actid = rstream.readByte();
 				tmp = rstream.readByte();
 				a.flags = tmp & 0xf;
 				a.t = tmp >> 4;
@@ -3938,7 +3939,7 @@ void Actions::parse(const byte *data, size_t dataSize) {
 					act_10end[j].resize(num);
 					for (uint16 i = 0; i < num; i++) {
 						ActEntry &a = act_10end[j][i];
-						a.value = rstream.readByte();
+						a.actid = rstream.readByte();
 						tmp = rstream.readByte();
 						a.flags = tmp & 0xf;
 						a.t = tmp >> 4;
@@ -3958,7 +3959,7 @@ void Actions::parse(const byte *data, size_t dataSize) {
 
 			for (uint16 i = 0; i < num; i++) {
 				ActEntry &a = entrie.entries[i];
-				a.value = rstream.readByte();
+				a.actid = rstream.readByte();
 				tmp = rstream.readByte();
 				a.flags = tmp & 0xf;
 				a.t = tmp >> 4;
@@ -3978,15 +3979,15 @@ void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
 	if (rnd)
 		val = _thing2[val].field_1[ 1 + rndRange16(_thing2[val].field_1[0]) ];
 
-	PTR_00417218->state = 0x1000 | val;
+	PTR_00417218->state = ObjState(val, 0, 1);
 
 	ObjectAction &act = _objectActions[val];
 	executeScript(1, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onCreateAddress);
 }
 
 void GamosEngine::FUN_004025d0() {
-	if ((PTR_00417218->state & 0xff) != 0xfe) {
-		ObjectAction &act = _objectActions[PTR_00417218->state & 0xff];
+	if (PTR_00417218->state.actid != 0xfe) {
+		ObjectAction &act = _objectActions[PTR_00417218->state.actid];
 
 		for (int i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];
@@ -4000,8 +4001,8 @@ void GamosEngine::FUN_004025d0() {
 			}
 		}
 
-		executeScript(PTR_00417218->state >> 12, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
-		PTR_00417218->state = 0xf0fe;
+		executeScript(PTR_00417218->state.t, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+		PTR_00417218->state = ObjState(0xfe, 0, 0xf);
 	}
 }
 
@@ -4181,7 +4182,7 @@ int GamosEngine::txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int
 
 	if (_txtInputActive == false) {
 		removeSubtitles(PTR_00417218);
-		PTR_00417218->state |= 0x200;
+		PTR_00417218->state.flags |= 2;
 		_txtInputVmOffset = offset;
 		_txtInputSpriteID = sprId;
 		_txtInputX = x;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index f8af39780b9..b6678cc1a31 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -146,10 +146,20 @@ struct Unknown1 {
 	uint32 field_3;
 };
 
-struct ActEntry {
-	uint8 value = 0;
+struct ObjState {
+	uint8 actid = 0;
 	uint8 flags = 0;
 	uint8 t = 0;
+
+	ObjState() = default;
+	ObjState(const ObjState&) = default;
+	ObjState(ObjState&&) = default;
+	ObjState& operator=(const ObjState&) = default;
+
+	ObjState(uint8 aa, uint8 af, uint8 at): actid(aa), flags(af), t(at) {};
+};
+
+struct ActEntry: ObjState {
 	int8 x = 0;
 	int8 y = 0;
 };
@@ -229,7 +239,8 @@ struct Object {
 
 	/* action */
 	uint8 actID = 0;
-	int16 state = 0;
+	uint8 t = 0;
+	ObjState state;
 	uint8 inputFlag = 0;
 	int16 tgtObjectId = -1;
 	int16 curObjectId = -1;
@@ -285,7 +296,7 @@ struct GameScreen {
 	Graphics::Surface _bkgImage;
 	byte *palette = nullptr;
 
-	Array2D<uint16> _savedStates;
+	Array2D<ObjState> _savedStates;
 	Common::Array<Object> _savedObjects;
 
 	RawData _bkgImageData;
@@ -491,7 +502,7 @@ private:
 	uint32 _statesWidth = 0;
 	uint32 _statesHeight = 0;
 	uint32 _statesShift = 0;
-	Array2D<uint16> _states;
+	Array2D<ObjState> _states;
 
 
 	uint8 _preprocDataId = 0;


Commit: 67b70b62db2066ea0b06ac4db12be5fe7e8482d0
    https://github.com/scummvm/scummvm/commit/67b70b62db2066ea0b06ac4db12be5fe7e8482d0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:58+01:00

Commit Message:
GAMOS: Implement internal save/load

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 45d6557c962..655368c6401 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -252,7 +252,7 @@ bool GamosEngine::loadModule(uint id) {
 	//DAT_004126e4 = 1;
 	_currentGameScreen = -1;
 	_readingBkgMainId = -1;
-	//DAT_004172f8 = 0;
+	_countReadedBkg = 0;
 	//DAT_004126ec = 0;
 	//INT_004126e8 = 0;
 
@@ -327,6 +327,7 @@ bool GamosEngine::loadModule(uint id) {
 			} else if (prevByte == RESTP_18) {
 				/* free elements ? */
 				_readingBkgOffset = _arch.pos();
+				_countReadedBkg++;
 			}
 
 			RawData data;
@@ -1876,6 +1877,7 @@ Object *GamosEngine::getFreeObject() {
 	obj->curObjectId = -1;
 
 	obj->pImg = nullptr;
+	obj->storage.clear(); // clear it so gfx object will not have data
 	return obj;
 }
 
@@ -2864,7 +2866,13 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		arg1 = ctx->pop32();
 		arg2 = ctx->pop32();
 
-		warning("Do save-load %d %d", arg1, arg2);
+		if (arg1 == 0) {
+			ctx->EAX.setVal(deleteSaveFile(arg2) ? 1 : 0);
+		} else if (arg1 == 1) {
+			ctx->EAX.setVal(writeSaveFile(arg2) ? 1 : 0);
+		} else if (arg1 == 2) {
+			ctx->EAX.setVal(loadSaveFile(arg2) ? 1 : 0);
+		}
 	}
 	break;
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index b6678cc1a31..9c574418412 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -486,6 +486,7 @@ private:
 
 	uint32 _readingBkgOffset = 0;
 	int32 _readingBkgMainId = -1;
+	int32 _countReadedBkg = 0;
 	int32 _currentGameScreen = -1;
 	int32 _loadedDataSize = -1;
 
@@ -761,6 +762,13 @@ protected:
 	bool loadStateFile();
 	void loadStateData(Common::SeekableReadStream *stream);
 
+	bool writeSaveFile(int id);
+	bool loadSaveFile(int id);
+	bool deleteSaveFile(int id);
+
+	void writeObjectData(Common::SeekableWriteStream *stream, const Object *obj);
+	void loadObjectData(Common::SeekableReadStream *stream, Object *obj);
+
 	void vmCallDispatcher(VM::Context *ctx, uint32 funcID);
 
 
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 0a908ff3672..3b229ea3ceb 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -303,4 +303,220 @@ void GamosEngine::zeroVMData(const Common::Array<XorArg> &seq) {
 		_vm.zeroMemory(xarg.pos, xarg.len);
 }
 
+
+
+
+bool GamosEngine::writeSaveFile(int id) {
+	Common::String fname = makeSaveName(getGameId(), id, "sav");
+	Common::SaveFileManager *sm = _system->getSavefileManager();
+
+	Common::OutSaveFile *osv = sm->openForSaving(fname);
+	if (!osv)
+		return false;
+
+	storeToGameScreen(_currentGameScreen);
+	_svFps = _vm.memory().getU8(_addrFPS);
+	_svFrame = _vm.memory().getU32(_addrCurrentFrame);
+	_d2_fld10 = _countReadedBkg;
+	_svModuleId = _currentModuleID;
+	_svGameScreen = _currentGameScreen;
+
+	writeStateData(osv);
+
+	writeVMData(osv, _xorSeq[0]);
+	writeVMData(osv, _xorSeq[1]);
+	writeVMData(osv, _xorSeq[2]);
+
+	for (int i = 0; i < _gameScreens.size(); i++) {
+		GameScreen &scr = _gameScreens[i];
+
+		osv->writeUint32LE(i);
+
+		for (int j = 0; j < scr._savedStates.size(); j++) {
+			const ObjState &ost = scr._savedStates[j];
+			osv->writeByte(ost.actid);
+			osv->writeByte(ost.flags);
+			osv->writeByte(ost.t);
+		}
+
+		osv->writeUint32LE(scr._savedObjects.size());
+
+		for (const Object &obj : scr._savedObjects) {
+			writeObjectData(osv, &obj);
+		}
+	}
+
+	osv->finalize();
+	delete osv;
+
+	switchToGameScreen(_currentGameScreen, true);
+	return true;
+}
+
+bool GamosEngine::loadSaveFile(int id) {
+	Common::String fname = makeSaveName(getGameId(), id, "sav");
+	Common::SaveFileManager *sm = _system->getSavefileManager();
+
+	Common::SeekableReadStream *rs = sm->openForLoading(fname);
+	if (!rs)
+		return false;
+
+	const uint8 sv1 = _d2_fld18;
+	const uint8 sv2 = _d2_fld17;
+	const uint8 sv3 = _d2_fld16;
+	const bool svmdi = _enableMidi;
+	const uint8 sv4 = _d2_fld14;
+
+	loadStateData(rs);
+
+	_sndVolume = _sndVolumeTarget;
+	_midiVolume = 0;
+	_d2_fld14 = sv4;
+	_enableMidi = svmdi;
+	_d2_fld16 = sv3;
+	_d2_fld17 = sv2;
+	_d2_fld18 = sv1;
+
+	_musicPlayer.setVolume(0);
+
+	const int32 cursorImgId = _mouseCursorImgId;
+	const int32 svMidiTrack = _midiTrack;
+	const uint8 cdtrack = _d2_fld19;
+
+	_runReadDataMod = true;
+	BYTE_004177f7 = 1;
+
+	loadModule(_svModuleId);
+
+	readVMData(rs, _xorSeq[0]);
+	readVMData(rs, _xorSeq[1]);
+	readVMData(rs, _xorSeq[2]);
+
+	for (int i = 0; i < _countReadedBkg; i++) {
+		uint32 val = rs->readUint32LE();
+		GameScreen &scr = _gameScreens[val];
+
+		scr._savedStates.resize( _states.sizes() );
+
+		for (int j = 0; j < scr._savedStates.size(); j++) {
+			ObjState &st = scr._savedStates[j];
+			st.actid = rs->readByte();
+			st.flags = rs->readByte();
+			st.t = rs->readByte();
+		}
+
+		val = rs->readUint32LE();
+
+		scr._savedObjects.resize(val);
+
+		for (Object &obj : scr._savedObjects) {
+			loadObjectData(rs, &obj);
+			if (((obj.flags & Object::FLAG_HASACTION) == 0) && obj.sprId >= 0 && obj.frame >= 0 && obj.seqId >= 0) {
+				obj.pImg = &_sprites[obj.sprId].sequences[obj.seqId]->operator[](obj.frame);
+			}
+		}
+	}
+
+	delete rs;
+
+	switchToGameScreen(_svGameScreen, false);
+
+	_vm.memory().setU8(_addrFPS, _svFps);
+	_vm.memory().setU32(_addrCurrentFrame, _svFrame);
+
+	_runReadDataMod = false;
+	BYTE_004177f7 = 0;
+
+	if (cdtrack != 0xff) {
+		//vmfunc_58(cdtrack);
+	}
+
+	if (svMidiTrack != -1)
+		scriptFunc16(svMidiTrack);
+
+	_midiVolume = 0;
+
+	if (cursorImgId != -1)
+		setCursor(cursorImgId, false);
+
+	setNeedReload();
+	return true;
+}
+
+void GamosEngine::writeObjectData(Common::SeekableWriteStream *stream, const Object *obj) {
+	stream->writeUint16LE(obj->index);
+	stream->writeByte(obj->flags);
+	stream->writeByte(obj->priority);
+	stream->writeSint16LE(obj->cell.x);
+	stream->writeSint16LE(obj->cell.y);
+
+	if (obj->flags & Object::FLAG_HASACTION) {
+		stream->writeByte(obj->actID);
+		stream->writeByte(obj->t);
+		stream->writeByte(obj->state.actid);
+		stream->writeByte(obj->state.flags);
+		stream->writeByte(obj->state.t);
+		stream->writeByte(obj->inputFlag);
+		stream->writeSint16LE(obj->tgtObjectId);
+		stream->writeSint16LE(obj->curObjectId);
+		stream->writeUint32LE(obj->storage.size());
+		stream->write(obj->storage.data(), obj->storage.size());
+	} else {
+		stream->writeSint32LE(obj->sprId);
+		stream->writeSint32LE(obj->seqId);
+		stream->writeSint16LE(obj->frame);
+		stream->writeSint16LE(obj->frameMax);
+		stream->writeSint16LE(obj->position.x);
+		stream->writeSint16LE(obj->position.y);
+		stream->writeSint16LE(obj->actObjIndex);
+	}
+}
+
+void GamosEngine::loadObjectData(Common::SeekableReadStream *stream, Object *obj) {
+	obj->index = stream->readUint16LE();
+	obj->flags = stream->readByte();
+	obj->priority = stream->readByte();
+	obj->cell.x = stream->readSint16LE();
+	obj->cell.y = stream->readSint16LE();
+
+	if (obj->flags & Object::FLAG_HASACTION) {
+		obj->actID = stream->readByte();
+		obj->t = stream->readByte();
+		obj->state.actid = stream->readByte();
+		obj->state.flags = stream->readByte();
+		obj->state.t = stream->readByte();
+		obj->inputFlag = stream->readByte();
+		obj->tgtObjectId = stream->readSint16LE();
+		obj->curObjectId = stream->readSint16LE();
+
+		uint32 storSize = stream->readUint32LE();
+		if (storSize) {
+			obj->storage.resize(storSize);
+			stream->read(obj->storage.data(), storSize);
+		} else
+			obj->storage.clear();
+	} else {
+		obj->sprId = stream->readSint32LE();
+		obj->seqId = stream->readSint32LE();
+		obj->frame = stream->readSint16LE();
+		obj->frameMax = stream->readSint16LE();
+		obj->position.x = stream->readSint16LE();
+		obj->position.y = stream->readSint16LE();
+		obj->actObjIndex = stream->readSint16LE();
+	}
+}
+
+
+bool GamosEngine::deleteSaveFile(int id) {
+	Common::String fname = makeSaveName(getGameId(), id, "sav");
+	Common::SaveFileManager *sm = _system->getSavefileManager();
+
+	if ( !sm->exists(fname) )
+		return true;
+
+	if ( sm->removeSavefile(fname) )
+		return true;
+	return false;
+}
+
 }


Commit: 224ed5b234b6f2c607d216d56913b20dd4f75a4b
    https://github.com/scummvm/scummvm/commit/224ed5b234b6f2c607d216d56913b20dd4f75a4b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:59+01:00

Commit Message:
GAMOS: Set default scroll parameters on load

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 655368c6401..3083bf7ef80 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -310,7 +310,16 @@ bool GamosEngine::loadModule(uint id) {
 				if (_runReadDataMod && BYTE_004177f7 == 0)
 					readData2(data);
 				if (BYTE_004177f7 == 0) {
-					//FUN_00403868();
+					_scrollY = 0;
+					_scrollX = 0;
+					_scrollTrackObj = -1;
+					_scrollSpeed = 16;
+					_scrollCutoff = 80;
+					_scrollSpeedReduce = -1;
+					_scrollBorderB = 0;
+					_scrollBorderU = 0;
+					_scrollBorderR = 0;
+					_scrollBorderL = 0;
 				}
 				isResource = false; /* do not loadResHandler */
 			} else if (prevByte == RESTP_10) {


Commit: 7fd6c2d095fdb317d3c978ea23d9b5c66ff95821
    https://github.com/scummvm/scummvm/commit/7fd6c2d095fdb317d3c978ea23d9b5c66ff95821
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:59+01:00

Commit Message:
GAMOS: Process for save only loaded screens

Changed paths:
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 3b229ea3ceb..761b7045645 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -330,19 +330,21 @@ bool GamosEngine::writeSaveFile(int id) {
 	for (int i = 0; i < _gameScreens.size(); i++) {
 		GameScreen &scr = _gameScreens[i];
 
-		osv->writeUint32LE(i);
-
-		for (int j = 0; j < scr._savedStates.size(); j++) {
-			const ObjState &ost = scr._savedStates[j];
-			osv->writeByte(ost.actid);
-			osv->writeByte(ost.flags);
-			osv->writeByte(ost.t);
-		}
+		if (scr.loaded) {
+			osv->writeUint32LE(i);
+
+			for (int j = 0; j < scr._savedStates.size(); j++) {
+				const ObjState &ost = scr._savedStates[j];
+				osv->writeByte(ost.actid);
+				osv->writeByte(ost.flags);
+				osv->writeByte(ost.t);
+			}
 
-		osv->writeUint32LE(scr._savedObjects.size());
+			osv->writeUint32LE(scr._savedObjects.size());
 
-		for (const Object &obj : scr._savedObjects) {
-			writeObjectData(osv, &obj);
+			for (const Object &obj : scr._savedObjects) {
+				writeObjectData(osv, &obj);
+			}
 		}
 	}
 


Commit: 95d0af9e7be26ef5349d80ef6318c781f41324e6
    https://github.com/scummvm/scummvm/commit/95d0af9e7be26ef5349d80ef6318c781f41324e6
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:02:59+01:00

Commit Message:
GAMOS: Remove unused commented variables and set missing _midiVolumeTarget in vm funcs

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 3083bf7ef80..23aa20b9eff 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -650,17 +650,15 @@ bool GamosEngine::init(const Common::String &moduleName) {
 
 bool GamosEngine::loadInitModule() {
 	rndSeed(_system->getMillis());
-	//DAT_0041723c = -1;
 	_curObjIndex = -1;
 	PTR_00417218 = nullptr;
 	PTR_00417214 = nullptr;
-	//DAT_00417238 = 0;
 	_xorSeq[2].clear();
 	_xorSeq[1].clear();
 	_xorSeq[0].clear();
 	_isMoviePlay = 0;
 	_txtInputActive = false;
-	//DAT_00417808 = 0;
+	//_updateMouse = false;
 	_runReadDataMod = true;
 	_savedSndVolume = 0;
 	_savedMidiVolume = 0;
@@ -1295,8 +1293,6 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 		PTR_00417218 = nullptr;
 		_curObjIndex = -1;
 		PTR_00417214 = nullptr;
-		//DAT_00417238 = 0;
-		//DAT_0041723c = -1;
 		DAT_00417228 = Common::Point();
 		BYTE_004177f6 = 1;
 		_preprocDataId = 0;
@@ -2808,7 +2804,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			break;
 
 		case 2:
-			ctx->EAX.setVal(1); //BYTE_004177fb != 0 ? 1 : 0;
+			ctx->EAX.setVal(_midiVolumeTarget != 0 ? 1 : 0);
 			break;
 
 		case 3:
@@ -3324,8 +3320,6 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 	uint8 sv1 = BYTE_004177fc;
 	uint8 sv2 = BYTE_004177f6;
 	byte *sv3 = PTR_004173e8;
-	//uVar11 = DAT_0041723c;
-	//uVar10 = DAT_00417238;
 	uint8 sv6 = _preprocDataId;
 	Common::Point sv8 = DAT_00417228;
 	Common::Point sv10 = DAT_00417220;
@@ -3338,8 +3332,6 @@ uint32 GamosEngine::savedDoActions(const Actions &a) {
 	BYTE_004177fc = sv1;
 	BYTE_004177f6 = sv2;
 	PTR_004173e8 = sv3;
-	//DAT_0041723c = uVar11;
-	//DAT_00417238 = uVar10;
 	_preprocDataId = sv6;
 	DAT_00417228 = sv8;
 	DAT_00417220 = sv10;


Commit: aad5ed68215de9f870864c26da14dfc28596224d
    https://github.com/scummvm/scummvm/commit/aad5ed68215de9f870864c26da14dfc28596224d
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:00+01:00

Commit Message:
GAMOS: Remove unused save files xor key

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 23aa20b9eff..99d59321e92 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -43,12 +43,6 @@
 
 namespace Gamos {
 
-const byte GamosEngine::_xorKeys[32] =  {0xa7, 0x15, 0xf0, 0x56, 0xf3, 0xfa, 0x84, 0x2c,
-                                         0xfd, 0x81, 0x38, 0xac, 0x73, 0xd2, 0x22, 0x47,
-                                         0xa0, 0x12, 0xb8, 0x19, 0x20, 0x6a, 0x26, 0x7c,
-                                         0x32, 0x57, 0xdd, 0xb2, 0x38, 0xa7, 0x95, 0x7a
-                                        };
-
 GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
 	_gameDescription(gameDesc), _randomSource("Gamos"),
 	_messageProc(this),
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 9c574418412..30f93b8d9e4 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -425,8 +425,6 @@ private:
 
 	Common::Array<XorArg> _xorSeq[3];
 
-	static const byte _xorKeys[32];
-
 	uint32 _seed = 1;
 
 	Object _cursorObject;


Commit: 3ee2c931a0a2c17422aa8f45104e602bd4ec845f
    https://github.com/scummvm/scummvm/commit/3ee2c931a0a2c17422aa8f45104e602bd4ec845f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:00+01:00

Commit Message:
GAMOS: Inverse arguments in functions with reversed sequences

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 99d59321e92..2f4a5db89d0 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1657,14 +1657,14 @@ void GamosEngine::preprocessDataB1(int id, ActEntry *e) {
 int GamosEngine::processData(ActEntry e, bool absolute) {
 	preprocessData(_preprocDataId, &e);
 	if (!absolute) {
-		createActiveObject(e,
+		createActiveObject(e, Common::Point(
 		             (e.x + DAT_00417220.x + _statesWidth) % _statesWidth,
-		             (e.y + DAT_00417220.y + _statesHeight) % _statesHeight);
+		             (e.y + DAT_00417220.y + _statesHeight) % _statesHeight) );
 		if (_needReload)
 			return 0;
 		return e.x == 0 && e.y == 0;
 	} else {
-		createActiveObject(e, e.x, e.y);
+		createActiveObject(e, Common::Point(e.x, e.y) );
 		return 0;
 	}
 }
@@ -1701,14 +1701,14 @@ void GamosEngine::FUN_00402a68(ActEntry e) {
 	}
 }
 
-void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
-	ObjState &stref = _states.at(x, y);
+void GamosEngine::createActiveObject(ActEntry e, Common::Point cell) {
+	ObjState &stref = _states.at(cell);
 
 	uint8 oid = e.actid;
 
 	if ((e.flags & 1) == 0) {
 		if (oid == 0xfe) {
-			removeObjectAtCoords(Common::Point(x, y), true);
+			removeObjectAtCoords(cell, true);
 			if (_needReload)
 				return;
 
@@ -1738,14 +1738,14 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 
 	ObjectAction &act = _objectActions[oid];
 	if (act.actType == 0) {
-		removeObjectAtCoords(Common::Point(x, y), true);
+		removeObjectAtCoords(cell, true);
 		if (_needReload)
 			return;
 		obj = nullptr;
 		index = -1;
 		odat = nullptr;
 	} else {
-		removeObjectAtCoords(Common::Point(x, y), false);
+		removeObjectAtCoords(cell, false);
 		if (_needReload)
 			return;
 		obj = getFreeObject();
@@ -1754,8 +1754,7 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 		obj->actID = oid;
 		obj->inputFlag = 0;
 		obj->priority = act.priority;
-		obj->cell.x = x;
-		obj->cell.y = y;
+		obj->cell = cell;
 		obj->tgtObjectId = -1;
 		obj->curObjectId = -1;
 		obj->state = stref;
@@ -1779,7 +1778,7 @@ void GamosEngine::createActiveObject(ActEntry e, int32 x, int32 y) {
 	}
 
 	stref = ObjState(oid, e.flags, e.t);
-	executeScript(e.t, y, x, odat, index, obj, &act, act.onCreateAddress);
+	executeScript(act.onCreateAddress, &act, obj, index, odat, cell, e.t);
 }
 
 void GamosEngine::removeObjectByIDMarkDirty(int32 id) {
@@ -1836,7 +1835,7 @@ void GamosEngine::removeObjectAtCoords(Common::Point cell, bool deleteGfxObj) {
 	if (povar4)
 		stref = ObjState(povar4->state.actid, 0, povar4->state.t);
 
-	executeScript(stref.t, cell.y, cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+	executeScript(act.onDeleteAddress, &act, nullptr, -1, nullptr, cell, stref.t);
 }
 
 Object *GamosEngine::getFreeObject() {
@@ -1900,8 +1899,7 @@ void GamosEngine::removeObjectMarkDirty(Object *obj) {
 	removeObject(obj);
 }
 
-
-void GamosEngine::executeScript(uint8 p1, uint32 celly, uint32 cellx, byte *storage, int32 index, Object *pobj, ObjectAction *act, int32 scriptAddr) {
+void GamosEngine::executeScript(int32 scriptAddr, ObjectAction *act, Object *pobj, int32 index, byte *storage, Common::Point cell, uint8 t) {
 	if (scriptAddr == -1)
 		return;
 
@@ -1913,12 +1911,10 @@ void GamosEngine::executeScript(uint8 p1, uint32 celly, uint32 cellx, byte *stor
 	Object *sv8 = PTR_00417218;
 	ObjectAction *sv9 = PTR_00417214;
 
-	BYTE_004177f6 = p1;
+	BYTE_004177f6 = t;
 	PTR_004173e8 = storage;
-	DAT_00417228.y = celly;
-	DAT_00417228.x = cellx;
-	DAT_00417220.y = celly;
-	DAT_00417220.x = cellx;
+	DAT_00417228 = cell;
+	DAT_00417220 = cell;
 	_curObjIndex = index;
 	PTR_00417218 = pobj;
 	PTR_00417214 = act;
@@ -1951,7 +1947,7 @@ bool GamosEngine::FUN_00402fb4() {
 					pobj->state.flags &= ~1;
 				} else {
 					if ((pobj->flags & Object::FLAG_TRANSITION) == 0) {
-						if (pobj->curObjectId != -1 && FUN_00402f34(true, false, &_objects[pobj->curObjectId])) {
+						if (pobj->curObjectId != -1 && updateGfxFrames(&_objects[pobj->curObjectId], false, true)) {
 							pobj->curObjectId = pobj->tgtObjectId;
 							if (pobj->tgtObjectId != -1) {
 								Object &o = _objects[pobj->tgtObjectId];
@@ -1962,7 +1958,7 @@ bool GamosEngine::FUN_00402fb4() {
 							}
 						}
 					} else {
-						if (FUN_00402f34(pobj->curObjectId != pobj->tgtObjectId, true, &_objects[pobj->curObjectId])) {
+						if (updateGfxFrames(&_objects[pobj->curObjectId], true, pobj->curObjectId != pobj->tgtObjectId)) {
 							pobj->curObjectId = pobj->tgtObjectId;
 							if (pobj->tgtObjectId != -1) {
 								Object &o = _objects[pobj->tgtObjectId];
@@ -2052,7 +2048,7 @@ bool GamosEngine::FUN_00402fb4() {
 			}
 		} else {
 			if (!PTR_00417388 && pobj->isGraphicObject() && pobj->actObjIndex == -1)
-				FUN_00402f34(true, false, pobj);
+				updateGfxFrames(pobj, false, true);
 		}
 continue_to_next_object:
 		;
@@ -2064,7 +2060,7 @@ exit:
 	return true;
 }
 
-bool GamosEngine::FUN_00402f34(bool p1, bool p2, Object *obj) {
+bool GamosEngine::updateGfxFrames(Object *obj, bool p2, bool p1) {
 	if (obj->frameMax < 2) {
 		if (p2 || (obj->flags & Object::FLAG_DIRTRECT)) {
 			addDirtRectOnObject(obj);
@@ -2422,7 +2418,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	case 20: {
 		arg1 = ctx->pop32();
 		for (const SubtitlePoint &d : _subtitlePoints[arg1]) {
-			FUN_0040738c(d.sprId, d.x, d.y, true);
+			createGfxObject(d.sprId, d, true);
 		}
 		ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 	} break;
@@ -2731,7 +2727,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 				tmp.actid = 0xfe;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
-				createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
+				createActiveObject(tmp, DAT_00412c94);
 			} else if (arg1 == 2) {
 				ActEntry tmp;
 				tmp.actid = 0;
@@ -2752,7 +2748,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			tmp.actid = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 0;
-			createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
+			createActiveObject(tmp, DAT_00412c94);
 		}
 		ctx->EAX.setVal(1);
 	} break;
@@ -2764,7 +2760,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			tmp.actid = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 1;
-			createActiveObject(tmp, DAT_00412c94.x, DAT_00412c94.y);
+			createActiveObject(tmp, DAT_00412c94);
 		}
 		ctx->EAX.setVal(1);
 	} break;
@@ -3003,7 +2999,7 @@ void GamosEngine::callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint3
 
 uint32 GamosEngine::scriptFunc19(uint32 id) {
 	BYTE_004177fc = 1;
-	FUN_0040738c(id, DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH, false);
+	createGfxObject(id, Common::Point(DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH), false);
 
 	return 1;
 }
@@ -3023,7 +3019,7 @@ uint32 GamosEngine::scriptFunc16(uint32 id) {
 }
 
 
-bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
+bool GamosEngine::createGfxObject(uint32 id, Common::Point position, bool staticObject) {
 	Sprite &spr = _sprites[id];
 	Object *gfxObj = getFreeObject();
 
@@ -3034,14 +3030,13 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 
 	gfxObj->frameMax = spr.field_3;
 	int16 idx = -1;
-	if (!p)
+	if (!staticObject)
 		idx = _curObjIndex;
 
 	gfxObj->actObjIndex = idx;
-	gfxObj->position.x = x;
-	gfxObj->position.y = y;
+	gfxObj->position = position;
 
-	if (!p) {
+	if (!staticObject) {
 		if (!PTR_00417218) {
 			gfxObj->priority = PTR_00417214->priority;
 		} else {
@@ -3072,7 +3067,7 @@ bool GamosEngine::FUN_0040738c(uint32 id, int32 x, int32 y, bool p) {
 		gfxObj->cell.y = -1;
 	}
 
-	FUN_00409378(id, gfxObj, p);
+	FUN_00409378(id, gfxObj, staticObject);
 	return true;
 }
 
@@ -3985,7 +3980,7 @@ void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
 	PTR_00417218->state = ObjState(val, 0, 1);
 
 	ObjectAction &act = _objectActions[val];
-	executeScript(1, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onCreateAddress);
+	executeScript(act.onCreateAddress, &act, nullptr, -1, nullptr, PTR_00417218->cell, 1);
 }
 
 void GamosEngine::FUN_004025d0() {
@@ -4004,7 +3999,7 @@ void GamosEngine::FUN_004025d0() {
 			}
 		}
 
-		executeScript(PTR_00417218->state.t, PTR_00417218->cell.y, PTR_00417218->cell.x, nullptr, -1, nullptr, &act, act.onDeleteAddress);
+		executeScript(act.onDeleteAddress, &act, nullptr, -1, nullptr, PTR_00417218->cell, PTR_00417218->state.t);
 		PTR_00417218->state = ObjState(0xfe, 0, 0xf);
 	}
 }
@@ -4356,7 +4351,7 @@ bool GamosEngine::onTxtInputUpdate(uint8 c) {
 			if ((obj.frame + 1 == obj.frameMax) && obj.actObjIndex != -1) {
 				obj.cell = _objects[ obj.actObjIndex ].cell;
 			}
-			FUN_00402f34(false, false, &obj);
+			updateGfxFrames(&obj, false, false);
 		}
 	}
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 30f93b8d9e4..86814252387 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -284,9 +284,7 @@ struct Object {
 	inline bool isStaticObject() const { return (flags & (FLAG_GRAPHIC | FLAG_FREECOORDS | FLAG_VALID)) == (FLAG_GRAPHIC | FLAG_VALID); };
 };
 
-struct SubtitlePoint {
-	int16 x = 0;
-	int16 y = 0;
+struct SubtitlePoint : Common::Point {
 	uint16 sprId = 0;
 };
 
@@ -658,11 +656,11 @@ protected:
 	void preprocessDataB1(int id, ActEntry *e);
 	int processData(ActEntry e, bool absolute);
 
-	void executeScript(uint8 p1, uint32 id, uint32 pos, byte *storage, int32 index, Object *pobj, ObjectAction *act, int32 scriptAddr);
+	void executeScript(int32 scriptAddr, ObjectAction *act, Object *pobj, int32 index, byte *storage, Common::Point cell, uint8 t);
 
 	void FUN_00402a68(ActEntry e);
 
-	void createActiveObject(ActEntry e, int32 x, int32 y);
+	void createActiveObject(ActEntry e, Common::Point cell);
 
 	void removeObjectAtCoords(Common::Point cell, bool deleteGfxObj);
 
@@ -679,7 +677,7 @@ protected:
 	bool updateMouseCursor(Common::Point mouseMove);
 	bool scrollAndDraw();
 	bool FUN_00402bc4();
-	bool FUN_00402f34(bool p1, bool p2, Object *obj);
+	bool updateGfxFrames(Object *obj, bool p2, bool p1);
 
 	void FUN_0040921c(Object *obj);
 	void addDirtRectOnObject(Object *obj);
@@ -695,7 +693,7 @@ protected:
 
 	uint32 doScript(uint32 scriptAddress);
 
-	bool FUN_0040738c(uint32 id, int32 x, int32 y, bool p);
+	bool createGfxObject(uint32 id, Common::Point position, bool p);
 
 	void FUN_00409378(int32 sprId, Object *obj, bool p);
 


Commit: 19063ff663f726edef872d3357f0392a8644ba27
    https://github.com/scummvm/scummvm/commit/19063ff663f726edef872d3357f0392a8644ba27
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:00+01:00

Commit Message:
GAMOS: Give names for part of path finding methods and variables

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 2f4a5db89d0..8dc74374064 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1981,7 +1981,7 @@ bool GamosEngine::FUN_00402fb4() {
 					PTR_00417214 = &_objectActions[pobj->actID];
 					PTR_004173e8 = pobj->storage.data();
 
-					DAT_00417804 = 0;
+					_pathInMove = false;
 					for (Actions &scr : PTR_00417214->actions) {
 						BYTE_004177f6 = PTR_00417218->t;
 
@@ -2684,23 +2684,23 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 38:
 		arg1 = ctx->pop32();
-		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412ca0)
-			ctx->EAX.setVal(0);
-		else
+		if (_pathInMove && (int32)arg1 == _pathDir4)
 			ctx->EAX.setVal(1);
+		else
+			ctx->EAX.setVal(0);
 		break;
 
 	case 39:
 		arg1 = ctx->pop32();
-		if (DAT_00417804 == 0 || (int32)arg1 != INT_00412c9c)
-			ctx->EAX.setVal(0);
-		else
+		if (_pathInMove && (int32)arg1 == _pathDir8)
 			ctx->EAX.setVal(1);
+		else
+			ctx->EAX.setVal(0);
 		break;
 
 	case 40:
 		arg1 = ctx->pop32();
-		if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412ca0) != 0)
+		if (_pathInMove && FUN_0040705c(arg1, _pathDir4) != 0)
 			ctx->EAX.setVal(1);
 		else
 			ctx->EAX.setVal(0);
@@ -2708,7 +2708,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 41:
 		arg1 = ctx->pop32();
-		if (DAT_00417804 != 0 && FUN_0040705c(arg1, INT_00412c9c) != 0)
+		if (_pathInMove && FUN_0040705c(arg1, _pathDir8) != 0)
 			ctx->EAX.setVal(1);
 		else
 			ctx->EAX.setVal(0);
@@ -2716,9 +2716,9 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 42: {
 		arg1 = ctx->pop32();
-		if (DAT_00417804 != 0) {
+		if (_pathInMove != false) {
 			if (arg1 == 0) {
-				DAT_00417804 = 0;
+				_pathInMove = false;
 				DAT_004177fe = 255;
 				DAT_00417805 = 255;
 				DAT_004177fd = 255;
@@ -2727,14 +2727,14 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 				tmp.actid = 0xfe;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
-				createActiveObject(tmp, DAT_00412c94);
+				createActiveObject(tmp, _pathTargetCell);
 			} else if (arg1 == 2) {
 				ActEntry tmp;
 				tmp.actid = 0;
 				tmp.t = BYTE_004177f6;
 				tmp.flags = 0;
-				tmp.x = DAT_00412c94.x - DAT_00412c8c.x;
-				tmp.y = DAT_00412c94.y - DAT_00412c8c.y;
+				tmp.x = _pathTargetCell.x - _pathStartCell.x;
+				tmp.y = _pathTargetCell.y - _pathStartCell.y;
 				FUN_00402a68(tmp);
 			}
 		}
@@ -2743,24 +2743,24 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 43: {
 		arg1 = ctx->pop32();
-		if (DAT_00417804) {
+		if (_pathInMove) {
 			ActEntry tmp;
 			tmp.actid = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 0;
-			createActiveObject(tmp, DAT_00412c94);
+			createActiveObject(tmp, _pathTargetCell);
 		}
 		ctx->EAX.setVal(1);
 	} break;
 
 	case 44: {
 		arg1 = ctx->pop32();
-		if (DAT_00417804) {
+		if (_pathInMove) {
 			ActEntry tmp;
 			tmp.actid = arg1;
 			tmp.t = BYTE_004177f6;
 			tmp.flags = 1;
-			createActiveObject(tmp, DAT_00412c94);
+			createActiveObject(tmp, _pathTargetCell);
 		}
 		ctx->EAX.setVal(1);
 	} break;
@@ -3467,14 +3467,14 @@ bool GamosEngine::FUN_00402bc4() {
 
 void GamosEngine::FUN_00407db8(uint8 p) {
 	if ((p == 0x82) || (p == 0x83))
-		DAT_00412c94 = DAT_004173f8;
+		_pathTargetCell = DAT_004173f8;
 	else
-		DAT_00412c94 = DAT_004173f0;
+		_pathTargetCell = DAT_004173f0;
 
-	DAT_00412c8c = PTR_00417218->cell;
-	INT_00412ca0 = -1;
-	INT_00412c9c = -1;
-	DAT_00417804 = 0;
+	_pathStartCell = PTR_00417218->cell;
+	_pathDir4 = -1;
+	_pathDir8 = -1;
+	_pathInMove = false;
 }
 
 byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
@@ -3497,7 +3497,7 @@ byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
 	}
 
 	if (p3 == 0xff)
-		return FUN_00407e2c();
+		return pathFindMoveToTarget();
 	else if (p3 == 0xfe)
 		return FUN_0040856c();
 	else
@@ -3508,13 +3508,13 @@ byte GamosEngine::FUN_004084bc(uint8 p) {
 	for (int j = 0; j < _statesHeight; j++) {
 		for (int i = 0; i < _statesWidth; i++) {
 			const uint8 id = _states.at(i, j).actid;
-			if (id != p)
-				_pathMap.at(i, j) = 0;
+			if (id == p)
+				_pathMap.at(i, j) = PATH_TARGET;
 			else
-				_pathMap.at(i, j) = 2;
+				_pathMap.at(i, j) = PATH_FREE;
 		}
 	}
-	return FUN_0040841c(true);
+	return pathFindCalcMove(true);
 }
 
 byte GamosEngine::FUN_00408510(uint8 p) {
@@ -3523,14 +3523,14 @@ byte GamosEngine::FUN_00408510(uint8 p) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if (id == 0xfe)
-				_pathMap.at(i, j) = 0;
+				_pathMap.at(i, j) = PATH_FREE;
 			else if (id == p)
-				_pathMap.at(i, j) = 2;
+				_pathMap.at(i, j) = PATH_TARGET;
 			else
-				_pathMap.at(i, j) = 3;
+				_pathMap.at(i, j) = PATH_OBSTACLE;
 		}
 	}
-	return FUN_0040841c(false);
+	return pathFindCalcMove(false);
 }
 
 byte GamosEngine::FUN_0040856c() {
@@ -3539,13 +3539,13 @@ byte GamosEngine::FUN_0040856c() {
 			uint8 id = _states.at(i, j).actid;
 
 			if (id == 0xfe)
-				_pathMap.at(i, j) = 0;
+				_pathMap.at(i, j) = PATH_FREE;
 			else
-				_pathMap.at(i, j) = 3;
+				_pathMap.at(i, j) = PATH_OBSTACLE;
 		}
 	}
-	_pathMap.at(DAT_00412c94) = 2;
-	return FUN_0040841c(false);
+	_pathMap.at(_pathTargetCell) = PATH_TARGET;
+	return pathFindCalcMove(false);
 }
 
 byte GamosEngine::FUN_004085d8(uint8 p) {
@@ -3554,118 +3554,118 @@ byte GamosEngine::FUN_004085d8(uint8 p) {
 			uint8 id = _states.at(i, j).actid;
 
 			if (id == p)
-				_pathMap.at(i, j) = 0;
+				_pathMap.at(i, j) = PATH_FREE;
 			else
-				_pathMap.at(i, j) = 3;
+				_pathMap.at(i, j) = PATH_OBSTACLE;
 		}
 	}
-	_pathMap.at(DAT_00412c94) = 2;
-	return FUN_0040841c(false);
+	_pathMap.at(_pathTargetCell) = PATH_TARGET;
+	return pathFindCalcMove(false);
 }
 
-byte GamosEngine::FUN_0040841c(bool p) {
-	_pathMap.at(DAT_00412c8c.x, DAT_00412c8c.y) = 6;
+byte GamosEngine::pathFindCalcMove(bool faceTarget) {
+	_pathMap.at(_pathStartCell.x, _pathStartCell.y) = PATH_STEP1;
 
 	while (true) {
-		byte res = FUN_004081b8(6, 4);
-		if (res == 0)
+		byte res = pathFindSetNeighbor(PATH_STEP1, PATH_STEP3);
+		if (res == 0) // no set
 			return 0;
-		else if (res == 1) {
-			if (p)
-				return FUN_00407e2c();
+		else if (res == 1) { // target achieve
+			if (faceTarget)
+				return pathFindMoveToTarget();
 			else
-				return FUN_00407f70(6);
+				return pathFindTraceMove(PATH_STEP1);
 		}
 
-		res = FUN_004081b8(4, 5);
-		if (res == 0)
+		res = pathFindSetNeighbor(PATH_STEP3, PATH_STEP2);
+		if (res == 0) // no set
 			return 0;
-		else if (res == 1) {
-			if (p)
-				return FUN_00407e2c();
+		else if (res == 1) { // target achieve
+			if (faceTarget)
+				return pathFindMoveToTarget();
 			else
-				return FUN_00407f70(4);
+				return pathFindTraceMove(PATH_STEP3);
 		}
 
-		res = FUN_004081b8(5, 6);
-		if (res == 0)
+		res = pathFindSetNeighbor(PATH_STEP2, PATH_STEP1);
+		if (res == 0) // no set
 			return 0;
-		else if (res == 1) {
-			if (p)
-				return FUN_00407e2c();
+		else if (res == 1) { // target achieve
+			if (faceTarget)
+				return pathFindMoveToTarget();
 			else
-				return FUN_00407f70(5);
+				return pathFindTraceMove(PATH_STEP2);
 		}
 	}
 }
 
-byte GamosEngine::FUN_00407e2c() {
-	int32 iVar2 = DAT_00412c8c.x - DAT_00412c94.x;
-	if (iVar2 < 1)
-		iVar2 = -iVar2;
+byte GamosEngine::pathFindMoveToTarget() {
+	int32 xdist = _pathStartCell.x - _pathTargetCell.x;
+	if (xdist < 1)
+		xdist = -xdist;
 
-	int32 iVar1 = DAT_00412c8c.y - DAT_00412c94.y;
-	if (iVar1 < 1)
-		iVar1 = -iVar1;
+	int32 ydist = _pathStartCell.y - _pathTargetCell.y;
+	if (ydist < 1)
+		ydist = -ydist;
 
-	if ((iVar2 == 0) && (iVar1 == 0))
+	if ((xdist == 0) && (ydist == 0))
 		return 0;
 
-	if ((iVar2 == 0) || (iVar1 / iVar2) > 3) {
-		if (iVar1 > 1) {
-			INT_00412c9c = 4;
-			if (DAT_00412c94.y <= DAT_00412c8c.y)
-				INT_00412c9c = 0;
+	if ((xdist == 0) || (ydist / xdist) > 3) {
+		if (ydist > 1) {
+			_pathDir8 = PATH_DIR_D;
+			if (_pathTargetCell.y <= _pathStartCell.y)
+				_pathDir8 = PATH_DIR_U;
 		}
-		INT_00412ca0 = 4;
-		if (DAT_00412c94.y <= DAT_00412c8c.y)
-			INT_00412ca0 = 0;
-	} else if ((iVar1 == 0) || (iVar2 / iVar1) > 3) {
-		if (iVar2 > 1) {
-			INT_00412c9c = 2;
-			if (DAT_00412c94.x <= DAT_00412c8c.x)
-				INT_00412c9c = 6;
+		_pathDir4 = PATH_DIR_D;
+		if (_pathTargetCell.y <= _pathStartCell.y)
+			_pathDir4 = PATH_DIR_U;
+	} else if ((ydist == 0) || (xdist / ydist) > 3) {
+		if (xdist > 1) {
+			_pathDir8 = PATH_DIR_R;
+			if (_pathTargetCell.x <= _pathStartCell.x)
+				_pathDir8 = PATH_DIR_L;
 		}
-		INT_00412ca0 = 2;
-		if (DAT_00412c94.x <= DAT_00412c8c.x)
-			INT_00412ca0 = 6;
+		_pathDir4 = PATH_DIR_R;
+		if (_pathTargetCell.x <= _pathStartCell.x)
+			_pathDir4 = PATH_DIR_L;
 	} else {
-		if (DAT_00412c8c.x < DAT_00412c94.x) {
-			INT_00412c9c = 3;
-			if (DAT_00412c94.y <= DAT_00412c8c.y)
-				INT_00412c9c = 1;
+		if (_pathStartCell.x < _pathTargetCell.x) {
+			_pathDir8 = PATH_DIR_DR;
+			if (_pathTargetCell.y <= _pathStartCell.y)
+				_pathDir8 = PATH_DIR_UR;
 		} else {
-			INT_00412c9c = 5;
-			if (DAT_00412c94.y <= DAT_00412c8c.y)
-				INT_00412c9c = 7;
+			_pathDir8 = PATH_DIR_DL;
+			if (_pathTargetCell.y <= _pathStartCell.y)
+				_pathDir8 = PATH_DIR_UL;
 		}
 
-		if (iVar1 < iVar2) {
-			INT_00412ca0 = 2;
-			if (DAT_00412c94.x <= DAT_00412c8c.x)
-				INT_00412ca0 = 6;
+		if (ydist < xdist) {
+			_pathDir4 = PATH_DIR_R;
+			if (_pathTargetCell.x <= _pathStartCell.x)
+				_pathDir4 = PATH_DIR_L;
 		} else {
-			INT_00412ca0 = 4;
-			if (DAT_00412c94.y <= DAT_00412c8c.y)
-				INT_00412ca0 = 0;
+			_pathDir4 = PATH_DIR_D;
+			if (_pathTargetCell.y <= _pathStartCell.y)
+				_pathDir4 = PATH_DIR_U;
 		}
 	}
 
-	DAT_00417804 = 1;
+	_pathInMove = true;
 	return 1;
 }
 
-byte GamosEngine::FUN_00407f70(uint8 p) {
-	int32 x = DAT_00412c94.x;
-	int32 y = DAT_00412c94.y;
+byte GamosEngine::pathFindTraceMove(uint8 p) {
+	int32 x = _pathTargetCell.x;
+	int32 y = _pathTargetCell.y;
 	int32 px = -1;
 	int32 py = -1;
 
 	while (true) {
-		int32 xdist = DAT_00412c8c.x - x;
+		int32 xdist = _pathStartCell.x - x;
 		if (xdist < 1)
 			xdist = -xdist;
-		int32 ydist = DAT_00412c8c.y - y;
+		int32 ydist = _pathStartCell.y - y;
 		if (ydist < 1)
 			ydist = -ydist;
 
@@ -3673,75 +3673,63 @@ byte GamosEngine::FUN_00407f70(uint8 p) {
 		int32 yy = y;
 
 		if (ydist < xdist) {
-			if (x == 0 || _pathMap.at(x - 1, y) != p) {
-				if ((x >= _pathRight) || _pathMap.at(x + 1, y) != p) {
-					if ((y == 0) || _pathMap.at(x, y - 1) != p) {
-						if ((y >= _pathBottom) || _pathMap.at(x, y + 1) != p) {
-							return ydist;
-						} else {
-							yy = y + 1;
-						}
-					} else {
-						yy = y - 1;
-					}
-				} else {
-					xx = x + 1;
-				}
-			} else {
+			if (x >= 1 && _pathMap.at(x - 1, y) == p) {
 				xx = x - 1;
+			} else if (x <= _pathRight - 1 && _pathMap.at(x + 1, y) == p) {
+				xx = x + 1;
+			} else if (y >= 1 && _pathMap.at(x, y - 1) == p) {
+				yy = y - 1;
+			} else if (y <= _pathBottom - 1 && _pathMap.at(x, y + 1) == p) {
+				yy = y + 1;
+			} else {
+				return ydist;
 			}
 		} else {
-			if ((y == 0) || _pathMap.at(x, y - 1) != p) {
-				if ((y >= _pathBottom) || _pathMap.at(x, y + 1) != p) {
-					if ((x == 0) || _pathMap.at(x - 1, y) != p) {
-						if (x >= _pathRight || _pathMap.at(x + 1, y) != p) {
-							return ydist;
-						} else {
-							xx = x + 1;
-						}
-					} else {
-						xx = x - 1;
-					}
-				} else {
-					yy = y + 1;
-				}
-			} else {
+			if (y >= 1 && _pathMap.at(x, y - 1) == p) {
 				yy = y - 1;
+			} else if (y <= _pathBottom - 1 && _pathMap.at(x, y + 1) == p) {
+				yy = y + 1;
+			} else if (x >= 1 && _pathMap.at(x - 1, y) == p) {
+				xx = x - 1;
+			} else if (x <= _pathRight - 1 && _pathMap.at(x + 1, y) == p) {
+				xx = x + 1;
+			} else {
+				return ydist;
 			}
 		}
 
-		if (xx == DAT_00412c8c.x && yy == DAT_00412c8c.y) {
-			INT_00412ca0 = 2;
+		if (xx == _pathStartCell.x && yy == _pathStartCell.y) {
+			_pathDir4 = PATH_DIR_R;
 			if (x <= xx) {
-				INT_00412ca0 = 6;
+				_pathDir4 = PATH_DIR_L;
 				if (x >= xx) {
-					INT_00412ca0 = 4;
+					_pathDir4 = PATH_DIR_D;
 					if (y <= yy)
-						INT_00412ca0 = 0;
+						_pathDir4 = PATH_DIR_U;
 				}
 			}
 			if (px != -1) {
 				if (py > yy) {
-					INT_00412c9c = 3;
+					_pathDir8 = PATH_DIR_DR;
 					if (px <= xx) {
-						INT_00412c9c = 5;
+						_pathDir8 = PATH_DIR_DL;
 						if (px >= xx)
-							INT_00412c9c = 4;
+							_pathDir8 = PATH_DIR_D;
 					}
 				} else if (py < yy) {
-					INT_00412c9c = 1;
+					_pathDir8 = PATH_DIR_UR;
 					if (px <= xx) {
-						INT_00412c9c = 7;
+						_pathDir8 = PATH_DIR_UL;
 						if (px >= xx)
-							INT_00412c9c = 0;
+							_pathDir8 = PATH_DIR_U;
 					}
 				} else {
-					INT_00412c9c = 2;
+					_pathDir8 = PATH_DIR_R;
 					if (px <= xx)
-						INT_00412c9c = 6;
+						_pathDir8 = PATH_DIR_L;
 				}
 			}
-			DAT_00417804 = 1;
+			_pathInMove = true;
 			return 1;
 		}
 
@@ -3751,36 +3739,36 @@ byte GamosEngine::FUN_00407f70(uint8 p) {
 		y = yy;
 		x = xx;
 
-		if (p == 4)
-			p = 6;
-		else if (p == 5)
-			p = 4;
-		else if (p == 6)
-			p = 5;
+		if (p == PATH_STEP3)
+			p = PATH_STEP1;
+		else if (p == PATH_STEP2)
+			p = PATH_STEP3;
+		else if (p == PATH_STEP1)
+			p = PATH_STEP2;
 	}
 }
 
-byte GamosEngine::FUN_004081b8(uint8 cv, uint8 sv) {
+byte GamosEngine::pathFindSetNeighbor(uint8 checkVal, uint8 setVal) {
 	uint8 ret = 0;
 
 	for (int32 y = 0; y < _statesHeight; y++) {
 		for (int32 x = 0; x < _statesWidth; x++) {
 			uint8 &rval = _pathMap.at(x, y);
-			if (rval == 0) {
-				if ((x > 0 && _pathMap.at(x - 1, y) == cv) ||
-				        (x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
-				        (y > 0 && _pathMap.at(x, y - 1) == cv) ||
-				        (y < _pathBottom && _pathMap.at(x, y + 1) == cv)) {
-					ret = sv;
-					rval = sv;
+			if (rval == PATH_FREE) {
+				if ((x > 0 && _pathMap.at(x - 1, y) == checkVal) ||
+				        (x < _pathRight && _pathMap.at(x + 1, y) == checkVal) ||
+				        (y > 0 && _pathMap.at(x, y - 1) == checkVal) ||
+				        (y < _pathBottom && _pathMap.at(x, y + 1) == checkVal)) {
+					ret = setVal;
+					rval = setVal;
 				}
-			} else if (rval == 2) {
-				if ((x > 0 && _pathMap.at(x - 1, y) == cv) ||
-				        (x < _pathRight && _pathMap.at(x + 1, y) == cv) ||
-				        (y > 0 && _pathMap.at(x, y - 1) == cv) ||
-				        (y < _pathBottom && _pathMap.at(x, y + 1) == cv)) {
-					DAT_00412c94.x = x;
-					DAT_00412c94.y = y;
+			} else if (rval == PATH_TARGET) {
+				if ((x > 0 && _pathMap.at(x - 1, y) == checkVal) ||
+				        (x < _pathRight && _pathMap.at(x + 1, y) == checkVal) ||
+				        (y > 0 && _pathMap.at(x, y - 1) == checkVal) ||
+				        (y < _pathBottom && _pathMap.at(x, y + 1) == checkVal)) {
+					_pathTargetCell.x = x;
+					_pathTargetCell.y = y;
 					return 1;
 				}
 			}
@@ -3811,7 +3799,7 @@ byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
 	}
 
 	if (p3 == 0xff)
-		return FUN_00407e2c();
+		return pathFindMoveToTarget();
 	else if (p3 == 0xfe)
 		return FUN_0040881c(_thing2[p2].field_0);
 	else
@@ -3824,12 +3812,12 @@ byte GamosEngine::FUN_004086e4(const Common::Array<byte> &arr) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
-				_pathMap.at(i, j) = 0;
+				_pathMap.at(i, j) = PATH_FREE;
 			else
-				_pathMap.at(i, j) = 2;
+				_pathMap.at(i, j) = PATH_TARGET;
 		}
 	}
-	return FUN_0040841c(true);
+	return pathFindCalcMove(true);
 }
 
 byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
@@ -3838,12 +3826,12 @@ byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
-				_pathMap.at(i, j) = 3;
+				_pathMap.at(i, j) = PATH_OBSTACLE;
 			else
-				_pathMap.at(i, j) = 2;
+				_pathMap.at(i, j) = PATH_TARGET;
 		}
 	}
-	return FUN_0040841c(false);
+	return pathFindCalcMove(false);
 }
 
 byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
@@ -3852,13 +3840,13 @@ byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
-				_pathMap.at(i, j) = 3;
+				_pathMap.at(i, j) = PATH_OBSTACLE;
 			else
-				_pathMap.at(i, j) = 0;
+				_pathMap.at(i, j) = PATH_FREE;
 		}
 	}
-	_pathMap.at(DAT_00412c94) = 2;
-	return FUN_0040841c(false);
+	_pathMap.at(_pathTargetCell) = PATH_TARGET;
+	return pathFindCalcMove(false);
 }
 
 
@@ -4162,7 +4150,7 @@ Common::String GamosEngine::gamos_itoa(int n, uint radix) {
 
 
 bool GamosEngine::FUN_0040705c(int a, int b) {
-	static const int arr[8] = {0, 7, 6, 5, 4, 3, 2, 1};
+	static const int arr[8] = {PATH_DIR_U, PATH_DIR_UL, PATH_DIR_L, PATH_DIR_DL, PATH_DIR_D, PATH_DIR_DR, PATH_DIR_R, PATH_DIR_UR};
 	int v = DAT_004173ec;
 	if (v > 3) {
 		v -= 4;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 86814252387..be687b6ca37 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -103,6 +103,24 @@ enum RESTYPE {
 	RESTP_XORSEQ2 = 0x7e,
 };
 
+enum {
+	PATH_DIR_U = 0,
+	PATH_DIR_UR = 1,
+	PATH_DIR_R = 2,
+	PATH_DIR_DR = 3,
+	PATH_DIR_D = 4,
+	PATH_DIR_DL = 5,
+	PATH_DIR_L = 6,
+	PATH_DIR_UL = 7,
+
+	PATH_FREE = 0,
+	PATH_TARGET = 2,
+	PATH_OBSTACLE = 3,
+	PATH_STEP1 = 6,
+	PATH_STEP2 = 5,
+	PATH_STEP3 = 4,
+};
+
 struct Image {
 	bool loaded = false;
 	int32 offset = -1;
@@ -536,7 +554,7 @@ private:
 	Common::Point DAT_004173f8;
 
 	uint8 DAT_00417803 = 0;
-	uint8 DAT_00417804 = 0;
+	bool _pathInMove = false;
 	uint8 DAT_00417805 = 0;
 
 	uint8 RawKeyCode = 0;
@@ -565,10 +583,10 @@ private:
 
 
 	/* path find ? */
-	Common::Point DAT_00412c8c;
-	Common::Point DAT_00412c94;
-	int8 INT_00412c9c = 0;
-	int8 INT_00412ca0 = 0;
+	Common::Point _pathStartCell;
+	Common::Point _pathTargetCell;
+	int8 _pathDir8 = 0;
+	int8 _pathDir4 = 0;
 
 	Array2D<uint8> _pathMap;
 	uint32 _statesCount = 0;
@@ -714,16 +732,18 @@ protected:
 	Object *addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32 y);
 	void addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y);
 
+
+	/* Path find methods */
 	void FUN_00407db8(uint8 p);
 	byte FUN_00408648(uint8 p1, uint8 p2, uint8 p3);
 	byte FUN_004084bc(uint8 p);
 	byte FUN_00408510(uint8 p);
 	byte FUN_0040856c();
 	byte FUN_004085d8(uint8 p);
-	byte FUN_0040841c(bool p);
-	byte FUN_00407e2c();
-	byte FUN_00407f70(uint8 p);
-	byte FUN_004081b8(uint8 cv, uint8 sv);
+	byte pathFindCalcMove(bool faceTarget);
+	byte pathFindMoveToTarget();
+	byte pathFindTraceMove(uint8 p);
+	byte pathFindSetNeighbor(uint8 checkVal, uint8 setVal);
 
 	byte FUN_004088cc(uint8 p1, uint8 p2, uint8 p3);
 	byte FUN_004086e4(const Common::Array<byte> &arr);
@@ -731,6 +751,8 @@ protected:
 	byte FUN_0040881c(const Common::Array<byte> &arr);
 
 
+
+
 	void FUN_0040279c(uint8 val, bool rnd);
 	void FUN_004025d0();
 	bool FUN_0040705c(int a, int b);


Commit: 4100b6ecd9bc0819d294f0c209a8fc29c59e6e5f
    https://github.com/scummvm/scummvm/commit/4100b6ecd9bc0819d294f0c209a8fc29c59e6e5f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:01+01:00

Commit Message:
GAMOS: Rename input handling fields and methods

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/movie.cpp
    engines/gamos/proc.cpp
    engines/gamos/proc.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 8dc74374064..021cd844c75 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -982,13 +982,13 @@ void GamosEngine::flushDirtyRects(bool apply) {
 
 	_screen->update();
 
-	DAT_004177fd = 0xff;
-	DAT_004177fe = ACT_NONE;
+	_inputMouseActId = 0xff;
+	_inputMouseActType = ACT_NONE;
 	PTR_00417388 = nullptr;
 
 	rndSeed(_system->getMillis());
-	PTR_004121b4 = nullptr;
-	FUN_0040255c(nullptr);
+	_inputActObj = nullptr;
+	cycleNextInputObj(nullptr);
 }
 
 bool GamosEngine::usePalette(const byte *pal, int num, int fade, bool winColors) {
@@ -1238,7 +1238,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 		_keySeq += RawKeyCode;
 	}
 
-	FUN_00402c2c(mouseMove, actPos, act2, act1);
+	processInput(mouseMove, actPos, act2, act1);
 	changeVolume();
 
 	if (!FUN_00402bc4())
@@ -1773,8 +1773,8 @@ void GamosEngine::createActiveObject(ActEntry e, Common::Point cell) {
 		obj->storage.resize(act.storageSize, 0);
 		odat = obj->storage.data();
 		index = obj->index;
-		if (act.actType == 3 && PTR_004121b4 == nullptr)
-			PTR_004121b4 = obj;
+		if (act.actType == 3 && _inputActObj == nullptr)
+			_inputActObj = obj;
 	}
 
 	stref = ObjState(oid, e.flags, e.t);
@@ -1811,7 +1811,7 @@ void GamosEngine::removeObjectAtCoords(Common::Point cell, bool deleteGfxObj) {
 					    obj.storage.clear(); */
 					removeSubtitles(&obj);
 					removeObject(&obj);
-					FUN_0040255c(&obj);
+					cycleNextInputObj(&obj);
 					povar4 = &obj;
 					if (!deleteGfxObj || multidel)
 						break;
@@ -2014,7 +2014,7 @@ bool GamosEngine::FUN_00402fb4() {
 											DAT_00412204 = nullptr;
 											goto exit;
 										}
-										FUN_0040255c(pobj);
+										cycleNextInputObj(pobj);
 										goto continue_to_next_object;
 									}
 									if (!DAT_004177ff) {
@@ -2541,27 +2541,27 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			break;
 
 		case 6:
-			ret = FUN_00408648(0x82, 0xff, 0xff);
+			ret = FUN_00408648(ACT2_MOUSEUP_L, 0xff, 0xff);
 			break;
 
 		case 7:
-			ret = FUN_00408648(0x82, 0xfe, 0xff);
+			ret = FUN_00408648(ACT2_MOUSEUP_L, 0xfe, 0xff);
 			break;
 
 		case 8:
-			ret = FUN_00408648(0x82, 0xfe, 0xfe);
+			ret = FUN_00408648(ACT2_MOUSEUP_L, 0xfe, 0xfe);
 			break;
 
 		case 9:
-			ret = FUN_00408648(0x83, 0xff, 0xff);
+			ret = FUN_00408648(ACT2_MOUSEUP_R, 0xff, 0xff);
 			break;
 
 		case 10:
-			ret = FUN_00408648(0x83, 0xfe, 0xff);
+			ret = FUN_00408648(ACT2_MOUSEUP_R, 0xfe, 0xff);
 			break;
 
 		case 11:
-			ret = FUN_00408648(0x83, 0xfe, 0xfe);
+			ret = FUN_00408648(ACT2_MOUSEUP_R, 0xfe, 0xfe);
 			break;
 
 		default:
@@ -2597,27 +2597,27 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			break;
 
 		case 6:
-			ret = FUN_00408648(0x82, arg2, 0xff);
+			ret = FUN_00408648(ACT2_MOUSEUP_L, arg2, 0xff);
 			break;
 
 		case 7:
-			ret = FUN_00408648(0x82, arg2, 0xfe);
+			ret = FUN_00408648(ACT2_MOUSEUP_L, arg2, 0xfe);
 			break;
 
 		case 8:
-			ret = FUN_00408648(0x82, arg2, arg2);
+			ret = FUN_00408648(ACT2_MOUSEUP_L, arg2, arg2);
 			break;
 
 		case 9:
-			ret = FUN_00408648(0x83, arg2, 0xff);
+			ret = FUN_00408648(ACT2_MOUSEUP_R, arg2, 0xff);
 			break;
 
 		case 10:
-			ret = FUN_00408648(0x83, arg2, 0xfe);
+			ret = FUN_00408648(ACT2_MOUSEUP_R, arg2, 0xfe);
 			break;
 
 		case 11:
-			ret = FUN_00408648(0x83, arg2, arg2);
+			ret = FUN_00408648(ACT2_MOUSEUP_R, arg2, arg2);
 			break;
 
 		default:
@@ -2653,27 +2653,27 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			break;
 
 		case 6:
-			ret = FUN_004088cc(0x82, arg2, 0xff);
+			ret = FUN_004088cc(ACT2_MOUSEUP_L, arg2, 0xff);
 			break;
 
 		case 7:
-			ret = FUN_004088cc(0x82, arg2, 0xfe);
+			ret = FUN_004088cc(ACT2_MOUSEUP_L, arg2, 0xfe);
 			break;
 
 		case 8:
-			ret = FUN_004088cc(0x82, arg2, arg2);
+			ret = FUN_004088cc(ACT2_MOUSEUP_L, arg2, arg2);
 			break;
 
 		case 9:
-			ret = FUN_004088cc(0x83, arg2, 0xff);
+			ret = FUN_004088cc(ACT2_MOUSEUP_R, arg2, 0xff);
 			break;
 
 		case 10:
-			ret = FUN_004088cc(0x83, arg2, 0xfe);
+			ret = FUN_004088cc(ACT2_MOUSEUP_R, arg2, 0xfe);
 			break;
 
 		case 11:
-			ret = FUN_004088cc(0x83, arg2, arg2);
+			ret = FUN_004088cc(ACT2_MOUSEUP_R, arg2, arg2);
 			break;
 
 		default:
@@ -2719,9 +2719,8 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		if (_pathInMove != false) {
 			if (arg1 == 0) {
 				_pathInMove = false;
-				DAT_004177fe = 255;
-				DAT_00417805 = 255;
-				DAT_004177fd = 255;
+				_inputMouseActType = 0xff;
+				_inputMouseActId = 0xff;
 			} else if (arg1 == 1) {
 				ActEntry tmp;
 				tmp.actid = 0xfe;
@@ -3181,9 +3180,9 @@ void GamosEngine::removeSubtitles(Object *obj) {
 	}
 }
 
-void GamosEngine::FUN_0040255c(Object *obj) {
-	if (obj == PTR_004121b4) {
-		PTR_004121b4 = nullptr;
+void GamosEngine::cycleNextInputObj(Object *obj) {
+	if (obj == _inputActObj) {
+		_inputActObj = nullptr;
 		int32 n = 0;
 
 		int16 objIndex = -1;
@@ -3198,11 +3197,11 @@ void GamosEngine::FUN_0040255c(Object *obj) {
 
 			if (robj.isActionObject() && _objectActions[robj.actID].actType == 3) {
 				if (n) {
-					PTR_004121b4 = &robj;
+					_inputActObj = &robj;
 					break;
 				}
-				if (!PTR_004121b4)
-					PTR_004121b4 = &robj;
+				if (!_inputActObj)
+					_inputActObj = &robj;
 			}
 		}
 	}
@@ -3228,13 +3227,13 @@ bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
 	return false;
 }
 
-void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1) {
+void GamosEngine::processInput(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1) {
 	uint8 tmpb = 0;
-	if (act2 == ACT2_8f)
-		FUN_0040255c(PTR_004121b4);
-	else if (act2 == ACT2_82)
+	if (act2 == ACT2_TAB)
+		cycleNextInputObj(_inputActObj);
+	else if (act2 == ACT2_MOUSEUP_L)
 		tmpb = 0x90;
-	else if (act2 == ACT2_83)
+	else if (act2 == ACT2_MOUSEUP_R)
 		tmpb = 0xa0;
 	else if (act2 == ACT_NONE)
 		actPos = move;
@@ -3257,7 +3256,7 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 			else if (action.actType == 2)
 				obj.inputFlag = tmpb & 0x4f;
 			else if (action.actType == 3) {
-				if (&obj == PTR_004121b4)
+				if (&obj == _inputActObj)
 					obj.inputFlag = tmpb & 0x4f;
 				else
 					obj.inputFlag = 0;
@@ -3272,35 +3271,33 @@ void GamosEngine::FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 a
 	}
 
 	if (!pobj) {
-		DAT_004173f0.x = actPos.x / _gridCellW;
-		DAT_004173f0.y = actPos.y / _gridCellH;
-		DAT_00417803 = _states.at(DAT_004173f0).actid;
+		_inputActCell.x = actPos.x / _gridCellW;
+		_inputActCell.y = actPos.y / _gridCellH;
+		_inputActId = _states.at(_inputActCell).actid;
 	} else {
-		DAT_00417803 = actT;
+		_inputActId = actT;
 		if (actT == 2) {
 			if (act2 == ACT_NONE)
 				tmpb |= 0x10;
-			else if (act2 == ACT2_81)
+			else if (act2 == ACT2_MOUSEDOWN)
 				tmpb |= 0x20;
 
 			pobj->inputFlag = tmpb;
 		} else if (actT == 3 && (tmpb == 0x90 || tmpb == 0xa0)) {
-			PTR_004121b4 = pobj;
+			_inputActObj = pobj;
 			pobj->inputFlag = tmpb;
 		}
 
-		DAT_004173f0 = pobj->cell;
+		_inputActCell = pobj->cell;
 	}
 
-	DAT_00417805 = act2;
-	if (act2 == ACT2_82 || act2 == ACT2_83) {
-		DAT_004177fe = act2;
-		DAT_004177fd = DAT_00417803;
-		DAT_004173f8 = DAT_004173f0;
+	if (act2 == ACT2_MOUSEUP_L || act2 == ACT2_MOUSEUP_R) {
+		_inputMouseActType = act2;
+		_inputMouseActId = _inputActId;
+		_inputMouseActCell = _inputActCell;
 	} else {
-		if (act2 == ACT2_81)
-			DAT_004177fe = ACT_NONE;
-		DAT_00417805 = ACT_NONE;
+		if (act2 == ACT2_MOUSEDOWN)
+			_inputMouseActType = ACT_NONE;
 	}
 
 }
@@ -3466,10 +3463,10 @@ bool GamosEngine::FUN_00402bc4() {
 }
 
 void GamosEngine::FUN_00407db8(uint8 p) {
-	if ((p == 0x82) || (p == 0x83))
-		_pathTargetCell = DAT_004173f8;
+	if ((p == ACT2_MOUSEUP_L) || (p == ACT2_MOUSEUP_R))
+		_pathTargetCell = _inputMouseActCell;
 	else
-		_pathTargetCell = DAT_004173f0;
+		_pathTargetCell = _inputActCell;
 
 	_pathStartCell = PTR_00417218->cell;
 	_pathDir4 = -1;
@@ -3480,10 +3477,10 @@ void GamosEngine::FUN_00407db8(uint8 p) {
 byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
 	FUN_00407db8(p1);
 
-	if (p1 == 0x82 || p1 == 0x83) {
-		if (p1 != DAT_004177fe)
+	if (p1 == ACT2_MOUSEUP_L || p1 == ACT2_MOUSEUP_R) {
+		if (p1 != _inputMouseActType)
 			return 0;
-		if (p2 != 0xff && p2 != DAT_004177fd)
+		if (p2 != 0xff && p2 != _inputMouseActId)
 			return 0;
 	} else {
 		if (p1 != 0xe) {
@@ -3492,7 +3489,7 @@ byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
 			else
 				return FUN_00408510(p2);
 		}
-		if (p2 != 0xff && p2 != DAT_00417803)
+		if (p2 != 0xff && p2 != _inputActId)
 			return 0;
 	}
 
@@ -3780,11 +3777,11 @@ byte GamosEngine::pathFindSetNeighbor(uint8 checkVal, uint8 setVal) {
 byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
 	FUN_00407db8(p1);
 
-	if (p1 == 0x82 || p1 == 0x83) {
-		if (p1 != DAT_004177fe)
+	if (p1 == ACT2_MOUSEUP_L || p1 == ACT2_MOUSEUP_R) {
+		if (p1 != _inputMouseActType)
 			return 0;
 
-		if ( (_thing2[p2].field_0[ DAT_004177fd >> 3 ] & (1 << (DAT_004177fd & 7))) == 0 )
+		if ( (_thing2[p2].field_0[ _inputMouseActId >> 3 ] & (1 << (_inputMouseActId & 7))) == 0 )
 			return 0;
 	} else {
 		if (p1 != 0xe) {
@@ -3794,7 +3791,7 @@ byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
 				return FUN_00408778(_thing2[p2].field_0);
 		}
 
-		if ( (_thing2[p2].field_0[ DAT_00417803 >> 3 ] & (1 << (DAT_00417803 & 7))) == 0 )
+		if ( (_thing2[p2].field_0[ _inputActId >> 3 ] & (1 << (_inputActId & 7))) == 0 )
 			return 0;
 	}
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index be687b6ca37..a160bf7da25 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -455,8 +455,8 @@ private:
 	uint8 DAT_004177f8 = 0;
 
 
-	uint8 DAT_004177fd = 0;
-	uint8 DAT_004177fe = 0;
+	uint8 _inputMouseActId = 0;
+	uint8 _inputMouseActType = 0;
 
 	bool _midiStarted = false;
 
@@ -533,7 +533,7 @@ private:
 
 	ObjectAction *PTR_00417214 = nullptr;
 	Object *PTR_00417218 = nullptr;
-	Object *PTR_004121b4 = nullptr;
+	Object *_inputActObj = nullptr;
 
 	uint8 BYTE_004177f6 = 0;
 	uint8 BYTE_004177fc = 0;
@@ -550,12 +550,11 @@ private:
 	int32 _curObjIndex = 0;
 
 
-	Common::Point DAT_004173f0;
-	Common::Point DAT_004173f8;
+	Common::Point _inputActCell;
+	Common::Point _inputMouseActCell;
 
-	uint8 DAT_00417803 = 0;
+	uint8 _inputActId = 0;
 	bool _pathInMove = false;
-	uint8 DAT_00417805 = 0;
 
 	uint8 RawKeyCode = 0;
 
@@ -688,7 +687,7 @@ protected:
 	void removeObjectByIDMarkDirty(int32 id);
 
 	void removeSubtitles(Object *obj);
-	void FUN_0040255c(Object *obj);
+	void cycleNextInputObj(Object *obj);
 
 	bool FUN_00402fb4();
 
@@ -721,7 +720,7 @@ protected:
 
 	void setCursor(int id, bool dirtRect);
 
-	void FUN_00402c2c(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1);
+	void processInput(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1);
 	bool FUN_00409600(Object *obj, Common::Point pos);
 
 	void setNeedReload() {
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index b2d18267f72..f5e50a40abe 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -300,10 +300,10 @@ int MoviePlayer::processImageChunk() {
 	uint32 tstamp = 0;
 	uint8 act = processMessages(keepAct, &tstamp);
 
-	if (act == ACT2_82)
+	if (act == ACT2_MOUSEUP_L)
 		return 2;
 
-	if (act == ACT2_83)
+	if (act == ACT2_MOUSEUP_R)
 		return 3;
 
 	if (_hdrBytes[1] == 1) {
@@ -326,10 +326,10 @@ int MoviePlayer::processImageChunk() {
 		} else if (dtime < _frameTime) {
 			while (true) {
 				act = processMessages(false, &tstamp);
-				if (act == ACT2_82)
+				if (act == ACT2_MOUSEUP_L)
 					return 2;
 
-				if (act == ACT2_83)
+				if (act == ACT2_MOUSEUP_R)
 					return 3;
 
 				if ((tstamp - _firstFrameTime) / _currentFrame >= _frameTime)
@@ -603,7 +603,7 @@ uint8 MoviePlayer::processMessages(bool keepAct, uint32 *msecs) {
 	while (g_system->getEventManager()->pollEvent(e)) {
 		if (e.type == Common::EVENT_QUIT) {
 			//_errMessage = 1;
-			return ACT2_83;
+			return ACT2_MOUSEUP_R;
 		}
 		_messageProc->processMessage(e);
 	}
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index 6ea45ad99e5..125f235c2b0 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -56,13 +56,13 @@ void SystemProc::processMessage(const Common::Event &ev) {
 			_act1 = 7;
 		else {
 			if (winKey == _keyCodes[8])
-				_act2 = ACT2_82;
+				_act2 = ACT2_MOUSEUP_L;
 			else if (winKey == _keyCodes[9])
-				_act2 = ACT2_83;
+				_act2 = ACT2_MOUSEUP_R;
 			else if (winKey == _keyCodes[10])
-				_act2 = ACT2_8f;
+				_act2 = ACT2_TAB;
 			else if (winKey == _keyCodes[11])
-				_act2 = ACT2_84;
+				_act2 = ACT2_HELP;
 			else
 				return;
 
@@ -90,7 +90,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 			return;
 
 		_mouseActPos = ev.mouse;
-		_act2 = ACT2_81;
+		_act2 = ACT2_MOUSEDOWN;
 		break;
 
 	case Common::EVENT_LBUTTONUP:
@@ -98,7 +98,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 			return;
 
 		_mouseActPos = ev.mouse;
-		_act2 = ACT2_82;
+		_act2 = ACT2_MOUSEUP_L;
 		_rawKeyCode = _keyCodes[8];
 		break;
 
@@ -107,7 +107,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 			return;
 
 		_mouseActPos = ev.mouse;
-		_act2 = ACT2_83;
+		_act2 = ACT2_MOUSEUP_R;
 		_rawKeyCode = _keyCodes[9];
 		break;
 
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index 0c5abb43aa1..99b28522c0d 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -29,11 +29,11 @@ namespace Gamos {
 
 enum ACT2 {
 	ACT_NONE = 0xe,
-	ACT2_81 = 0x81,
-	ACT2_82 = 0x82,
-	ACT2_83 = 0x83,
-	ACT2_84 = 0x84,
-	ACT2_8f = 0x8f,
+	ACT2_MOUSEDOWN = 0x81,
+	ACT2_MOUSEUP_L = 0x82,
+	ACT2_MOUSEUP_R = 0x83,
+	ACT2_HELP = 0x84,
+	ACT2_TAB = 0x8f,
 };
 
 class SystemProc {


Commit: a5c329b88854ada6c5cb64347368c909abf8c3a9
    https://github.com/scummvm/scummvm/commit/a5c329b88854ada6c5cb64347368c909abf8c3a9
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:01+01:00

Commit Message:
GAMOS: Delete unused fields

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 021cd844c75..3ae438d58c7 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -44,7 +44,7 @@
 namespace Gamos {
 
 GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) : Engine(syst),
-	_gameDescription(gameDesc), _randomSource("Gamos"),
+	_gameDescription(gameDesc),
 	_messageProc(this),
 	_vm(this, callbackVMCallDispatcher),
 	_txtInputVMAccess(_vm) {}
@@ -581,21 +581,21 @@ bool GamosEngine::initMainDatas() {
 		return false;
 	}
 
-	_pages1kbCount = dataStream.readUint32LE();
-	_readBufSize = dataStream.readUint32LE();
+	/* skip count of pages 1kb size */
+	dataStream.skip(4);
+	/* skip read buffer size */
+	dataStream.skip(4);
 	_width = dataStream.readUint32LE();
 	_height = dataStream.readUint32LE();
 	_gridCellW = dataStream.readSint32LE();
 	_gridCellH = dataStream.readSint32LE();
 	_movieCount = dataStream.readUint32LE();
-	_unk5 = dataStream.readByte();
-	_unk6 = dataStream.readByte();
-	_unk7 = dataStream.readByte();
+	dataStream.skip(3); // skip unknown unused
 	_fps = dataStream.readByte();
-	_unk8 = dataStream.readByte();
-	_unk9 = dataStream.readByte();
+	dataStream.skip(1); // skip unknown unused
+	_drawCursor = dataStream.readByte();
 	_fadeEffectID = dataStream.readByte();
-	_unk11 = dataStream.readByte();
+	_playIntro = dataStream.readByte();
 
 	_introPos.x = dataStream.readSint32LE();
 	_introPos.y = dataStream.readSint32LE();
@@ -881,7 +881,7 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 
 
 bool GamosEngine::playIntro() {
-	if (_movieCount != 0 && _unk11 == 1)
+	if (_movieCount != 0 && _playIntro == 1)
 		return scriptFunc18(0);
 	return true;
 }
@@ -3208,7 +3208,7 @@ void GamosEngine::cycleNextInputObj(Object *obj) {
 }
 
 void GamosEngine::setCursor(int id, bool dirtRect) {
-	if (_unk9 == 0)
+	if (_drawCursor == 0)
 		_mouseCursorImgId = id;
 	else
 		_mouseCursorImgId = -1;
@@ -3991,7 +3991,7 @@ void GamosEngine::FUN_004025d0() {
 
 
 bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
-	if (_mouseCursorImgId >= 0 && _unk9 == 0) {
+	if (_mouseCursorImgId >= 0 && _drawCursor == 0 && _mouseCursorImgId < _sprites.size()) {
 		Sprite &cursorSpr = _sprites[_mouseCursorImgId];
 
 		if (cursorSpr.field_3 > 1) {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index a160bf7da25..4a69a9f9685 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -375,36 +375,28 @@ class GamosEngine : public Engine, public KeyCodes {
 
 private:
 	const GamosGameDescription *_gameDescription;
-	Common::RandomSource _randomSource;
 
 	bool _errSet = false;
 	Common::String _errMessage;
 
 	Archive _arch;
 
-	byte _cmdByte;
+	byte _cmdByte = 0;
 
-	bool _runReadDataMod;
-	int _currentModuleID;
+	bool _runReadDataMod = false;
+	int _currentModuleID = 0;
 
 	byte _saveLoadID = 0;
-
-	uint32 _magic;
-	uint32 _pages1kbCount;
-	uint32 _readBufSize;
-	uint32 _width; //screen output width
-	uint32 _height; //screen output height
-	int32 _gridCellW;
-	int32 _gridCellH;
-	uint32 _movieCount;
-	byte _unk5;
-	byte _unk6;
-	byte _unk7;
-	byte _fps;
-	byte _unk8;
-	byte _unk9;
+	uint32 _magic = 0xBAD00BAD;
+	uint32 _width = 0; //screen output width
+	uint32 _height = 0; //screen output height
+	int32 _gridCellW = 0;
+	int32 _gridCellH = 0;
+	uint32 _movieCount = 0;
+	byte _fps = 1;
+	byte _drawCursor = 0;
 	byte _fadeEffectID = 0;
-	byte _unk11;
+	byte _playIntro = 0;
 
 	byte _currentFade = 0;
 
@@ -840,12 +832,6 @@ public:
 
 	uint32 getEngineVersion() const;
 
-	/**
-	 * Gets a random number
-	 */
-	uint32 getRandomNumber(uint maxNum) {
-		return _randomSource.getRandomNumber(maxNum);
-	}
 
 	bool hasFeature(EngineFeature f) const override {
 		return


Commit: 0a5be01936be2ea66cc18f447459ae1146b38daa
    https://github.com/scummvm/scummvm/commit/0a5be01936be2ea66cc18f447459ae1146b38daa
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:02+01:00

Commit Message:
GAMOS: Rename many fields

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/proc.cpp
    engines/gamos/proc.h
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 3ae438d58c7..00ffebbeb19 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -112,7 +112,7 @@ Common::Error GamosEngine::run() {
 		if (curTime >= _lastTimeStamp + _delayTime) {
 			_lastTimeStamp = curTime;
 
-			if (_messageProc._gd2flags & 2) {
+			if (_messageProc._inputFlags & 2) {
 
 			}
 
@@ -140,11 +140,11 @@ Common::Error GamosEngine::run() {
 	stopMidi();
 	stopMCI();
 
-	_d2_fld17 = 1;
+	_enableMovie = true;
 	_enableMidi = true;
-	_d2_fld14 = 1;
-	_d2_fld16 = 1;
-	_runReadDataMod = true;
+	_enableSounds = true;
+	_enableInput = true;
+	_isResLoadingProcess = true;
 	writeStateFile();
 
 	return Common::kNoError;
@@ -236,7 +236,7 @@ bool GamosEngine::loader2() {
 bool GamosEngine::loadModule(uint id) {
 	_keySeq.clear();
 
-	if ((!_runReadDataMod && !writeStateFile()) ||
+	if ((!_isResLoadingProcess && !writeStateFile()) ||
 	        !_arch.seekDir(1))
 		return false;
 
@@ -301,9 +301,9 @@ bool GamosEngine::loadModule(uint id) {
 				RawData data;
 				if (!_arch.readCompressedData(&data))
 					return false;
-				if (_runReadDataMod && BYTE_004177f7 == 0)
+				if (_isResLoadingProcess && !_isSaveLoadingProcess)
 					readData2(data);
-				if (BYTE_004177f7 == 0) {
+				if (!_isSaveLoadingProcess) {
 					_scrollY = 0;
 					_scrollX = 0;
 					_scrollTrackObj = -1;
@@ -409,7 +409,7 @@ bool GamosEngine::loadModule(uint id) {
 	}
 
 	//FUN_00404a28();
-	if (BYTE_004177f7)
+	if (_isSaveLoadingProcess)
 		return true;
 
 	// Reverse Here
@@ -451,11 +451,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_18) {
 		loadRes18(pid, data, dataSize);
 	} else if (tp == RESTP_19) {
-		if (BYTE_004177f7 == 0) {
+		if (!_isSaveLoadingProcess) {
 			for (int i = 0; i < _states.size(); i++)
 				_states.at(i) = ObjState(0xfe, 0, 0xf);
 
-			DAT_004177f8 = 1;
+			_ignoreSoundActions = true;
 
 			Actions acts;
 			acts.parse(data, dataSize);
@@ -464,7 +464,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 			if (_needReload)
 				warning("needs reload from loadResHandler, CANT HAPPEN!");
 
-			DAT_004177f8 = 0;
+			_ignoreSoundActions = false;
 
 			storeToGameScreen(pid);
 		}
@@ -621,7 +621,7 @@ bool GamosEngine::initMainDatas() {
 }
 
 bool GamosEngine::init(const Common::String &moduleName) {
-	BYTE_004177f7 = 0;
+	_isSaveLoadingProcess = false;
 
 	if (!_arch.open(Common::Path(moduleName)))
 		return false;
@@ -645,15 +645,15 @@ bool GamosEngine::init(const Common::String &moduleName) {
 bool GamosEngine::loadInitModule() {
 	rndSeed(_system->getMillis());
 	_curObjIndex = -1;
-	PTR_00417218 = nullptr;
-	PTR_00417214 = nullptr;
+	_curObject = nullptr;
+	_curAction = nullptr;
 	_xorSeq[2].clear();
 	_xorSeq[1].clear();
 	_xorSeq[0].clear();
 	_isMoviePlay = 0;
 	_txtInputActive = false;
 	//_updateMouse = false;
-	_runReadDataMod = true;
+	_isResLoadingProcess = true;
 	_savedSndVolume = 0;
 	_savedMidiVolume = 0;
 	_sndVolumeTarget = 0;
@@ -893,7 +893,7 @@ bool GamosEngine::playMovie(int id) {
 
 
 bool GamosEngine::scriptFunc18(uint32 id) {
-	if (_d2_fld17 != 0) {
+	if (_enableMovie) {
 		_isMoviePlay++;
 		bool res = playMovie(id);
 		_isMoviePlay--;
@@ -1105,17 +1105,17 @@ void GamosEngine::readData2(const RawData &data) {
 	if (getEngineVersion() == 0x80000018) {
 		_stateExt = dataStream.readString(0, 4); // FIX ME
 		dataStream.seek(4);
-		_messageProc._gd2flags = dataStream.readByte(); //4
+		_messageProc._inputFlags = dataStream.readByte(); //4
 		dataStream.seek(8);
 		_svModuleId = dataStream.readSint32LE(); // 8
 		_svGameScreen = dataStream.readSint32LE(); // c
 		_d2_fld10 = dataStream.readUint32LE(); // x10
-		_d2_fld14 = dataStream.readByte(); // x14
+		_enableSounds = dataStream.readByte() != 0 ? true : false; // x14
 		_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
-		_d2_fld16 = dataStream.readByte(); // x16
-		_d2_fld17 = dataStream.readByte(); // x17
-		_d2_fld18 = dataStream.readByte(); // x18
-		_d2_fld19 = dataStream.readByte(); // x19
+		_enableInput = dataStream.readByte() != 0 ? true : false; // x16
+		_enableMovie = dataStream.readByte() != 0 ? true : false; // x17
+		_enableCDAudio = dataStream.readByte() != 0 ? true : false; // x18
+		_cdAudioTrack = dataStream.readSByte(); // x19
 		dataStream.seek(0x1c);
 		_scrollX = dataStream.readSint32LE(); // x1c
 		_scrollY = dataStream.readSint32LE(); // x20
@@ -1141,17 +1141,17 @@ void GamosEngine::readData2(const RawData &data) {
 	} else if (getEngineVersion() == 0x80000016) {
 		_stateExt = dataStream.readString(0, 4); // FIX ME
 		dataStream.seek(4);
-		_messageProc._gd2flags = dataStream.readByte(); //4
+		_messageProc._inputFlags = dataStream.readByte(); //4
 		dataStream.seek(8);
 		_svModuleId = dataStream.readSint32LE();
 		_svGameScreen = dataStream.readSint32LE();
 		_d2_fld10 = dataStream.readUint32LE();
-		_d2_fld14 = dataStream.readByte(); // x14
+		_enableSounds = dataStream.readByte() != 0 ? true : false; // x14
 		_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
-		_d2_fld16 = dataStream.readByte(); // x16
-		_d2_fld17 = dataStream.readByte(); // x17
-		_d2_fld18 = 0;
-		_d2_fld19 = 0;
+		_enableInput = dataStream.readByte() != 0 ? true : false; // x16
+		_enableMovie = dataStream.readByte() != 0 ? true : false; // x17
+		_enableCDAudio = false;
+		_cdAudioTrack = -1;
 		_scrollX = 0;
 		_scrollY = 0;
 		_scrollTrackObj = -1;
@@ -1223,7 +1223,7 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	_needReload = false;
 	_vm._interrupt = false;
 
-	if (_d2_fld16 == 0) {
+	if (_enableInput == 0) {
 		act1 = ACT_NONE;
 		act2 = ACT_NONE;
 		RawKeyCode = ACT_NONE;
@@ -1282,18 +1282,18 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 	Common::Array<Common::Point> ARR_00412208(512);
 
 	if (!absolute) {
-		DAT_00417228 = PTR_00417218->cell;
+		_curObjectStartCell = _curObject->cell;
 	} else {
-		PTR_00417218 = nullptr;
+		_curObject = nullptr;
 		_curObjIndex = -1;
-		PTR_00417214 = nullptr;
-		DAT_00417228 = Common::Point();
-		BYTE_004177f6 = 1;
+		_curAction = nullptr;
+		_curObjectStartCell = Common::Point();
+		_curObjectT = 1;
 		_preprocDataId = 0;
-		PTR_004173e8 = nullptr;
+		_curObjStorage = nullptr;
 	}
 
-	DAT_00417220 = DAT_00417228;
+	_curObjectCurrentCell = _curObjectStartCell;
 
 	int32 spos = -1;
 	int32 sbuf[6];
@@ -1337,8 +1337,8 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 				ObjState fb;
 				if (!absolute) {
 					Common::Point xy;
-					xy.x = (e.x + DAT_00417220.x + _statesWidth) % _statesWidth;
-					xy.y = (e.y + DAT_00417220.y + _statesHeight) % _statesHeight;
+					xy.x = (e.x + _curObjectCurrentCell.x + _statesWidth) % _statesWidth;
+					xy.y = (e.y + _curObjectCurrentCell.y + _statesHeight) % _statesHeight;
 					fb = _states.at(xy);
 				} else {
 					fb = _states.at(e.x, e.y);
@@ -1385,8 +1385,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 		}
 	}
 
-	BYTE_00412200 = 0;
-
+	_curObjectActProcessed = false;
 	if (a.flags & Actions::HAS_ACT4) {
 		ActEntry e = a.act_4;
 		preprocessData(_preprocDataId, &e);
@@ -1398,21 +1397,21 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 			return 0;
 	}
 
-	BYTE_004177fc = 0;
+	_gfxObjectCreated = false;
 	if (a.flags & Actions::HAS_FUNCTION) {
 		uint32 fldsv;
-		if (PTR_00417218)
-			fldsv = PTR_00417218->priority;
+		if (_curObject)
+			fldsv = _curObject->priority;
 		if (a.functionAddress != -1)
 			doScript(a.functionAddress);
 		if (_needReload)
 			return 0;
-		if (BYTE_004177fc == 0 && BYTE_00412200 == 0 && PTR_00417218 && PTR_00417218->priority != fldsv && PTR_00417218->curObjectId != -1)
-			addDirtRectOnObject(&_objects[PTR_00417218->curObjectId]);
+		if (!_gfxObjectCreated && !_curObjectActProcessed && _curObject && _curObject->priority != fldsv && _curObject->curObjectId != -1)
+			addDirtRectOnObject(&_objects[_curObject->curObjectId]);
 	}
 
-	if (BYTE_004177fc == 0 && BYTE_00412200 != 0)
-		FUN_004095a0(PTR_00417218);
+	if (!_gfxObjectCreated && _curObjectActProcessed)
+		FUN_004095a0(_curObject);
 
 	int32 retval = 0;
 
@@ -1658,8 +1657,8 @@ int GamosEngine::processData(ActEntry e, bool absolute) {
 	preprocessData(_preprocDataId, &e);
 	if (!absolute) {
 		createActiveObject(e, Common::Point(
-		             (e.x + DAT_00417220.x + _statesWidth) % _statesWidth,
-		             (e.y + DAT_00417220.y + _statesHeight) % _statesHeight) );
+		             (e.x + _curObjectCurrentCell.x + _statesWidth) % _statesWidth,
+		             (e.y + _curObjectCurrentCell.y + _statesHeight) % _statesHeight) );
 		if (_needReload)
 			return 0;
 		return e.x == 0 && e.y == 0;
@@ -1671,33 +1670,33 @@ int GamosEngine::processData(ActEntry e, bool absolute) {
 
 void GamosEngine::FUN_00402a68(ActEntry e) {
 	if (e.x != 0 || e.y != 0) {
-		DAT_00417220.x = (e.x + DAT_00417220.x + _statesWidth) % _statesWidth;
-		DAT_00417220.y = (e.y + DAT_00417220.y + _statesHeight) % _statesHeight;
+		_curObjectCurrentCell.x = (e.x + _curObjectCurrentCell.x + _statesWidth) % _statesWidth;
+		_curObjectCurrentCell.y = (e.y + _curObjectCurrentCell.y + _statesHeight) % _statesHeight;
 
-		ObjState st = PTR_00417218->state;
-		_states.at(DAT_00417228) = ObjState(st.actid, 0, st.t);
+		ObjState st = _curObject->state;
+		_states.at(_curObjectStartCell) = ObjState(st.actid, 0, st.t);
 
-		removeObjectAtCoords(DAT_00417220, false);
+		removeObjectAtCoords(_curObjectCurrentCell, false);
 
-		PTR_00417218->cell = DAT_00417220;
+		_curObject->cell = _curObjectCurrentCell;
 
-		ObjState rthing = _states.at(DAT_00417220);
-		PTR_00417218->state = ObjState(rthing.actid, st.flags, rthing.t);
+		ObjState rthing = _states.at(_curObjectCurrentCell);
+		_curObject->state = ObjState(rthing.actid, st.flags, rthing.t);
 
-		_states.at(DAT_00417220) = ObjState(PTR_00417218->actID, 0, PTR_00417218->t);
+		_states.at(_curObjectCurrentCell) = ObjState(_curObject->actID, 0, _curObject->t);
 
-		BYTE_00412200 = 1;
+		_curObjectActProcessed = true;
 	}
 
-	if (e.t != BYTE_004177f6) {
-		BYTE_004177f6 = e.t;
-		PTR_00417218->t = e.t;
+	if (e.t != _curObjectT) {
+		_curObjectT = e.t;
+		_curObject->t = e.t;
 
-		ObjState &stref = _states.at(DAT_00417220);
+		ObjState &stref = _states.at(_curObjectCurrentCell);
 		stref.flags = 0;
-		stref.t = BYTE_004177f6;
+		stref.t = _curObjectT;
 
-		BYTE_00412200 = 1;
+		_curObjectActProcessed = true;
 	}
 }
 
@@ -1758,7 +1757,7 @@ void GamosEngine::createActiveObject(ActEntry e, Common::Point cell) {
 		obj->tgtObjectId = -1;
 		obj->curObjectId = -1;
 		obj->state = stref;
-		if (PTR_00417218 && obj->index > PTR_00417218->index)
+		if (_curObject && obj->index > _curObject->index)
 			obj->state.flags |= 1;
 
 		// if (storageSize < 5) {
@@ -1903,38 +1902,38 @@ void GamosEngine::executeScript(int32 scriptAddr, ObjectAction *act, Object *pob
 	if (scriptAddr == -1)
 		return;
 
-	uint8 sv1 = BYTE_004177f6;
-	byte *sv2 = PTR_004173e8;
-	Common::Point sv4 = DAT_00417228;
-	Common::Point sv6 = DAT_00417220;
-	int32 sv7 = _curObjIndex;
-	Object *sv8 = PTR_00417218;
-	ObjectAction *sv9 = PTR_00417214;
-
-	BYTE_004177f6 = t;
-	PTR_004173e8 = storage;
-	DAT_00417228 = cell;
-	DAT_00417220 = cell;
+	const uint8 sv1 = _curObjectT;
+	byte * const sv2 = _curObjStorage;
+	const Common::Point sv4 = _curObjectStartCell;
+	const Common::Point sv6 = _curObjectCurrentCell;
+	const int32 sv7 = _curObjIndex;
+	Object * const sv8 = _curObject;
+	ObjectAction * const sv9 = _curAction;
+
+	_curObjectT = t;
+	_curObjStorage = storage;
+	_curObjectStartCell = cell;
+	_curObjectCurrentCell = cell;
 	_curObjIndex = index;
-	PTR_00417218 = pobj;
-	PTR_00417214 = act;
+	_curObject = pobj;
+	_curAction = act;
 
 	doScript(scriptAddr);
 
-	BYTE_004177f6 = sv1;
-	PTR_004173e8 = sv2;
-	DAT_00417228 = sv4;
-	DAT_00417220 = sv6;
+	_curObjectT = sv1;
+	_curObjStorage = sv2;
+	_curObjectStartCell = sv4;
+	_curObjectCurrentCell = sv6;
 	_curObjIndex = sv7;
-	PTR_00417218 = sv8;
-	PTR_00417214 = sv9;
+	_curObject = sv8;
+	_curAction = sv9;
 }
 
 bool GamosEngine::FUN_00402fb4() {
 	if (_objects.empty())
 		return true;
 
-	Object *pobj = DAT_00412204;
+	Object *pobj = _firstUpdateObject;
 	if (!pobj)
 		pobj = &(_objects.front());
 
@@ -1969,75 +1968,75 @@ bool GamosEngine::FUN_00402fb4() {
 							}
 							pobj->flags &= ~Object::FLAG_TRANSITION;
 						} else {
-							if (pobj == DAT_00412204) {
+							if (pobj == _firstUpdateObject) {
 								goto exit;
 							}
 							goto continue_to_next_object;
 						}
 					}
 
-					PTR_00417218 = pobj;
+					_curObject = pobj;
 					_curObjIndex = pobj->index;
-					PTR_00417214 = &_objectActions[pobj->actID];
-					PTR_004173e8 = pobj->storage.data();
+					_curAction = &_objectActions[pobj->actID];
+					_curObjStorage = pobj->storage.data();
 
 					_pathInMove = false;
-					for (Actions &scr : PTR_00417214->actions) {
-						BYTE_004177f6 = PTR_00417218->t;
+					for (Actions &scr : _curAction->actions) {
+						_curObjectT = _curObject->t;
 
 						int ivr8 = 0;
-						if (BYTE_004177f6 == 2)
+						if (_curObjectT == 2)
 							ivr8 = 1;
-						else if (BYTE_004177f6 == 4)
+						else if (_curObjectT == 4)
 							ivr8 = 2;
-						else if (BYTE_004177f6 == 8)
+						else if (_curObjectT == 8)
 							ivr8 = 3;
 
 						bool tmp = false;
 						for (int i = 0; i < 8; i++) {
-							if (PTR_00417214->mask & (1 << i)) {
+							if (_curAction->mask & (1 << i)) {
 								int fncid = ((i & 3) + ivr8) & 3;
 								if (i > 3)
 									fncid += 4;
 								DAT_004173ec = fncid;
 
-								DAT_004177ff = false;
+								_restartUpdateObject = false;
 								_preprocDataId = fncid;
 								int32 res = doActions(scr, false);
 
 								if (_needReload)
 									return false;
 
-								if (res != 0) {
-									if (res != 1) {
-										if (DAT_00412204) {
-											DAT_00412204 = nullptr;
-											goto exit;
-										}
-										cycleNextInputObj(pobj);
-										goto continue_to_next_object;
+								if (res == 1) {
+									if (_restartUpdateObject) {
+										tmp = true;
+										break;
+									}
+
+									if (_firstUpdateObject) {
+										_firstUpdateObject = nullptr;
+										goto exit;
 									}
-									if (!DAT_004177ff) {
-										if (DAT_00412204) {
-											DAT_00412204 = nullptr;
-											goto exit;
-										}
-										goto continue_to_next_object;
+									goto continue_to_next_object;
+								} else if (res != 0) {
+									if (_firstUpdateObject) {
+										_firstUpdateObject = nullptr;
+										goto exit;
 									}
-									tmp = true;
-									break;
+									cycleNextInputObj(pobj);
+									goto continue_to_next_object;
 								}
 							}
 						}
 
 						if (scr.flags & 0x80) {
 							if (tmp) {
-								DAT_00412204 = pobj;
+								_firstUpdateObject = pobj;
 								goto exit;
 							}
 
-							if (DAT_00412204) {
-								DAT_00412204 = nullptr;
+							if (_firstUpdateObject) {
+								_firstUpdateObject = nullptr;
 								goto exit;
 							}
 
@@ -2055,7 +2054,7 @@ continue_to_next_object:
 	}
 
 exit:
-	PTR_00417218 = nullptr;
+	_curObject = nullptr;
 	_curObjIndex = -1;
 	return true;
 }
@@ -2302,7 +2301,7 @@ bool GamosEngine::loadImage(Image *img) {
 }
 
 uint32 GamosEngine::doScript(uint32 scriptAddress) {
-	uint32 res = _vm.doScript(scriptAddress, PTR_004173e8);
+	uint32 res = _vm.doScript(scriptAddress, _curObjStorage);
 	return res;
 }
 
@@ -2312,59 +2311,59 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	switch (funcID) {
 	case 0:
-		DAT_004177ff = true;
+		_restartUpdateObject = true;
 		ctx->EAX.setVal(1);
 		break;
 	case 1:
-		ctx->EAX.setVal( PTR_00417218->curObjectId == -1 ? 1 : 0 );
+		ctx->EAX.setVal( _curObject->curObjectId == -1 ? 1 : 0 );
 		break;
 
 	case 2:
 		arg1 = ctx->pop32();
-		if (PTR_00417218->tgtObjectId == -1)
+		if (_curObject->tgtObjectId == -1)
 			ctx->EAX.setVal(0);
 		else
-			ctx->EAX.setVal( _objects[ PTR_00417218->tgtObjectId ].sprId == arg1 ? 1 : 0 );
+			ctx->EAX.setVal( _objects[ _curObject->tgtObjectId ].sprId == arg1 ? 1 : 0 );
 		break;
 	case 3:
-		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0x90) == 0x10 ? 1 : 0 );
+		ctx->EAX.setVal( (_curObject->inputFlag & 0x90) == 0x10 ? 1 : 0 );
 		break;
 	case 4:
-		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0xa0) == 0x20 ? 1 : 0 );
+		ctx->EAX.setVal( (_curObject->inputFlag & 0xa0) == 0x20 ? 1 : 0 );
 		break;
 	case 5:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0xb0) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (_curObject->inputFlag & 0xb0) == arg1 ? 1 : 0 );
 		break;
 	case 6:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (PTR_00417218->inputFlag & 0x4f) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (_curObject->inputFlag & 0x4f) == arg1 ? 1 : 0 );
 		break;
 	case 7:
 		arg1 = ctx->pop32();
-		if ((PTR_00417218->inputFlag & 0x40) == 0 || (PTR_00417218->inputFlag & 8) != (arg1 & 8))
+		if ((_curObject->inputFlag & 0x40) == 0 || (_curObject->inputFlag & 8) != (arg1 & 8))
 			ctx->EAX.setVal(0);
 		else
-			ctx->EAX.setVal( FUN_0040705c(arg1 & 7, PTR_00417218->inputFlag & 7) ? 1 : 0 );
+			ctx->EAX.setVal( FUN_0040705c(arg1 & 7, _curObject->inputFlag & 7) ? 1 : 0 );
 		break;
 	case 8:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( PTR_00417218->priority == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( _curObject->priority == arg1 ? 1 : 0 );
 		break;
 	case 9:
 		arg1 = ctx->pop32();
 		ctx->EAX.setVal( savedDoActions(_subtitleActions[arg1]) );
 		break;
 	case 10:
-		ctx->EAX.setVal( PTR_00417218->state.actid == 0xfe ? 1 : 0 );
+		ctx->EAX.setVal( _curObject->state.actid == 0xfe ? 1 : 0 );
 		break;
 	case 11:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( PTR_00417218->state.actid == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( _curObject->state.actid == arg1 ? 1 : 0 );
 		break;
 	case 12:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( _thing2[arg1].field_0[ PTR_00417218->state.actid >> 3 ] & (1 << (PTR_00417218->state.actid & 7)) );
+		ctx->EAX.setVal( _thing2[arg1].field_0[ _curObject->state.actid >> 3 ] & (1 << (_curObject->state.actid & 7)) );
 		break;
 	case 13: {
 		VM::ValAddr regRef = ctx->popReg();
@@ -2401,7 +2400,8 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 17:
 		arg1 = ctx->pop32();
-		playSound(arg1);
+		if (!_ignoreSoundActions && _enableSounds)
+			playSound(arg1);
 		ctx->EAX.setVal(1);
 		break;
 
@@ -2426,7 +2426,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	case 21: {
 		VM::ValAddr regRef = ctx->popReg();
 		arg2 = ctx->pop32();
-		ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH) );
+		ctx->EAX.setVal( txtInputBegin(ctx, regRef.getMemType(), regRef.getOffset(), arg2, _curObjectCurrentCell.x * _gridCellW, _curObjectCurrentCell.y * _gridCellH) );
 	} break;
 
 	case 22: {
@@ -2439,7 +2439,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	case 23: {
 		VM::ValAddr regRef = ctx->popReg();
 		arg2 = ctx->pop32();
-		addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), arg2, DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH);
+		addSubtitles(ctx, regRef.getMemType(), regRef.getOffset(), arg2, _curObjectCurrentCell.x * _gridCellW, _curObjectCurrentCell.y * _gridCellH);
 		ctx->EAX.setVal(1);
 	} break;
 
@@ -2455,14 +2455,14 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 25: {
 		arg1 = ctx->pop32();
-		if (PTR_00417218->priority != arg1) {
-			PTR_00417218->priority = arg1;
-			if (PTR_00417218->tgtObjectId != -1) {
-				Object &obj = _objects[PTR_00417218->tgtObjectId];
+		if (_curObject->priority != arg1) {
+			_curObject->priority = arg1;
+			if (_curObject->tgtObjectId != -1) {
+				Object &obj = _objects[_curObject->tgtObjectId];
 				obj.priority = arg1;
 			}
-			if (PTR_00417218->curObjectId != -1) {
-				Object &obj = _objects[PTR_00417218->curObjectId];
+			if (_curObject->curObjectId != -1) {
+				Object &obj = _objects[_curObject->curObjectId];
 				obj.priority = arg1;
 				addDirtRectOnObject(&obj);
 			}
@@ -2472,7 +2472,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	break;
 
 	case 26:
-		removeSubtitles(PTR_00417218);
+		removeSubtitles(_curObject);
 		ctx->EAX.setVal(1);
 		break;
 
@@ -2494,10 +2494,10 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 
 	case 30: {
-		if (PTR_00417218->curObjectId != -1) {
-			Object *obj = &_objects[PTR_00417218->curObjectId];
-			PTR_00417218->tgtObjectId = -1;
-			PTR_00417218->curObjectId = -1;
+		if (_curObject->curObjectId != -1) {
+			Object *obj = &_objects[_curObject->curObjectId];
+			_curObject->tgtObjectId = -1;
+			_curObject->curObjectId = -1;
 			removeObjectMarkDirty(obj);
 		}
 	} break;
@@ -2514,13 +2514,13 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 
 	case 33:
-		PTR_00417218->priority = _statesHeight - PTR_00417218->cell.y;
+		_curObject->priority = _statesHeight - _curObject->cell.y;
 		ctx->EAX.setVal(1);
 		break;
 
 	case 34: {
 		VM::ValAddr regRef = ctx->popReg();
-		ctx->setMem8(regRef, PTR_00417218->priority);
+		ctx->setMem8(regRef, _curObject->priority);
 		ctx->EAX.setVal(1);
 	} break;
 
@@ -2724,13 +2724,13 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			} else if (arg1 == 1) {
 				ActEntry tmp;
 				tmp.actid = 0xfe;
-				tmp.t = BYTE_004177f6;
+				tmp.t = _curObjectT;
 				tmp.flags = 0;
 				createActiveObject(tmp, _pathTargetCell);
 			} else if (arg1 == 2) {
 				ActEntry tmp;
 				tmp.actid = 0;
-				tmp.t = BYTE_004177f6;
+				tmp.t = _curObjectT;
 				tmp.flags = 0;
 				tmp.x = _pathTargetCell.x - _pathStartCell.x;
 				tmp.y = _pathTargetCell.y - _pathStartCell.y;
@@ -2745,7 +2745,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		if (_pathInMove) {
 			ActEntry tmp;
 			tmp.actid = arg1;
-			tmp.t = BYTE_004177f6;
+			tmp.t = _curObjectT;
 			tmp.flags = 0;
 			createActiveObject(tmp, _pathTargetCell);
 		}
@@ -2757,7 +2757,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		if (_pathInMove) {
 			ActEntry tmp;
 			tmp.actid = arg1;
-			tmp.t = BYTE_004177f6;
+			tmp.t = _curObjectT;
 			tmp.flags = 1;
 			createActiveObject(tmp, _pathTargetCell);
 		}
@@ -2768,7 +2768,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		arg1 = ctx->pop32();
 		// Seems here needed only ->t ?
 		// In AiTi arg1 0x20, 0x40, 0x80
-		ctx->EAX.setVal( ((PTR_00417218->flags | (PTR_00417218->t << 4)) & arg1) ? 1 : 0 );
+		ctx->EAX.setVal( ((_curObject->flags | (_curObject->t << 4)) & arg1) ? 1 : 0 );
 		break;
 
 	case 46: {
@@ -2785,11 +2785,11 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 		switch (arg1) {
 		case 0:
-			ctx->EAX.setVal(_d2_fld16 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_enableInput ? 1 : 0);
 			break;
 
 		case 1:
-			ctx->EAX.setVal(_d2_fld14 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_enableSounds ? 1 : 0);
 			break;
 
 		case 2:
@@ -2797,11 +2797,11 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			break;
 
 		case 3:
-			ctx->EAX.setVal(_d2_fld17 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_enableMovie ? 1 : 0);
 			break;
 
 		case 4:
-			ctx->EAX.setVal(_d2_fld18 != 0 ? 1 : 0);
+			ctx->EAX.setVal(_enableCDAudio ? 1 : 0);
 			break;
 
 		default:
@@ -2815,17 +2815,17 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 		switch (arg1) {
 		case 0:
-			_d2_fld16 = 0;
+			_enableInput = false;
 			break;
 		case 1:
-			_d2_fld16 = 1;
+			_enableInput = true;
 			break;
 		case 2:
-			_d2_fld14 = 0;
+			_enableSounds = false;
 			_sndVolumeTarget = 0;
 			break;
 		case 3:
-			_d2_fld14 = 1;
+			_enableSounds = true;
 			_sndVolumeTarget = _savedSndVolume;
 			break;
 		case 4:
@@ -2835,20 +2835,20 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			_midiVolumeTarget = _savedMidiVolume;
 			break;
 		case 6:
-			_d2_fld17 = 0;
+			_enableMovie = false;
 			break;
 		case 7:
-			_d2_fld17 = 1;
+			_enableMovie = true;
 			break;
 		case 8:
 			//FUN_0040a9c0(0);
-			_d2_fld18 = 0;
+			_enableCDAudio = false;
 			break;
 		case 9:
-			if (_d2_fld19 != 0xff) {
+			if (_cdAudioTrack != -1) {
 				//FUN_0040a958(_d2_fld19);
 			}
-			_d2_fld18 = 1;
+			_enableCDAudio = true;
 			break;
 		default:
 			break;
@@ -2913,7 +2913,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 			playVideo(Common::String(buffer), Common::Point(a, b), Common::Point(c, d));
 
-			if (_d2_fld19 != 0xff) {
+			if (_cdAudioTrack != -1) {
 				/* vm func 58 */
 			}
 
@@ -2997,14 +2997,14 @@ void GamosEngine::callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint3
 }
 
 uint32 GamosEngine::scriptFunc19(uint32 id) {
-	BYTE_004177fc = 1;
-	createGfxObject(id, Common::Point(DAT_00417220.x * _gridCellW, DAT_00417220.y * _gridCellH), false);
+	_gfxObjectCreated = true;
+	createGfxObject(id, Common::Point(_curObjectCurrentCell.x * _gridCellW, _curObjectCurrentCell.y * _gridCellH), false);
 
 	return 1;
 }
 
 uint32 GamosEngine::scriptFunc16(uint32 id) {
-	if (DAT_004177f8 == 0) {
+	if (!_ignoreSoundActions) {
 		stopMidi();
 		if (_enableMidi) {
 			_midiTrack = id;
@@ -3036,32 +3036,32 @@ bool GamosEngine::createGfxObject(uint32 id, Common::Point position, bool static
 	gfxObj->position = position;
 
 	if (!staticObject) {
-		if (!PTR_00417218) {
-			gfxObj->priority = PTR_00417214->priority;
+		if (!_curObject) {
+			gfxObj->priority = _curAction->priority;
 		} else {
 			int32 index = gfxObj->index;
-			if (PTR_00417218->curObjectId != -1) {
-				Object *pgObj = &_objects[PTR_00417218->curObjectId];
+			if (_curObject->curObjectId != -1) {
+				Object *pgObj = &_objects[_curObject->curObjectId];
 				addDirtRectOnObject(pgObj);
 				pgObj->flags &= ~Object::FLAG_GRAPHIC;
-				if (PTR_00417218->tgtObjectId != PTR_00417218->curObjectId)
+				if (_curObject->tgtObjectId != _curObject->curObjectId)
 					removeObject(pgObj);
 			}
 
-			PTR_00417218->curObjectId = index;
+			_curObject->curObjectId = index;
 			if (!(gfxObj->flags & Object::FLAG_DIRTRECT)) {
-				if (PTR_00417218->tgtObjectId != -1)
-					removeObject(&_objects[PTR_00417218->tgtObjectId]);
-				PTR_00417218->tgtObjectId = index;
+				if (_curObject->tgtObjectId != -1)
+					removeObject(&_objects[_curObject->tgtObjectId]);
+				_curObject->tgtObjectId = index;
 			}
 
-			gfxObj->priority = PTR_00417218->priority;
-			if (DAT_00417220 != DAT_00417228) {
-				PTR_00417218->flags |= Object::FLAG_TRANSITION;
+			gfxObj->priority = _curObject->priority;
+			if (_curObjectCurrentCell != _curObjectStartCell) {
+				_curObject->flags |= Object::FLAG_TRANSITION;
 			}
 		}
 	} else {
-		gfxObj->priority = PTR_00417218->priority;
+		gfxObj->priority = _curObject->priority;
 		gfxObj->cell.x = -1;
 		gfxObj->cell.y = -1;
 	}
@@ -3082,32 +3082,32 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 
 	if (spr.field_2 == 1) {
 		obj->pImg = &spr.sequences[0]->operator[](0);
-		if (BYTE_004177f6 == 8) {
+		if (_curObjectT == 8) {
 			if (spr.field_1 & 2)
 				obj->flags |= Object::FLAG_FLIPH;
-		} else if (BYTE_004177f6 == 4 && (spr.field_1 & 4)) {
+		} else if (_curObjectT == 4 && (spr.field_1 & 4)) {
 			obj->flags |= Object::FLAG_FLIPV;
 		}
 	} else {
-		if (BYTE_004177f6 == 1) {
+		if (_curObjectT == 1) {
 			obj->seqId = 1;
-			if (DAT_00417220.y == DAT_00417228.y && (spr.field_1 & 8))
+			if (_curObjectCurrentCell.y == _curObjectStartCell.y && (spr.field_1 & 8))
 				obj->seqId = 0;
-		} else if (BYTE_004177f6 == 2) {
+		} else if (_curObjectT == 2) {
 			obj->seqId = 3;
-			if (DAT_00417228.y < DAT_00417220.y)
+			if (_curObjectStartCell.y < _curObjectCurrentCell.y)
 				obj->seqId = 2;
-			else if (DAT_00417228.y > DAT_00417220.y) {
+			else if (_curObjectStartCell.y > _curObjectCurrentCell.y) {
 				obj->seqId = 4;
 				if (spr.field_1 & 4) {
 					obj->seqId = 2;
 					obj->flags |= Object::FLAG_FLIPV;
 				}
-			} else if (DAT_00417220.x == DAT_00417228.x && (spr.field_1 & 8))
+			} else if (_curObjectCurrentCell.x == _curObjectStartCell.x && (spr.field_1 & 8))
 				obj->seqId = 0;
-		} else if (BYTE_004177f6 == 4) {
+		} else if (_curObjectT == 4) {
 			obj->seqId = 5;
-			if (DAT_00417220.y == DAT_00417228.y && (spr.field_1 & 8))
+			if (_curObjectCurrentCell.y == _curObjectStartCell.y && (spr.field_1 & 8))
 				obj->seqId = 0;
 			else if (spr.field_1 & 4) {
 				obj->seqId = 1;
@@ -3115,15 +3115,15 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 			}
 		} else {
 			obj->seqId = 7;
-			if (DAT_00417220.y == DAT_00417228.y) {
-				if ((spr.field_1 & 8) && DAT_00417220.x == DAT_00417228.x)
+			if (_curObjectCurrentCell.y == _curObjectStartCell.y) {
+				if ((spr.field_1 & 8) && _curObjectCurrentCell.x == _curObjectStartCell.x)
 					obj->seqId = 0;
 				else if (spr.field_1 & 2) {
 					obj->seqId = 3;
 					obj->flags |= Object::FLAG_FLIPH;
 				}
 			} else {
-				if (DAT_00417228.y < DAT_00417220.y) {
+				if (_curObjectStartCell.y < _curObjectCurrentCell.y) {
 					obj->seqId = 8;
 					if (spr.field_1 & 2) {
 						obj->seqId = 2;
@@ -3149,7 +3149,7 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 		obj->pImg = &spr.sequences[obj->seqId]->operator[](0);
 	}
 	if (!p) {
-		obj->cell = DAT_00417228;
+		obj->cell = _curObjectStartCell;
 		FUN_0040921c(obj);
 	} else {
 		obj->flags |= Object::FLAG_FREECOORDS;
@@ -3162,7 +3162,7 @@ void GamosEngine::FUN_004095a0(Object *obj) {
 	if (obj->curObjectId != -1) {
 		Object &yobj = _objects[obj->curObjectId];
 		addDirtRectOnObject(&yobj);
-		if (DAT_00417228 != DAT_00417220)
+		if (_curObjectStartCell != _curObjectCurrentCell)
 			obj->flags |= Object::FLAG_TRANSITION;
 		FUN_00409378(yobj.sprId, &yobj, false);
 	}
@@ -3303,34 +3303,34 @@ void GamosEngine::processInput(Common::Point move, Common::Point actPos, uint8 a
 }
 
 uint32 GamosEngine::savedDoActions(const Actions &a) {
-	uint8 sv1 = BYTE_004177fc;
-	uint8 sv2 = BYTE_004177f6;
-	byte *sv3 = PTR_004173e8;
-	uint8 sv6 = _preprocDataId;
-	Common::Point sv8 = DAT_00417228;
-	Common::Point sv10 = DAT_00417220;
-	int sv11 = _curObjIndex;
-	Object *sv12 = PTR_00417218;
-	ObjectAction *sv13 = PTR_00417214;
-
-	uint32 res = doActions(a, true);
-
-	BYTE_004177fc = sv1;
-	BYTE_004177f6 = sv2;
-	PTR_004173e8 = sv3;
+	const bool sv1 = _gfxObjectCreated;
+	const uint8 sv2 = _curObjectT;
+	byte * const sv3 = _curObjStorage;
+	const uint8 sv6 = _preprocDataId;
+	const Common::Point sv8 = _curObjectStartCell;
+	const Common::Point sv10 = _curObjectCurrentCell;
+	const int sv11 = _curObjIndex;
+	Object * const sv12 = _curObject;
+	ObjectAction * const sv13 = _curAction;
+
+	const uint32 res = doActions(a, true);
+
+	_gfxObjectCreated = sv1;
+	_curObjectT = sv2;
+	_curObjStorage = sv3;
 	_preprocDataId = sv6;
-	DAT_00417228 = sv8;
-	DAT_00417220 = sv10;
+	_curObjectStartCell = sv8;
+	_curObjectCurrentCell = sv10;
 	_curObjIndex = sv11;
-	PTR_00417218 = sv12;
-	PTR_00417214 = sv13;
+	_curObject = sv12;
+	_curAction = sv13;
 
 	return res;
 }
 
 void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int32 sprId, int32 x, int32 y) {
-	removeSubtitles(PTR_00417218);
-	PTR_00417218->state.flags |= 2;
+	removeSubtitles(_curObject);
+	_curObject->state.flags |= 2;
 
 	while (true) {
 		uint8 ib = ctx->getMem8(memtype, offset);
@@ -3412,7 +3412,7 @@ Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32
 	gfxObj->flags |= Object::FLAG_GRAPHIC | Object::FLAG_OVERLAY | Object::FLAG_FREECOORDS;
 	gfxObj->frame = 0;
 	gfxObj->frameMax = 1;
-	gfxObj->priority = PTR_00417218->priority;
+	gfxObj->priority = _curObject->priority;
 	gfxObj->cell.x = -1;
 	gfxObj->cell.y = -1;
 	gfxObj->actObjIndex = _curObjIndex;
@@ -3468,7 +3468,7 @@ void GamosEngine::FUN_00407db8(uint8 p) {
 	else
 		_pathTargetCell = _inputActCell;
 
-	_pathStartCell = PTR_00417218->cell;
+	_pathStartCell = _curObject->cell;
 	_pathDir4 = -1;
 	_pathDir8 = -1;
 	_pathInMove = false;
@@ -3962,30 +3962,30 @@ void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
 	if (rnd)
 		val = _thing2[val].field_1[ 1 + rndRange16(_thing2[val].field_1[0]) ];
 
-	PTR_00417218->state = ObjState(val, 0, 1);
+	_curObject->state = ObjState(val, 0, 1);
 
 	ObjectAction &act = _objectActions[val];
-	executeScript(act.onCreateAddress, &act, nullptr, -1, nullptr, PTR_00417218->cell, 1);
+	executeScript(act.onCreateAddress, &act, nullptr, -1, nullptr, _curObject->cell, 1);
 }
 
 void GamosEngine::FUN_004025d0() {
-	if (PTR_00417218->state.actid != 0xfe) {
-		ObjectAction &act = _objectActions[PTR_00417218->state.actid];
+	if (_curObject->state.actid != 0xfe) {
+		ObjectAction &act = _objectActions[_curObject->state.actid];
 
 		for (int i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];
 			if (obj.isStaticObject() &&
 			        obj.actObjIndex == -1 &&
-			        obj.cell.x == PTR_00417218->cell.x &&
-			        obj.cell.y == PTR_00417218->cell.y) {
+			        obj.cell.x == _curObject->cell.x &&
+			        obj.cell.y == _curObject->cell.y) {
 
 				removeObjectMarkDirty(&obj);
 				break;
 			}
 		}
 
-		executeScript(act.onDeleteAddress, &act, nullptr, -1, nullptr, PTR_00417218->cell, PTR_00417218->state.t);
-		PTR_00417218->state = ObjState(0xfe, 0, 0xf);
+		executeScript(act.onDeleteAddress, &act, nullptr, -1, nullptr, _curObject->cell, _curObject->state.t);
+		_curObject->state = ObjState(0xfe, 0, 0xf);
 	}
 }
 
@@ -4164,14 +4164,14 @@ int GamosEngine::txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int
 	}
 
 	if (_txtInputActive == false) {
-		removeSubtitles(PTR_00417218);
-		PTR_00417218->state.flags |= 2;
+		removeSubtitles(_curObject);
+		_curObject->state.flags |= 2;
 		_txtInputVmOffset = offset;
 		_txtInputSpriteID = sprId;
 		_txtInputX = x;
 		_txtInputY = y;
-		_txtInputObject = PTR_00417218;
-		_txtInputAction = PTR_00417214;
+		_txtInputObject = _curObject;
+		_txtInputAction = _curAction;
 		_txtInputObjectIndex = _curObjIndex;
 
 		txtInputProcess(0);
@@ -4181,8 +4181,8 @@ int GamosEngine::txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int
 }
 
 void GamosEngine::txtInputProcess(uint8 c) {
-	PTR_00417218 = _txtInputObject;
-	PTR_00417214 = _txtInputAction;
+	_curObject = _txtInputObject;
+	_curAction = _txtInputAction;
 	_curObjIndex = _txtInputObjectIndex;
 
 	Sprite &spr = _sprites[_txtInputSpriteID];
@@ -4193,7 +4193,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 		if (ib == 0) {
 			if (_txtInputActive) {
 				_txtInputActive = false;
-				removeSubtitles(PTR_00417218);
+				removeSubtitles(_curObject);
 				return;
 			}
 			_txtInputActive = true;
@@ -4251,7 +4251,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 				_txtInputVMAccess.setMemType(VM::REF_EDI);
 				if ((_txtInputFlags & 0x70) == 0x10) {
 					_txtInputVMAccess.setMemType(VM::REF_EBX);
-					_txtInputVMAccess.objMem = PTR_004173e8;
+					_txtInputVMAccess.objMem = _curObjStorage;
 				}
 				if ( (_txtInputFlags & 0x80) == 0 ) {
 					_txtInputVMAccess.setOffset( _vm.memory().getU8(_txtInputVmOffset) );
@@ -4286,7 +4286,7 @@ void GamosEngine::txtInputProcess(uint8 c) {
 
 				if (_txtInputActive) {
 					_txtInputActive = false;
-					removeSubtitles(PTR_00417218);
+					removeSubtitles(_curObject);
 					return;
 				}
 				_txtInputActive = true;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4a69a9f9685..44764ae4e70 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -383,7 +383,7 @@ private:
 
 	byte _cmdByte = 0;
 
-	bool _runReadDataMod = false;
+	bool _isResLoadingProcess = false;
 	int _currentModuleID = 0;
 
 	byte _saveLoadID = 0;
@@ -443,8 +443,8 @@ private:
 
 
 
-	uint8 BYTE_004177f7 = 0;
-	uint8 DAT_004177f8 = 0;
+	bool _isSaveLoadingProcess = false;
+	bool _ignoreSoundActions = false;
 
 
 	uint8 _inputMouseActId = 0;
@@ -461,11 +461,11 @@ private:
 	int32 _svModuleId = 0;
 	int32 _svGameScreen = 0;
 	uint32 _d2_fld10 = 0;
-	uint8 _d2_fld14 = 0;
-	uint8 _d2_fld16 = 0;
-	uint8 _d2_fld17 = 0;
-	uint8 _d2_fld18 = 0;
-	uint8 _d2_fld19 = 0;
+	bool _enableSounds = false;
+	bool _enableInput = false;
+	bool _enableMovie = false;
+	bool _enableCDAudio = false;
+	int8 _cdAudioTrack = -1;
 	int32 _scrollX = 0;
 	int32 _scrollY = 0;
 	int32 _scrollTrackObj = 0;
@@ -519,23 +519,23 @@ private:
 
 	Pool<Object> _objects;
 
-	uint8 BYTE_00412200 = 0;
+	bool _curObjectActProcessed = false;
 
-	Object *DAT_00412204 = nullptr;
+	Object *_firstUpdateObject = nullptr;
 
-	ObjectAction *PTR_00417214 = nullptr;
-	Object *PTR_00417218 = nullptr;
+	ObjectAction *_curAction = nullptr;
+	Object *_curObject = nullptr;
 	Object *_inputActObj = nullptr;
 
-	uint8 BYTE_004177f6 = 0;
-	uint8 BYTE_004177fc = 0;
-	bool DAT_004177ff = false;
+	uint8 _curObjectT = 0;
+	bool _gfxObjectCreated = false;
+	bool _restartUpdateObject = false;
 
 
-	byte *PTR_004173e8 = nullptr;
+	byte *_curObjStorage = nullptr;
 
-	Common::Point DAT_00417220;
-	Common::Point DAT_00417228;
+	Common::Point _curObjectCurrentCell;
+	Common::Point _curObjectStartCell;
 
 	byte *PTR_00417388 = nullptr;
 
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index 125f235c2b0..736d916ecb9 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -28,7 +28,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 	switch (ev.type) {
 	case Common::EVENT_KEYDOWN:
-		if ((_gd2flags & 1) == 0)
+		if ((_inputFlags & 1) == 0)
 			return;
 
 		_ascii = ev.kbd.ascii;
@@ -77,7 +77,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 		break;
 
 	case Common::EVENT_MOUSEMOVE:
-		if ((_gd2flags & 2) == 0)
+		if ((_inputFlags & 2) == 0)
 			return;
 
 		_mouseReportedPos = ev.mouse;
@@ -86,7 +86,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 	case Common::EVENT_LBUTTONDOWN:
 	case Common::EVENT_RBUTTONDOWN:
-		if ((_gd2flags & 2) == 0)
+		if ((_inputFlags & 2) == 0)
 			return;
 
 		_mouseActPos = ev.mouse;
@@ -94,7 +94,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 		break;
 
 	case Common::EVENT_LBUTTONUP:
-		if ((_gd2flags & 2) == 0)
+		if ((_inputFlags & 2) == 0)
 			return;
 
 		_mouseActPos = ev.mouse;
@@ -103,7 +103,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 		break;
 
 	case Common::EVENT_RBUTTONUP:
-		if ((_gd2flags & 2) == 0)
+		if ((_inputFlags & 2) == 0)
 			return;
 
 		_mouseActPos = ev.mouse;
diff --git a/engines/gamos/proc.h b/engines/gamos/proc.h
index 99b28522c0d..36ff71e6f7f 100644
--- a/engines/gamos/proc.h
+++ b/engines/gamos/proc.h
@@ -55,7 +55,7 @@ public:
 	Common::Point _mouseReportedPos;
 	Common::Point _mouseActPos;
 
-	uint8 _gd2flags = 0; /* 0x4 */
+	uint8 _inputFlags = 0; /* 0x4 */
 	uint8 _keyCodes[12]; /* 0x40 */
 
 };
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 761b7045645..9c19a14cf47 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -131,7 +131,7 @@ bool GamosEngine::writeStateFile() {
 	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
-	if (!_runReadDataMod) {
+	if (!_isResLoadingProcess) {
 		if (sm->exists(fname)) {
 			Common::InSaveFile *rsv = sm->openForLoading(fname);
 			byte svdata[0x4c];
@@ -165,7 +165,7 @@ bool GamosEngine::loadStateFile() {
 	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
-	if (!_runReadDataMod) {
+	if (!_isResLoadingProcess) {
 		if (sm->exists(fname)) {
 			Common::SeekableReadStream *rs = sm->openForLoading(fname);
 			rs->seek(0x4c);
@@ -184,7 +184,7 @@ bool GamosEngine::loadStateFile() {
 
 			zeroVMData(_xorSeq[1]);
 
-			_runReadDataMod = false;
+			_isResLoadingProcess = false;
 
 			delete rs;
 		}
@@ -197,19 +197,19 @@ void GamosEngine::writeStateData(Common::SeekableWriteStream *stream) {
 	memcpy(buf, _stateExt.c_str(), _stateExt.size() > 4 ? 4 : _stateExt.size());
 
 	stream->write(buf, 4); // 0
-	stream->writeByte(_messageProc._gd2flags);  // 4
+	stream->writeByte(_messageProc._inputFlags);  // 4
 	stream->writeByte(0);  // 5
 	stream->writeByte(0);  // 6
 	stream->writeByte(0);  // 7
 	stream->writeSint32LE(_svModuleId); // 8
 	stream->writeSint32LE(_svGameScreen); // 0xc
 	stream->writeUint32LE(_d2_fld10); // 0x10
-	stream->writeByte(_d2_fld14); // 0x14
+	stream->writeByte(_enableSounds ? 1 : 0); // 0x14
 	stream->writeByte(_enableMidi ? 1 : 0); // 0x15
-	stream->writeByte(_d2_fld16); // 0x16
-	stream->writeByte(_d2_fld17); // 0x17
-	stream->writeByte(_d2_fld18); // 0x18
-	stream->writeByte(_d2_fld19); // 0x19
+	stream->writeByte(_enableInput ? 1 : 0); // 0x16
+	stream->writeByte(_enableMovie ? 1 : 0); // 0x17
+	stream->writeByte(_enableCDAudio ? 1 : 0); // 0x18
+	stream->writeSByte(_cdAudioTrack); // 0x19
 	stream->writeByte(0); // 0x1a
 	stream->writeByte(0); // 0x1b
 	stream->writeSint32LE(_scrollX); // 0x1c
@@ -237,17 +237,17 @@ void GamosEngine::writeStateData(Common::SeekableWriteStream *stream) {
 void GamosEngine::loadStateData(Common::SeekableReadStream *dataStream) {
 	_stateExt = dataStream->readString(0, 4); // FIX ME
 	dataStream->seek(4);
-	_messageProc._gd2flags = dataStream->readByte(); //4
+	_messageProc._inputFlags = dataStream->readByte(); //4
 	dataStream->seek(8);
 	_svModuleId = dataStream->readSint32LE(); // 8
 	_svGameScreen = dataStream->readSint32LE(); // c
 	_d2_fld10 = dataStream->readUint32LE(); // x10
-	_d2_fld14 = dataStream->readByte(); // x14
+	_enableSounds = dataStream->readByte() != 0 ? true : false; // x14
 	_enableMidi = dataStream->readByte() != 0 ? true : false; //x15
-	_d2_fld16 = dataStream->readByte(); // x16
-	_d2_fld17 = dataStream->readByte(); // x17
-	_d2_fld18 = dataStream->readByte(); // x18
-	_d2_fld19 = dataStream->readByte(); // x19
+	_enableInput = dataStream->readByte() != 0 ? true : false; // x16
+	_enableMovie = dataStream->readByte() != 0 ? true : false; // x17
+	_enableCDAudio = dataStream->readByte() != 0 ? true : false; // x18
+	_cdAudioTrack = dataStream->readSByte(); // x19
 	dataStream->seek(0x1c);
 	_scrollX = dataStream->readSint32LE(); // x1c
 	_scrollY = dataStream->readSint32LE(); // x20
@@ -363,30 +363,30 @@ bool GamosEngine::loadSaveFile(int id) {
 	if (!rs)
 		return false;
 
-	const uint8 sv1 = _d2_fld18;
-	const uint8 sv2 = _d2_fld17;
-	const uint8 sv3 = _d2_fld16;
+	const bool sv1 = _enableCDAudio;
+	const bool sv2 = _enableMovie;
+	const bool sv3 = _enableInput;
 	const bool svmdi = _enableMidi;
-	const uint8 sv4 = _d2_fld14;
+	const bool sv4 = _enableSounds;
 
 	loadStateData(rs);
 
 	_sndVolume = _sndVolumeTarget;
 	_midiVolume = 0;
-	_d2_fld14 = sv4;
+	_enableSounds = sv4;
 	_enableMidi = svmdi;
-	_d2_fld16 = sv3;
-	_d2_fld17 = sv2;
-	_d2_fld18 = sv1;
+	_enableInput = sv3;
+	_enableMovie = sv2;
+	_enableCDAudio = sv1;
 
 	_musicPlayer.setVolume(0);
 
 	const int32 cursorImgId = _mouseCursorImgId;
 	const int32 svMidiTrack = _midiTrack;
-	const uint8 cdtrack = _d2_fld19;
+	const int8 cdtrack = _cdAudioTrack;
 
-	_runReadDataMod = true;
-	BYTE_004177f7 = 1;
+	_isResLoadingProcess = true;
+	_isSaveLoadingProcess = true;
 
 	loadModule(_svModuleId);
 
@@ -426,10 +426,10 @@ bool GamosEngine::loadSaveFile(int id) {
 	_vm.memory().setU8(_addrFPS, _svFps);
 	_vm.memory().setU32(_addrCurrentFrame, _svFrame);
 
-	_runReadDataMod = false;
-	BYTE_004177f7 = 0;
+	_isResLoadingProcess = false;
+	_isSaveLoadingProcess = false;
 
-	if (cdtrack != 0xff) {
+	if (cdtrack != -1) {
 		//vmfunc_58(cdtrack);
 	}
 


Commit: 245ae2ffb4ffaf218249a317b64575890e6d9231
    https://github.com/scummvm/scummvm/commit/245ae2ffb4ffaf218249a317b64575890e6d9231
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:02+01:00

Commit Message:
GAMOS: Give names for methods

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/movie.cpp
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 00ffebbeb19..c57f36281cc 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -138,7 +138,7 @@ Common::Error GamosEngine::run() {
 
 	stopSounds();
 	stopMidi();
-	stopMCI();
+	stopCDAudio();
 
 	_enableMovie = true;
 	_enableMidi = true;
@@ -255,7 +255,7 @@ bool GamosEngine::loadModule(uint id) {
 	_xorSeq[2].clear();
 
 	stopMidi();
-	stopMCI();
+	stopCDAudio();
 	stopSounds();
 
 	/* Complete me */
@@ -449,7 +449,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_13) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
 	} else if (tp == RESTP_18) {
-		loadRes18(pid, data, dataSize);
+		loadBackground(pid, data, dataSize);
 	} else if (tp == RESTP_19) {
 		if (!_isSaveLoadingProcess) {
 			for (int i = 0; i < _states.size(); i++)
@@ -506,13 +506,13 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_3A) {
 		_thing2[pid].field_2.assign(data, data + dataSize);
 	} else if (tp == RESTP_40) {
-		return loadRes40(pid, data, dataSize);
+		return loadSpriteInfo(pid, data, dataSize);
 	} else if (tp == RESTP_41) {
-		return loadRes41(pid, data, dataSize);
+		return loadSpriteSeqLength(pid, data, dataSize);
 	} else if (tp == RESTP_42) {
-		return loadRes42(pid, p1, data, dataSize);
+		return loadSpriteSeqImageInfo(pid, p1, data, dataSize);
 	} else if (tp == RESTP_43) {
-		return loadRes43(pid, p1, p2, data, dataSize);
+		return loadSpriteSeqImageData(pid, p1, p2, data, dataSize);
 	} else if (tp == RESTP_50) {
 		/* just ignore it? */
 	} else if (tp == RESTP_51) {
@@ -520,7 +520,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		_soundSamples[pid].assign(data + 4, data + 4 + datSz);
 		//warning("sound  size %d", dataSize);
 	} else if (tp == RESTP_52) {
-		return loadRes52(pid, data, dataSize);
+		return loadMidiTrack(pid, data, dataSize);
 		//warning("midi  size %d", dataSize);
 	} else if (tp == RESTP_60) {
 		_subtitleActions[pid].parse(data, dataSize);
@@ -751,7 +751,7 @@ void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
 	}
 }
 
-bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteInfo(int32 id, const byte *data, size_t dataSize) {
 	if (dataSize < 4)
 		return false;
 
@@ -768,7 +768,7 @@ bool GamosEngine::loadRes40(int32 id, const byte *data, size_t dataSize) {
 	return true;
 }
 
-bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteSeqLength(int32 id, const byte *data, size_t dataSize) {
 	if (*(const uint32 *)data != 0)
 		error("41 not null!!!");
 
@@ -778,7 +778,7 @@ bool GamosEngine::loadRes41(int32 id, const byte *data, size_t dataSize) {
 	return true;
 }
 
-bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, size_t dataSize) {
 	//warning("loadRes42 pid %d p %d sz %x",id, p1, dataSize);
 
 	if (_sprites[id].sequences.size() == 0)
@@ -802,7 +802,7 @@ bool GamosEngine::loadRes42(int32 id, int32 p1, const byte *data, size_t dataSiz
 	return true;
 }
 
-bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize) {
 	_images.push_back(new Image());
 	_sprites[id].sequences[p1]->operator[](p2).image = _images.back();
 
@@ -840,12 +840,12 @@ bool GamosEngine::loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size
 	return true;
 }
 
-bool GamosEngine::loadRes52(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadMidiTrack(int32 id, const byte *data, size_t dataSize) {
 	_midiTracks[id].assign(data, data + dataSize);
 	return true;
 }
 
-bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadBackground(int32 id, const byte *data, size_t dataSize) {
 	GameScreen &bimg = _gameScreens[id];
 	bimg.loaded = true;
 	bimg.offset = _readingBkgOffset;
@@ -882,20 +882,20 @@ bool GamosEngine::loadRes18(int32 id, const byte *data, size_t dataSize) {
 
 bool GamosEngine::playIntro() {
 	if (_movieCount != 0 && _playIntro == 1)
-		return scriptFunc18(0);
+		return playMovie(0);
 	return true;
 }
 
-bool GamosEngine::playMovie(int id) {
+bool GamosEngine::moviePlayerPlay(int id) {
 	bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
 	return res;
 }
 
 
-bool GamosEngine::scriptFunc18(uint32 id) {
+bool GamosEngine::playMovie(uint32 id) {
 	if (_enableMovie) {
 		_isMoviePlay++;
-		bool res = playMovie(id);
+		bool res = moviePlayerPlay(id);
 		_isMoviePlay--;
 		return res;
 	}
@@ -908,8 +908,9 @@ void GamosEngine::stopMidi() {
 	_midiStarted = false;
 }
 
-void GamosEngine::stopMCI() {
+void GamosEngine::stopCDAudio() {
 	//warning("Not implemented stopMCI");
+	_cdAudioTrack = -1;
 }
 
 void GamosEngine::stopSounds() {
@@ -1226,27 +1227,27 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 	if (_enableInput == 0) {
 		act1 = ACT_NONE;
 		act2 = ACT_NONE;
-		RawKeyCode = ACT_NONE;
+		_pressedKeyCode = ACT_NONE;
 	}
 
-	RawKeyCode = keyCode;
+	_pressedKeyCode = keyCode;
 
-	if (RawKeyCode != 0 && RawKeyCode != ACT_NONE) {
+	if (_pressedKeyCode != 0 && _pressedKeyCode != ACT_NONE) {
 		if (_keySeq.size() >= 32)
 			_keySeq = _keySeq.substr(_keySeq.size() - 31);
 
-		_keySeq += RawKeyCode;
+		_keySeq += _pressedKeyCode;
 	}
 
 	processInput(mouseMove, actPos, act2, act1);
 	changeVolume();
 
-	if (!FUN_00402bc4())
+	if (!updateVMInputFrameStates())
 		return 0;
 
 	bool loop = false;
 	if (!_txtInputActive)
-		loop = FUN_00402fb4();
+		loop = updateObjects();
 	else
 		loop = onTxtInputUpdate(act2);
 
@@ -1261,13 +1262,13 @@ uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Com
 				return 0;
 		}
 
-		RawKeyCode = ACT_NONE;
+		_pressedKeyCode = ACT_NONE;
 
-		if (!FUN_00402bc4())
+		if (!updateVMInputFrameStates())
 			return 0;
 
 		if (!_txtInputActive)
-			loop = FUN_00402fb4();
+			loop = updateObjects();
 		else
 			loop = onTxtInputUpdate(act2);
 
@@ -1392,7 +1393,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 		preprocessDataB1(e.t, &e);
 		rnd();
 		e.flags = a.act_4.flags;
-		FUN_00402a68(e);
+		processActionCurObject(e);
 		if (_needReload)
 			return 0;
 	}
@@ -1411,7 +1412,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 	}
 
 	if (!_gfxObjectCreated && _curObjectActProcessed)
-		FUN_004095a0(_curObject);
+		updateLinkedGfxObject(_curObject);
 
 	int32 retval = 0;
 
@@ -1668,7 +1669,7 @@ int GamosEngine::processData(ActEntry e, bool absolute) {
 	}
 }
 
-void GamosEngine::FUN_00402a68(ActEntry e) {
+void GamosEngine::processActionCurObject(ActEntry e) {
 	if (e.x != 0 || e.y != 0) {
 		_curObjectCurrentCell.x = (e.x + _curObjectCurrentCell.x + _statesWidth) % _statesWidth;
 		_curObjectCurrentCell.y = (e.y + _curObjectCurrentCell.y + _statesHeight) % _statesHeight;
@@ -1929,7 +1930,7 @@ void GamosEngine::executeScript(int32 scriptAddr, ObjectAction *act, Object *pob
 	_curAction = sv9;
 }
 
-bool GamosEngine::FUN_00402fb4() {
+bool GamosEngine::updateObjects() {
 	if (_objects.empty())
 		return true;
 
@@ -1952,7 +1953,7 @@ bool GamosEngine::FUN_00402fb4() {
 								Object &o = _objects[pobj->tgtObjectId];
 								o.flags |= Object::FLAG_GRAPHIC;
 								o.cell = pobj->cell;
-								FUN_0040921c(&o);
+								updateGfxObjectPosition(&o);
 								addDirtRectOnObject(&o);
 							}
 						}
@@ -1963,7 +1964,7 @@ bool GamosEngine::FUN_00402fb4() {
 								Object &o = _objects[pobj->tgtObjectId];
 								o.flags |= Object::FLAG_GRAPHIC;
 								o.cell = pobj->cell;
-								FUN_0040921c(&o);
+								updateGfxObjectPosition(&o);
 								addDirtRectOnObject(&o);
 							}
 							pobj->flags &= ~Object::FLAG_TRANSITION;
@@ -2085,14 +2086,14 @@ bool GamosEngine::updateGfxFrames(Object *obj, bool p2, bool p1) {
 		}
 
 		if ((obj->flags & Object::FLAG_FREECOORDS) == 0)
-			FUN_0040921c(obj);
+			updateGfxObjectPosition(obj);
 
 		addDirtRectOnObject(obj);
 	}
 	return false;
 }
 
-void GamosEngine::FUN_0040921c(Object *gfxObj) {
+void GamosEngine::updateGfxObjectPosition(Object *gfxObj) {
 	ImagePos *imgPos = gfxObj->pImg;
 	Image *img = imgPos->image;
 
@@ -2372,7 +2373,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		ctx->EAX.setVal(0);
 
 		for(uint i = 0; i < str.size(); i++) {
-			if (str[i] == RawKeyCode) {
+			if (str[i] == _pressedKeyCode) {
 				ctx->EAX.setVal(1);
 				break;
 			}
@@ -2395,7 +2396,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 16:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( scriptFunc16(arg1) );
+		ctx->EAX.setVal( playMidiTrack(arg1) );
 		break;
 
 	case 17:
@@ -2407,12 +2408,14 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 18:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( scriptFunc18(arg1) ? 1 : 0 );
+		ctx->EAX.setVal( playMovie(arg1) ? 1 : 0 );
 		break;
 
 	case 19:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( scriptFunc19(arg1) );
+		_gfxObjectCreated = true;
+		createGfxObject(arg1, Common::Point(_curObjectCurrentCell.x * _gridCellW, _curObjectCurrentCell.y * _gridCellH), false);
+		ctx->EAX.setVal( 1 );
 		break;
 
 	case 20: {
@@ -2477,19 +2480,19 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 
 	case 27:
-		FUN_004025d0();
+		removeStaticGfxCurObj();
 		ctx->EAX.setVal(1);
 		break;
 
 	case 28:
 		arg1 = ctx->pop32();
-		FUN_0040279c(arg1, false);
+		runRenewStaticGfxCurObj(arg1, false);
 		ctx->EAX.setVal(1);
 		break;
 
 	case 29:
 		arg1 = ctx->pop32();
-		FUN_0040279c(arg1, true);
+		runRenewStaticGfxCurObj(arg1, true);
 		ctx->EAX.setVal(1);
 		break;
 
@@ -2734,7 +2737,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 				tmp.flags = 0;
 				tmp.x = _pathTargetCell.x - _pathStartCell.x;
 				tmp.y = _pathTargetCell.y - _pathStartCell.y;
-				FUN_00402a68(tmp);
+				processActionCurObject(tmp);
 			}
 		}
 		ctx->EAX.setVal(1);
@@ -2918,7 +2921,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 			}
 
 			if (_midiTrack != -1) {
-				scriptFunc16(_midiTrack);
+				playMidiTrack(_midiTrack);
 			}
 		}
 		ctx->EAX.setVal(1);
@@ -2996,14 +2999,7 @@ void GamosEngine::callbackVMCallDispatcher(void *engine, VM::Context *ctx, uint3
 	gamos->vmCallDispatcher(ctx, funcID);
 }
 
-uint32 GamosEngine::scriptFunc19(uint32 id) {
-	_gfxObjectCreated = true;
-	createGfxObject(id, Common::Point(_curObjectCurrentCell.x * _gridCellW, _curObjectCurrentCell.y * _gridCellH), false);
-
-	return 1;
-}
-
-uint32 GamosEngine::scriptFunc16(uint32 id) {
+uint32 GamosEngine::playMidiTrack(uint32 id) {
 	if (!_ignoreSoundActions) {
 		stopMidi();
 		if (_enableMidi) {
@@ -3066,11 +3062,11 @@ bool GamosEngine::createGfxObject(uint32 id, Common::Point position, bool static
 		gfxObj->cell.y = -1;
 	}
 
-	FUN_00409378(id, gfxObj, staticObject);
+	gfxObjectCalculateFlip(id, gfxObj, staticObject);
 	return true;
 }
 
-void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
+void GamosEngine::gfxObjectCalculateFlip(int32 sprId, Object *obj, bool p) {
 	obj->flags &= ~(Object::FLAG_FLIPH | Object::FLAG_FLIPV);
 	obj->actID = 0;
 	obj->frame = 0;
@@ -3150,7 +3146,7 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 	}
 	if (!p) {
 		obj->cell = _curObjectStartCell;
-		FUN_0040921c(obj);
+		updateGfxObjectPosition(obj);
 	} else {
 		obj->flags |= Object::FLAG_FREECOORDS;
 	}
@@ -3158,13 +3154,13 @@ void GamosEngine::FUN_00409378(int32 sprId, Object *obj, bool p) {
 	addDirtRectOnObject(obj);
 }
 
-void GamosEngine::FUN_004095a0(Object *obj) {
+void GamosEngine::updateLinkedGfxObject(Object *obj) {
 	if (obj->curObjectId != -1) {
 		Object &yobj = _objects[obj->curObjectId];
 		addDirtRectOnObject(&yobj);
 		if (_curObjectStartCell != _curObjectCurrentCell)
 			obj->flags |= Object::FLAG_TRANSITION;
-		FUN_00409378(yobj.sprId, &yobj, false);
+		gfxObjectCalculateFlip(yobj.sprId, &yobj, false);
 	}
 }
 
@@ -3217,7 +3213,7 @@ void GamosEngine::setCursor(int id, bool dirtRect) {
 }
 
 
-bool GamosEngine::FUN_00409600(Object *obj, Common::Point pos) {
+bool GamosEngine::checkPointOnLinkedGfx(Object *obj, Common::Point pos) {
 	if (obj->curObjectId == -1)
 		return false;
 
@@ -3262,7 +3258,7 @@ void GamosEngine::processInput(Common::Point move, Common::Point actPos, uint8 a
 					obj.inputFlag = 0;
 			}
 
-			if ((!pobj || obj.priority <= pobjF5) && FUN_00409600(&obj, actPos)) {
+			if ((!pobj || obj.priority <= pobjF5) && checkPointOnLinkedGfx(&obj, actPos)) {
 				actT = action.actType;
 				pobjF5 = obj.priority;
 				pobj = &obj;
@@ -3429,12 +3425,12 @@ Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32
 	return gfxObj;
 }
 
-bool GamosEngine::FUN_00402bc4() {
-	if (RawKeyCode == ACT_NONE) {
+bool GamosEngine::updateVMInputFrameStates() {
+	if (_pressedKeyCode == ACT_NONE) {
 		_vm.memory().setU8(_addrKeyCode, 0);
 		_vm.memory().setU8(_addrKeyDown, 0);
 	} else {
-		_vm.memory().setU8(_addrKeyCode, RawKeyCode);
+		_vm.memory().setU8(_addrKeyCode, _pressedKeyCode);
 		_vm.memory().setU8(_addrKeyDown, 1);
 	}
 
@@ -3956,8 +3952,8 @@ void Actions::parse(const byte *data, size_t dataSize) {
 	}
 }
 
-void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
-	FUN_004025d0();
+void GamosEngine::runRenewStaticGfxCurObj(uint8 val, bool rnd) {
+	removeStaticGfxCurObj();
 
 	if (rnd)
 		val = _thing2[val].field_1[ 1 + rndRange16(_thing2[val].field_1[0]) ];
@@ -3968,7 +3964,7 @@ void GamosEngine::FUN_0040279c(uint8 val, bool rnd) {
 	executeScript(act.onCreateAddress, &act, nullptr, -1, nullptr, _curObject->cell, 1);
 }
 
-void GamosEngine::FUN_004025d0() {
+void GamosEngine::removeStaticGfxCurObj() {
 	if (_curObject->state.actid != 0xfe) {
 		ObjectAction &act = _objectActions[_curObject->state.actid];
 
@@ -4340,11 +4336,11 @@ bool GamosEngine::onTxtInputUpdate(uint8 c) {
 		}
 	}
 
-	if (RawKeyCode != KeyCodes::WIN_SPACE && RawKeyCode != KeyCodes::WIN_RETURN &&
-		(RawKeyCode == ACT_NONE || c != ACT_NONE) )
+	if (_pressedKeyCode != KeyCodes::WIN_SPACE && _pressedKeyCode != KeyCodes::WIN_RETURN &&
+		(_pressedKeyCode == ACT_NONE || c != ACT_NONE) )
 		return true;
 
-	txtInputProcess(RawKeyCode);
+	txtInputProcess(_pressedKeyCode);
 	return true;
 }
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 44764ae4e70..5c9df970acc 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -548,7 +548,7 @@ private:
 	uint8 _inputActId = 0;
 	bool _pathInMove = false;
 
-	uint8 RawKeyCode = 0;
+	uint8 _pressedKeyCode = 0;
 
 	Common::String _keySeq;
 
@@ -617,14 +617,14 @@ protected:
 
 	void loadXorSeq(const byte *data, size_t dataSize, int id);
 
-	bool loadRes40(int32 id, const byte *data, size_t dataSize);
-	bool loadRes41(int32 id, const byte *data, size_t dataSize);
-	bool loadRes42(int32 id, int32 p1, const byte *data, size_t dataSize);
-	bool loadRes43(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize);
+	bool loadSpriteInfo(int32 id, const byte *data, size_t dataSize);
+	bool loadSpriteSeqLength(int32 id, const byte *data, size_t dataSize);
+	bool loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, size_t dataSize);
+	bool loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize);
 
-	bool loadRes52(int32 id, const byte *data, size_t dataSize);
+	bool loadMidiTrack(int32 id, const byte *data, size_t dataSize);
 
-	bool loadRes18(int32 id, const byte *data, size_t dataSize);
+	bool loadBackground(int32 id, const byte *data, size_t dataSize);
 
 	void freeImages();
 	void freeSequences();
@@ -639,14 +639,13 @@ protected:
 
 
 	void stopMidi();
-	void stopMCI();
+	void stopCDAudio();
 	void stopSounds();
 
 	bool playIntro();
 
-	bool scriptFunc18(uint32 id);
-	uint32 scriptFunc19(uint32 id);
-	uint32 scriptFunc16(uint32 id);
+	bool playMovie(uint32 id);
+	uint32 playMidiTrack(uint32 id);
 
 	void setErrMessage(const Common::String &msg);
 
@@ -659,7 +658,7 @@ protected:
 	int32 doActions(const Actions &a, bool absolute);
 	uint32 savedDoActions(const Actions &a);
 
-	uint32 getU32(const void *ptr);
+	static uint32 getU32(const void *ptr);
 
 	void preprocessData(int id, ActEntry *e);
 	void preprocessDataB1(int id, ActEntry *e);
@@ -667,7 +666,7 @@ protected:
 
 	void executeScript(int32 scriptAddr, ObjectAction *act, Object *pobj, int32 index, byte *storage, Common::Point cell, uint8 t);
 
-	void FUN_00402a68(ActEntry e);
+	void processActionCurObject(ActEntry e);
 
 	void createActiveObject(ActEntry e, Common::Point cell);
 
@@ -681,14 +680,14 @@ protected:
 	void removeSubtitles(Object *obj);
 	void cycleNextInputObj(Object *obj);
 
-	bool FUN_00402fb4();
+	bool updateObjects();
 
 	bool updateMouseCursor(Common::Point mouseMove);
 	bool scrollAndDraw();
-	bool FUN_00402bc4();
+	bool updateVMInputFrameStates();
 	bool updateGfxFrames(Object *obj, bool p2, bool p1);
 
-	void FUN_0040921c(Object *obj);
+	void updateGfxObjectPosition(Object *obj);
 	void addDirtRectOnObject(Object *obj);
 	void addDirtyRect(const Common::Rect &rect);
 
@@ -704,16 +703,16 @@ protected:
 
 	bool createGfxObject(uint32 id, Common::Point position, bool p);
 
-	void FUN_00409378(int32 sprId, Object *obj, bool p);
+	void gfxObjectCalculateFlip(int32 sprId, Object *obj, bool p);
 
-	void FUN_004095a0(Object *obj);
+	void updateLinkedGfxObject(Object *obj);
 
-	bool playMovie(int id);
+	bool moviePlayerPlay(int id);
 
 	void setCursor(int id, bool dirtRect);
 
 	void processInput(Common::Point move, Common::Point actPos, uint8 act2, uint8 act1);
-	bool FUN_00409600(Object *obj, Common::Point pos);
+	bool checkPointOnLinkedGfx(Object *obj, Common::Point pos);
 
 	void setNeedReload() {
 		_needReload = true;
@@ -741,12 +740,11 @@ protected:
 	byte FUN_00408778(const Common::Array<byte> &arr);
 	byte FUN_0040881c(const Common::Array<byte> &arr);
 
+	bool FUN_0040705c(int a, int b);
 
 
-
-	void FUN_0040279c(uint8 val, bool rnd);
-	void FUN_004025d0();
-	bool FUN_0040705c(int a, int b);
+	void runRenewStaticGfxCurObj(uint8 val, bool rnd);
+	void removeStaticGfxCurObj();
 
 	int txtInputBegin(VM::Context *ctx, byte memtype, int32 offset, int sprId, int32 x, int32 y);
 	void txtInputProcess(uint8 c);
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index f5e50a40abe..bff4ccf17ec 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -48,7 +48,7 @@ bool MoviePlayer::init(Common::File *file, uint32 offset, GamosEngine *gamos) {
 	_frameSize = Common::Point(_screen->w, _screen->h);
 
 	_gamos->stopMidi();
-	_gamos->stopMCI();
+	_gamos->stopCDAudio();
 
 	_file = file;
 	return _file->seek(offset, SEEK_SET);
@@ -59,7 +59,7 @@ bool MoviePlayer::deinit() {
 		_gamos->stopSounds();
 
 	_gamos->stopMidi();
-	_gamos->stopMCI();
+	_gamos->stopCDAudio();
 
 	_gamos->setPaletteCurrentGS();
 
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 9c19a14cf47..2c74dc41eb0 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -434,7 +434,7 @@ bool GamosEngine::loadSaveFile(int id) {
 	}
 
 	if (svMidiTrack != -1)
-		scriptFunc16(svMidiTrack);
+		playMidiTrack(svMidiTrack);
 
 	_midiVolume = 0;
 


Commit: 0c99c33d5bcc2fb67584c7a786fd6de54c6be58f
    https://github.com/scummvm/scummvm/commit/0c99c33d5bcc2fb67584c7a786fd6de54c6be58f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:02+01:00

Commit Message:
GAMOS: remove unused code created by engine template

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/metaengine.cpp
    engines/gamos/metaengine.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index c57f36281cc..658e9542865 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -150,17 +150,6 @@ Common::Error GamosEngine::run() {
 	return Common::kNoError;
 }
 
-Common::Error GamosEngine::syncGame(Common::Serializer &s) {
-	// The Serializer has methods isLoading() and isSaving()
-	// if you need to specific steps; for example setting
-	// an array size after reading it's length, whereas
-	// for saving it would write the existing array's length
-	int dummy = 0;
-	s.syncAsUint32LE(dummy);
-
-	return Common::kNoError;
-}
-
 bool GamosEngine::loader2() {
 	int32 skipsz = _arch.readSint32LE();
 	_arch.skip(skipsz);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 5c9df970acc..4949321cef1 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -829,36 +829,6 @@ public:
 	Common::String getRunFile() const;
 
 	uint32 getEngineVersion() const;
-
-
-	bool hasFeature(EngineFeature f) const override {
-		return
-		    (f == kSupportsLoadingDuringRuntime) ||
-		    (f == kSupportsSavingDuringRuntime) ||
-		    (f == kSupportsReturnToLauncher);
-	};
-
-	bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override {
-		return true;
-	}
-	bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override {
-		return true;
-	}
-
-	/**
-	 * Uses a serializer to allow implementing savegame
-	 * loading and saving using a single method
-	 */
-	Common::Error syncGame(Common::Serializer &s);
-
-	Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override {
-		Common::Serializer s(nullptr, stream);
-		return syncGame(s);
-	}
-	Common::Error loadGameStream(Common::SeekableReadStream *stream) override {
-		Common::Serializer s(stream, nullptr);
-		return syncGame(s);
-	}
 };
 
 extern GamosEngine *g_engine;
diff --git a/engines/gamos/metaengine.cpp b/engines/gamos/metaengine.cpp
index 97ab6298757..862d838f2bb 100644
--- a/engines/gamos/metaengine.cpp
+++ b/engines/gamos/metaengine.cpp
@@ -34,11 +34,6 @@ Common::Error GamosMetaEngine::createInstance(OSystem *syst, Engine **engine, co
 	return Common::kNoError;
 }
 
-bool GamosMetaEngine::hasFeature(MetaEngineFeature f) const {
-	return checkExtendedSaves(f) ||
-	       (f == kSupportsLoadingDuringStartup);
-}
-
 #if PLUGIN_ENABLED_DYNAMIC(GAMOS)
 REGISTER_PLUGIN_DYNAMIC(GAMOS, PLUGIN_TYPE_ENGINE, GamosMetaEngine);
 #else
diff --git a/engines/gamos/metaengine.h b/engines/gamos/metaengine.h
index bdb19c957fb..2a97274a8db 100644
--- a/engines/gamos/metaengine.h
+++ b/engines/gamos/metaengine.h
@@ -30,13 +30,6 @@ public:
 	const char *getName() const override;
 
 	Common::Error createInstance(OSystem *syst, Engine **engine, const Gamos::GamosGameDescription *desc) const override;
-
-	/**
-	 * Determine whether the engine supports the specified MetaEngine feature.
-	 *
-	 * Used by e.g. the launcher to determine whether to enable the Load button.
-	 */
-	bool hasFeature(MetaEngineFeature f) const override;
 };
 
 #endif // GAMOS_METAENGINE_H


Commit: a0c3e99c3029116cbf5bb6699590a8f18f9b6341
    https://github.com/scummvm/scummvm/commit/a0c3e99c3029116cbf5bb6699590a8f18f9b6341
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:03+01:00

Commit Message:
GAMOS: give names for fields of Sprite and Unknown1 structures

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 658e9542865..83273669e3c 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -150,6 +150,7 @@ Common::Error GamosEngine::run() {
 	return Common::kNoError;
 }
 
+
 bool GamosEngine::loader2() {
 	int32 skipsz = _arch.readSint32LE();
 	_arch.skip(skipsz);
@@ -489,11 +490,14 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		//warning("RESTP_2C %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
 	} else if (tp == RESTP_38) {
 		//warning("Data 38 size %zu", dataSize);
-		_thing2[pid].field_0.assign(data, data + dataSize);
+		_thing2[pid].masks.assign(data, data + dataSize);
 	} else if (tp == RESTP_39) {
-		_thing2[pid].field_1.assign(data, data + dataSize);
+		if (data[0] == 0)
+			_thing2[pid].oids.clear();
+		else
+			_thing2[pid].oids.assign(data + 1, data + 1 + data[0]);
 	} else if (tp == RESTP_3A) {
-		_thing2[pid].field_2.assign(data, data + dataSize);
+		_thing2[pid].actsT.assign(data, data + dataSize);
 	} else if (tp == RESTP_40) {
 		return loadSpriteInfo(pid, data, dataSize);
 	} else if (tp == RESTP_41) {
@@ -748,9 +752,9 @@ bool GamosEngine::loadSpriteInfo(int32 id, const byte *data, size_t dataSize) {
 		warning("dataSize > 4");
 
 	_sprites[id].field_0 = data[0];
-	_sprites[id].field_1 = data[1];
-	_sprites[id].field_2 = data[2];
-	_sprites[id].field_3 = data[3];
+	_sprites[id].flags = data[1];
+	_sprites[id].lastChar = data[2];
+	_sprites[id].frameCount = data[3];
 
 	_onlyScanImage = data[1] & 0x80;
 
@@ -810,7 +814,7 @@ bool GamosEngine::loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byt
 		img->offset = s.readSint32LE();
 		img->cSize = s.readSint32LE();
 	} else {
-		if (_sprites[id].field_1 & 0x80) {
+		if (_sprites[id].flags & 0x80) {
 			if (_arch._lastReadDecompressedSize) {
 				img->offset = _arch._lastReadDataOffset;
 				img->cSize = _arch._lastReadSize;
@@ -1341,10 +1345,10 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 						cval = 2;
 					}
 				} else if (fb.actid != 0xfe &&
-				           (_thing2[e.actid].field_0[(fb.actid) >> 3] & (1 << (fb.actid & 7))) != 0) {
+				           (_thing2[e.actid].masks[(fb.actid) >> 3] & (1 << (fb.actid & 7))) != 0) {
 
-					if (!_thing2[e.actid].field_2.empty()) {
-						e.t = _thing2[e.actid].field_2[fb.actid] >> 4;
+					if (!_thing2[e.actid].actsT.empty()) {
+						e.t = _thing2[e.actid].actsT[fb.actid] >> 4;
 						preprocessData(fnc + 8, &e);
 					}
 
@@ -1706,11 +1710,11 @@ void GamosEngine::createActiveObject(ActEntry e, Common::Point cell) {
 		}
 	} else {
 		Unknown1 &unk1 = _thing2[ oid ];
-		uint8 index = rndRange16(unk1.field_1[0]);
-		oid = unk1.field_1[ index + 1 ];
-		if (!unk1.field_2.empty()) {
+		uint8 index = rndRange16(unk1.oids.size());
+		oid = unk1.oids[ index ];
+		if (!unk1.actsT.empty()) {
 			byte id1 = e.t;
-			e.t = unk1.field_2[ oid ] >> 4;
+			e.t = unk1.actsT[ oid ] >> 4;
 			preprocessData(8 + id1, &e);
 		}
 	}
@@ -2353,7 +2357,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 	case 12:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( _thing2[arg1].field_0[ _curObject->state.actid >> 3 ] & (1 << (_curObject->state.actid & 7)) );
+		ctx->EAX.setVal( _thing2[arg1].masks[ _curObject->state.actid >> 3 ] & (1 << (_curObject->state.actid & 7)) );
 		break;
 	case 13: {
 		VM::ValAddr regRef = ctx->popReg();
@@ -2864,7 +2868,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 	case 50:
 		arg1 = ctx->pop32();
-		PTR_00417388 = _thing2[arg1].field_0.data();
+		PTR_00417388 = _thing2[arg1].masks.data();
 		ctx->EAX.setVal(1);
 		break;
 
@@ -3009,10 +3013,10 @@ bool GamosEngine::createGfxObject(uint32 id, Common::Point position, bool static
 
 	gfxObj->flags |= Object::FLAG_GRAPHIC;
 
-	if (spr.field_1 & 1)
+	if (spr.flags & 1)
 		gfxObj->flags |= Object::FLAG_DIRTRECT;
 
-	gfxObj->frameMax = spr.field_3;
+	gfxObj->frameMax = spr.frameCount;
 	int16 idx = -1;
 	if (!staticObject)
 		idx = _curObjIndex;
@@ -3065,18 +3069,18 @@ void GamosEngine::gfxObjectCalculateFlip(int32 sprId, Object *obj, bool p) {
 	Sprite &spr = _sprites[sprId];
 
 
-	if (spr.field_2 == 1) {
+	if (spr.lastChar == 1) {
 		obj->pImg = &spr.sequences[0]->operator[](0);
 		if (_curObjectT == 8) {
-			if (spr.field_1 & 2)
+			if (spr.flags & 2)
 				obj->flags |= Object::FLAG_FLIPH;
-		} else if (_curObjectT == 4 && (spr.field_1 & 4)) {
+		} else if (_curObjectT == 4 && (spr.flags & 4)) {
 			obj->flags |= Object::FLAG_FLIPV;
 		}
 	} else {
 		if (_curObjectT == 1) {
 			obj->seqId = 1;
-			if (_curObjectCurrentCell.y == _curObjectStartCell.y && (spr.field_1 & 8))
+			if (_curObjectCurrentCell.y == _curObjectStartCell.y && (spr.flags & 8))
 				obj->seqId = 0;
 		} else if (_curObjectT == 2) {
 			obj->seqId = 3;
@@ -3084,47 +3088,47 @@ void GamosEngine::gfxObjectCalculateFlip(int32 sprId, Object *obj, bool p) {
 				obj->seqId = 2;
 			else if (_curObjectStartCell.y > _curObjectCurrentCell.y) {
 				obj->seqId = 4;
-				if (spr.field_1 & 4) {
+				if (spr.flags & 4) {
 					obj->seqId = 2;
 					obj->flags |= Object::FLAG_FLIPV;
 				}
-			} else if (_curObjectCurrentCell.x == _curObjectStartCell.x && (spr.field_1 & 8))
+			} else if (_curObjectCurrentCell.x == _curObjectStartCell.x && (spr.flags & 8))
 				obj->seqId = 0;
 		} else if (_curObjectT == 4) {
 			obj->seqId = 5;
-			if (_curObjectCurrentCell.y == _curObjectStartCell.y && (spr.field_1 & 8))
+			if (_curObjectCurrentCell.y == _curObjectStartCell.y && (spr.flags & 8))
 				obj->seqId = 0;
-			else if (spr.field_1 & 4) {
+			else if (spr.flags & 4) {
 				obj->seqId = 1;
 				obj->flags |= Object::FLAG_FLIPV;
 			}
 		} else {
 			obj->seqId = 7;
 			if (_curObjectCurrentCell.y == _curObjectStartCell.y) {
-				if ((spr.field_1 & 8) && _curObjectCurrentCell.x == _curObjectStartCell.x)
+				if ((spr.flags & 8) && _curObjectCurrentCell.x == _curObjectStartCell.x)
 					obj->seqId = 0;
-				else if (spr.field_1 & 2) {
+				else if (spr.flags & 2) {
 					obj->seqId = 3;
 					obj->flags |= Object::FLAG_FLIPH;
 				}
 			} else {
 				if (_curObjectStartCell.y < _curObjectCurrentCell.y) {
 					obj->seqId = 8;
-					if (spr.field_1 & 2) {
+					if (spr.flags & 2) {
 						obj->seqId = 2;
 						obj->flags |= Object::FLAG_FLIPH;
 					}
 				} else {
 					obj->seqId = 6;
-					if (spr.field_1 & 4) {
+					if (spr.flags & 4) {
 						obj->seqId = 8;
 						obj->flags |= Object::FLAG_FLIPV;
 
-						if (spr.field_1 & 2) {
+						if (spr.flags & 2) {
 							obj->seqId = 2;
 							obj->flags |= Object::FLAG_FLIPH;
 						}
-					} else if (spr.field_1 & 2) {
+					} else if (spr.flags & 2) {
 						obj->seqId = 4;
 						obj->flags |= Object::FLAG_FLIPH;
 					}
@@ -3405,7 +3409,7 @@ Object *GamosEngine::addSubtitleImage(uint32 frame, int32 spr, int32 *pX, int32
 	gfxObj->position.y = y;
 	gfxObj->sprId = spr;
 	gfxObj->seqId = 0;
-	gfxObj->frame = frame - _sprites[spr].field_1;
+	gfxObj->frame = frame - _sprites[spr].startChar;
 	gfxObj->pImg = &_sprites[spr].sequences[gfxObj->seqId]->operator[](gfxObj->frame);
 
 	*pX += gfxObj->pImg->image->surface.w - gfxObj->pImg->xoffset;
@@ -3766,24 +3770,24 @@ byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
 		if (p1 != _inputMouseActType)
 			return 0;
 
-		if ( (_thing2[p2].field_0[ _inputMouseActId >> 3 ] & (1 << (_inputMouseActId & 7))) == 0 )
+		if ( (_thing2[p2].masks[ _inputMouseActId >> 3 ] & (1 << (_inputMouseActId & 7))) == 0 )
 			return 0;
 	} else {
 		if (p1 != 0xe) {
 			if (p3 == 0xff)
-				return FUN_004086e4(_thing2[p2].field_0);
+				return FUN_004086e4(_thing2[p2].masks);
 			else
-				return FUN_00408778(_thing2[p2].field_0);
+				return FUN_00408778(_thing2[p2].masks);
 		}
 
-		if ( (_thing2[p2].field_0[ _inputActId >> 3 ] & (1 << (_inputActId & 7))) == 0 )
+		if ( (_thing2[p2].masks[ _inputActId >> 3 ] & (1 << (_inputActId & 7))) == 0 )
 			return 0;
 	}
 
 	if (p3 == 0xff)
 		return pathFindMoveToTarget();
 	else if (p3 == 0xfe)
-		return FUN_0040881c(_thing2[p2].field_0);
+		return FUN_0040881c(_thing2[p2].masks);
 	else
 		return FUN_0040856c();
 }
@@ -3945,7 +3949,7 @@ void GamosEngine::runRenewStaticGfxCurObj(uint8 val, bool rnd) {
 	removeStaticGfxCurObj();
 
 	if (rnd)
-		val = _thing2[val].field_1[ 1 + rndRange16(_thing2[val].field_1[0]) ];
+		val = _thing2[val].oids[ rndRange16(_thing2[val].oids.size()) ];
 
 	_curObject->state = ObjState(val, 0, 1);
 
@@ -3979,10 +3983,10 @@ bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
 	if (_mouseCursorImgId >= 0 && _drawCursor == 0 && _mouseCursorImgId < _sprites.size()) {
 		Sprite &cursorSpr = _sprites[_mouseCursorImgId];
 
-		if (cursorSpr.field_3 > 1) {
+		if (cursorSpr.frameCount > 1) {
 
 			_cursorFrame++;
-			if (_cursorFrame >= cursorSpr.field_3)
+			if (_cursorFrame >= cursorSpr.frameCount)
 				_cursorFrame = 0;
 
 			ImagePos &impos = cursorSpr.sequences[0]->operator[](_cursorFrame);
@@ -4284,11 +4288,11 @@ void GamosEngine::txtInputProcess(uint8 c) {
 
 		if (_txtInputTyped) {
 			if (_txtInputLength < _txtInputMaxLength) {
-				if (ib < spr.field_1)
+				if (ib < spr.startChar)
 					ib = tolower(ib);
-				if (ib > spr.field_2)
+				if (ib > spr.lastChar)
 					ib = toupper(ib);
-				if (ib >= spr.field_1 && ib <= spr.field_2 &&
+				if (ib >= spr.startChar && ib <= spr.lastChar &&
 				   (_txtInputIsNumber == false || Common::isDigit(ib))) {
 					_txtInputBuffer[_txtInputLength] = ib;
 					_txtInputObjects[_txtInputLength] = addSubtitleImage(ib, _txtInputSpriteID, &_txtInputX, _txtInputY);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4949321cef1..33c60718eae 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -143,10 +143,15 @@ typedef Common::Array<ImagePos> ImageSeq;
 
 struct Sprite {
 	uint32 index = 0;
+
 	byte field_0;
-	byte field_1;
-	byte field_2;
-	byte field_3;
+	union
+	{
+		byte flags;
+		byte startChar; // if it's font
+	};
+	byte lastChar;
+	byte frameCount;
 
 	Common::Array<ImageSeq *> sequences;
 };
@@ -158,10 +163,9 @@ struct XorArg {
 };
 
 struct Unknown1 {
-	Common::Array<byte> field_0;
-	Common::Array<byte> field_1;
-	Common::Array<byte> field_2;
-	uint32 field_3;
+	Common::Array<byte> masks;
+	Common::Array<byte> oids;
+	Common::Array<byte> actsT;
 };
 
 struct ObjState {


Commit: 8837689bd18fad9ec011246c28d8cf8641214e48
    https://github.com/scummvm/scummvm/commit/8837689bd18fad9ec011246c28d8cf8641214e48
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:03+01:00

Commit Message:
GAMOS: give names for resource types

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 83273669e3c..e58aaf45569 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -287,7 +287,7 @@ bool GamosEngine::loadModule(uint id) {
 		case 4: {
 			_resReadOffset = _arch.pos();
 			bool isResource = true;
-			if (prevByte == RESTP_F) {
+			if (prevByte == RESTP_GAMECONF) {
 				RawData data;
 				if (!_arch.readCompressedData(&data))
 					return false;
@@ -306,18 +306,18 @@ bool GamosEngine::loadModule(uint id) {
 					_scrollBorderL = 0;
 				}
 				isResource = false; /* do not loadResHandler */
-			} else if (prevByte == RESTP_10) {
+			} else if (prevByte == RESTP_GAMECONF2) {
 				if (!initMainDatas())
 					return false;
 				isResource = false; /* do not loadResHandler */
-			} else if (prevByte == RESTP_11) {
+			} else if (prevByte == RESTP_DATACONF) {
 				RawData data;
 				if (!_arch.readCompressedData(&data))
 					return false;
 				if (pid == id)
 					readElementsConfig(data);
 				isResource = false; /* do not loadResHandler */
-			} else if (prevByte == RESTP_18) {
+			} else if (prevByte == RESTP_BKG) {
 				/* free elements ? */
 				_readingBkgOffset = _arch.pos();
 				_countReadedBkg++;
@@ -336,15 +336,15 @@ bool GamosEngine::loadModule(uint id) {
 			uint32 datasz = (data.size() + 3) & (~3);
 
 			switch (prevByte) {
-			case RESTP_11:
-			case RESTP_18:
-			case RESTP_19:
-			case RESTP_20:
-			case RESTP_40:
-			case RESTP_50:
+			case RESTP_DATACONF:
+			case RESTP_BKG:
+			case RESTP_INITACT:
+			case RESTP_ACT_INFO:
+			case RESTP_SPR_INFO:
+			case RESTP_UNKNOWN_50:
 				break;
 
-			case RESTP_43:
+			case RESTP_SPR_SEQIMGDATA:
 				//warning("t %x sz %x sum %x", prevByte, data.size(), _loadedDataSize);
 				if (_onlyScanImage)
 					_loadedDataSize += 0x10;
@@ -419,7 +419,7 @@ bool GamosEngine::loadModule(uint id) {
 }
 
 bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize) {
-	if (tp == RESTP_12) {
+	if (tp == RESTP_VMSTATE) {
 		Common::MemoryReadStream dataStream(data, dataSize, DisposeAfterUse::NO);
 
 		_addrBlk12 = _loadedDataSize;
@@ -436,11 +436,11 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		_vm.memory().setU32(_addrCurrentFrame, dataStream.readUint32LE());
 
 		setFPS(_fps);
-	} else if (tp == RESTP_13) {
+	} else if (tp == RESTP_VMDATA) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
-	} else if (tp == RESTP_18) {
+	} else if (tp == RESTP_BKG) {
 		loadBackground(pid, data, dataSize);
-	} else if (tp == RESTP_19) {
+	} else if (tp == RESTP_INITACT) {
 		if (!_isSaveLoadingProcess) {
 			for (int i = 0; i < _states.size(); i++)
 				_states.at(i) = ObjState(0xfe, 0, 0xf);
@@ -458,66 +458,66 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 
 			storeToGameScreen(pid);
 		}
-	} else if (tp == RESTP_20) {
+	} else if (tp == RESTP_ACT_INFO) {
 		if (dataSize != 4)
 			return false;
 		_objectActions[pid].actType = data[0];
 		_objectActions[pid].mask = data[1];
 		_objectActions[pid].priority = data[2];
 		_objectActions[pid].storageSize = data[3] + 1;
-	} else if (tp == RESTP_21) {
+	} else if (tp == RESTP_ACT_ONCREATE) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onCreateAddress = _loadedDataSize + p3;
-		//warning("RESTP_21 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
-	} else if (tp == RESTP_22) {
+		//warning("RESTP_ACT_ONCREATE %x pid %d sz %x", _loadedDataSize, pid, dataSize);
+	} else if (tp == RESTP_ACT_ONDELETE) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].onDeleteAddress = _loadedDataSize + p3;
-		//warning("RESTP_22 %x pid %d sz %x", _loadedDataSize, pid, dataSize);
-	} else if (tp == RESTP_23) {
+		//warning("RESTP_ACT_ONDELETE %x pid %d sz %x", _loadedDataSize, pid, dataSize);
+	} else if (tp == RESTP_ACT_COUNT) {
 		if (dataSize % 4 != 0 || dataSize < 4)
 			return false;
 		_objectActions[pid].actions.resize(dataSize / 4);
-	} else if (tp == RESTP_2A) {
+	} else if (tp == RESTP_ACT_DATA) {
 		Actions &scr = _objectActions[pid].actions[p1];
 		scr.parse(data, dataSize);
-	} else if (tp == RESTP_2B) {
+	} else if (tp == RESTP_ACT_COND) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].actions[p1].conditionAddress = _loadedDataSize + p3;
-		//warning("RESTP_2B %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
-	} else if (tp == RESTP_2C) {
+		//warning("RESTP_ACT_COND %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
+	} else if (tp == RESTP_ACT_FUNC) {
 		_vm.writeMemory(_loadedDataSize, data, dataSize);
 		_objectActions[pid].actions[p1].functionAddress = _loadedDataSize + p3;
-		//warning("RESTP_2C %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
-	} else if (tp == RESTP_38) {
+		//warning("RESTP_ACT_FUNC %x pid %d p1 %d sz %x", _loadedDataSize, pid, p1, dataSize);
+	} else if (tp == RESTP_UNK_MASKS) {
 		//warning("Data 38 size %zu", dataSize);
 		_thing2[pid].masks.assign(data, data + dataSize);
-	} else if (tp == RESTP_39) {
+	} else if (tp == RESTP_UNK_OIDS) {
 		if (data[0] == 0)
 			_thing2[pid].oids.clear();
 		else
 			_thing2[pid].oids.assign(data + 1, data + 1 + data[0]);
-	} else if (tp == RESTP_3A) {
+	} else if (tp == RESTP_UNK_ACTST) {
 		_thing2[pid].actsT.assign(data, data + dataSize);
-	} else if (tp == RESTP_40) {
+	} else if (tp == RESTP_SPR_INFO) {
 		return loadSpriteInfo(pid, data, dataSize);
-	} else if (tp == RESTP_41) {
+	} else if (tp == RESTP_SPR_SEQLEN) {
 		return loadSpriteSeqLength(pid, data, dataSize);
-	} else if (tp == RESTP_42) {
+	} else if (tp == RESTP_SPR_SEQIMGINFO) {
 		return loadSpriteSeqImageInfo(pid, p1, data, dataSize);
-	} else if (tp == RESTP_43) {
+	} else if (tp == RESTP_SPR_SEQIMGDATA) {
 		return loadSpriteSeqImageData(pid, p1, p2, data, dataSize);
-	} else if (tp == RESTP_50) {
+	} else if (tp == RESTP_UNKNOWN_50) {
 		/* just ignore it? */
-	} else if (tp == RESTP_51) {
+	} else if (tp == RESTP_SFX_SAMPLE) {
 		uint32 datSz = getU32(data) & (~3);
 		_soundSamples[pid].assign(data + 4, data + 4 + datSz);
 		//warning("sound  size %d", dataSize);
-	} else if (tp == RESTP_52) {
+	} else if (tp == RESTP_MIDI_TRACK) {
 		return loadMidiTrack(pid, data, dataSize);
 		//warning("midi  size %d", dataSize);
-	} else if (tp == RESTP_60) {
+	} else if (tp == RESTP_SUB_ACT) {
 		_subtitleActions[pid].parse(data, dataSize);
-	} else if (tp == RESTP_61) {
+	} else if (tp == RESTP_SUB_PLACE) {
 		Common::MemoryReadStream dataStream(data, dataSize, DisposeAfterUse::NO);
 		const int count = dataSize / 8;
 		_subtitlePoints[pid].resize(count);
@@ -548,9 +548,9 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 }
 
 bool GamosEngine::reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3) {
-	if (tp == RESTP_43) {
+	if (tp == RESTP_SPR_SEQIMGDATA) {
 		_sprites[pid].sequences[p1]->operator[](p2).image = _images.back();
-	} else if (tp == RESTP_42) {
+	} else if (tp == RESTP_SPR_SEQIMGINFO) {
 		_sprites[pid].sequences[p1] = _imgSeq.back();
 	} else {
 		error("Reuse of resource not implemented: resource type %x, id %d %d %d %d", tp, pid, p1, p2, p3);
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 33c60718eae..f32a991a8d9 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -72,32 +72,32 @@ enum CONFTYPE {
 
 
 enum RESTYPE {
-	RESTP_F = 0xf,
-	RESTP_10 = 0x10,
-	RESTP_11 = 0x11,
-	RESTP_12 = 0x12,
-	RESTP_13 = 0x13,
-	RESTP_18 = 0x18,
-	RESTP_19 = 0x19,
-	RESTP_20 = 0x20,
-	RESTP_21 = 0x21,
-	RESTP_22 = 0x22,
-	RESTP_23 = 0x23,
-	RESTP_2A = 0x2a,
-	RESTP_2B = 0x2b,
-	RESTP_2C = 0x2c,
-	RESTP_38 = 0x38,
-	RESTP_39 = 0x39,
-	RESTP_3A = 0x3a,
-	RESTP_40 = 0x40,
-	RESTP_41 = 0x41,
-	RESTP_42 = 0x42,
-	RESTP_43 = 0x43,
-	RESTP_50 = 0x50,
-	RESTP_51 = 0x51,
-	RESTP_52 = 0x52,
-	RESTP_60 = 0x60,
-	RESTP_61 = 0x61,
+	RESTP_GAMECONF = 0xf,
+	RESTP_GAMECONF2 = 0x10,
+	RESTP_DATACONF = 0x11,
+	RESTP_VMSTATE = 0x12,
+	RESTP_VMDATA = 0x13,
+	RESTP_BKG = 0x18,
+	RESTP_INITACT = 0x19,
+	RESTP_ACT_INFO = 0x20,
+	RESTP_ACT_ONCREATE = 0x21,
+	RESTP_ACT_ONDELETE = 0x22,
+	RESTP_ACT_COUNT = 0x23,
+	RESTP_ACT_DATA = 0x2a,
+	RESTP_ACT_COND = 0x2b,
+	RESTP_ACT_FUNC = 0x2c,
+	RESTP_UNK_MASKS = 0x38,
+	RESTP_UNK_OIDS = 0x39,
+	RESTP_UNK_ACTST = 0x3a,
+	RESTP_SPR_INFO = 0x40,
+	RESTP_SPR_SEQLEN = 0x41,
+	RESTP_SPR_SEQIMGINFO = 0x42,
+	RESTP_SPR_SEQIMGDATA = 0x43,
+	RESTP_UNKNOWN_50 = 0x50,
+	RESTP_SFX_SAMPLE = 0x51,
+	RESTP_MIDI_TRACK = 0x52,
+	RESTP_SUB_ACT = 0x60,
+	RESTP_SUB_PLACE = 0x61,
 	RESTP_XORSEQ0 = 0x7c,
 	RESTP_XORSEQ1 = 0x7d,
 	RESTP_XORSEQ2 = 0x7e,


Commit: 04ecd4bd8c2cc218808a492500143d3d6cdfcda5
    https://github.com/scummvm/scummvm/commit/04ecd4bd8c2cc218808a492500143d3d6cdfcda5
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:03+01:00

Commit Message:
GAMOS: Use exe name as base for save file names

Changed paths:
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index 2c74dc41eb0..e9b41684dc8 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -128,7 +128,7 @@ Common::String GamosEngine::makeSaveName(const Common::String &main, int id, con
 
 
 bool GamosEngine::writeStateFile() {
-	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
+	Common::String fname = makeSaveName(getRunFile(), _saveLoadID, _stateExt);
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
 	if (!_isResLoadingProcess) {
@@ -162,7 +162,7 @@ bool GamosEngine::writeStateFile() {
 }
 
 bool GamosEngine::loadStateFile() {
-	Common::String fname = makeSaveName(getGameId(), _saveLoadID, _stateExt);
+	Common::String fname = makeSaveName(getRunFile(), _saveLoadID, _stateExt);
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
 	if (!_isResLoadingProcess) {
@@ -307,7 +307,7 @@ void GamosEngine::zeroVMData(const Common::Array<XorArg> &seq) {
 
 
 bool GamosEngine::writeSaveFile(int id) {
-	Common::String fname = makeSaveName(getGameId(), id, "sav");
+	Common::String fname = makeSaveName(getRunFile(), id, "sav");
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
 	Common::OutSaveFile *osv = sm->openForSaving(fname);
@@ -356,7 +356,7 @@ bool GamosEngine::writeSaveFile(int id) {
 }
 
 bool GamosEngine::loadSaveFile(int id) {
-	Common::String fname = makeSaveName(getGameId(), id, "sav");
+	Common::String fname = makeSaveName(getRunFile(), id, "sav");
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
 	Common::SeekableReadStream *rs = sm->openForLoading(fname);
@@ -510,7 +510,7 @@ void GamosEngine::loadObjectData(Common::SeekableReadStream *stream, Object *obj
 
 
 bool GamosEngine::deleteSaveFile(int id) {
-	Common::String fname = makeSaveName(getGameId(), id, "sav");
+	Common::String fname = makeSaveName(getRunFile(), id, "sav");
 	Common::SaveFileManager *sm = _system->getSavefileManager();
 
 	if ( !sm->exists(fname) )


Commit: 859a0a4858eeea50e0225afbb89ab4c31c94942e
    https://github.com/scummvm/scummvm/commit/859a0a4858eeea50e0225afbb89ab4c31c94942e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:04+01:00

Commit Message:
GAMOS: Add conversion input into win1251 and win1252 codepages

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/keycodes.cpp
    engines/gamos/keycodes.h
    engines/gamos/proc.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index e58aaf45569..b294a045e41 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -97,6 +97,11 @@ Common::Error GamosEngine::run() {
 	CursorMan.setDefaultArrowCursor();
 	CursorMan.showMouse(true);
 
+	if (getGameLanguage() == Common::RU_RUS)
+		setCP1251();
+	else
+		setCP1252();
+
 	init(getRunFile());
 
 	Common::Event e;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index f32a991a8d9..b02ef866036 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -825,6 +825,9 @@ public:
 
 	uint32 getFeatures() const;
 
+	Common::Language getGameLanguage() {
+		return _gameDescription->desc.language;
+	}
 	/**
 	 * Returns the game Id
 	 */
diff --git a/engines/gamos/keycodes.cpp b/engines/gamos/keycodes.cpp
index 95afeb1bc26..e468b5a0da6 100644
--- a/engines/gamos/keycodes.cpp
+++ b/engines/gamos/keycodes.cpp
@@ -20,6 +20,8 @@
  */
 
 #include "gamos/gamos.h"
+#include "common/enc-internal.h"
+
 namespace Gamos {
 
 KeyCodes::KeyCodes() {
@@ -291,4 +293,32 @@ KeyCodes::KeyCodes() {
 	_scummCodes[WIN_BROWSER_FAVORITES] = Common::KEYCODE_AC_BOOKMARKS;
 }
 
+void KeyCodes::setCPTable(const uint16 *table, uint16 size, uint16 offset) {
+	uint16 codeMax = 0x7f;
+
+	for(uint32 i = 0; i < size; i++) {
+		if (table[i] > codeMax)
+			codeMax = table[i];
+	}
+
+	_cpTable.clear();
+	_cpTable.resize(codeMax + 1, 0);
+
+	//ascii
+	for (uint8 i = 0x20; i < 0x7f; i++)
+		_cpTable[i] = i;
+
+	//cp
+	for(uint32 i = 0; i < size; i++)
+		_cpTable[ table[i] ] = offset + i;
+}
+
+void KeyCodes::setCP1251() {
+	setCPTable(Common::kWindows1251ConversionTable, 128, 0x80);
+}
+
+void KeyCodes::setCP1252() {
+	setCPTable(Common::kWindows1252ConversionTable, 128, 0x80);
+}
+
 }
diff --git a/engines/gamos/keycodes.h b/engines/gamos/keycodes.h
index 51a31608d82..8ceabdb27ed 100644
--- a/engines/gamos/keycodes.h
+++ b/engines/gamos/keycodes.h
@@ -263,9 +263,13 @@ private:
 	uint8 _winCodes[Common::KEYCODE_LAST];
 	uint16 _scummCodes[256];
 
+	Common::Array<uint8> _cpTable;
+
 protected:
 	KeyCodes();
 
+	void setCPTable(const uint16 *table, uint16 size, uint16 offset = 0x80);
+
 public:
 	uint8 GetWinCode(uint16 code) {
 		return _winCodes[code];
@@ -273,6 +277,15 @@ public:
 	uint16 GetScummCode(uint8 code) {
 		return _scummCodes[code];
 	};
+
+	void setCP1251();
+	void setCP1252();
+
+	uint16 getCPCode(uint16 code) const {
+		if (code >= _cpTable.size())
+			return 0;
+		return _cpTable[code];
+	}
 };
 
 
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index 736d916ecb9..25280178f58 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -33,11 +33,18 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 		_ascii = ev.kbd.ascii;
 
-		if (ev.kbd.ascii)
-			_rawKeyCode = ev.kbd.ascii;
-
 		winKey = _codesConverter->GetWinCode(ev.kbd.keycode);
 
+		if (winKey == KeyCodes::WIN_BACK ||
+			winKey == KeyCodes::WIN_RETURN ||
+			winKey == KeyCodes::WIN_ESCAPE)
+			_rawKeyCode = winKey;
+		else if (_ascii != 0)
+			_rawKeyCode = _codesConverter->getCPCode(_ascii);
+
+		if (_rawKeyCode == 0)
+			_rawKeyCode = ACT_NONE;
+
 		if (winKey == _keyCodes[0])
 			_act1 = 0;
 		else if (winKey == _keyCodes[1])


Commit: 7b32a31b16610faf80a7590cc56bf958fa451330
    https://github.com/scummvm/scummvm/commit/7b32a31b16610faf80a7590cc56bf958fa451330
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:04+01:00

Commit Message:
GAMOS: Move const methods into header

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index b294a045e41..af0d8f3b644 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -55,22 +55,6 @@ GamosEngine::~GamosEngine() {
 	delete _screen;
 }
 
-uint32 GamosEngine::getFeatures() const {
-	return _gameDescription->desc.flags;
-}
-
-Common::String GamosEngine::getGameId() const {
-	return _gameDescription->desc.gameId;
-}
-
-Common::String GamosEngine::getRunFile() const {
-	return _gameDescription->runFile;
-}
-
-uint32 GamosEngine::getEngineVersion() const {
-	return _gameDescription->engineVersion;
-}
-
 void GamosEngine::freeImages() {
 	for (Image *img : _images)
 		delete img;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index b02ef866036..caadf3dbb9c 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -823,19 +823,25 @@ public:
 	GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc);
 	~GamosEngine() override;
 
-	uint32 getFeatures() const;
+	uint32 getFeatures() const {
+		return _gameDescription->desc.flags;
+	}
+
+	Common::String getGameId() const {
+		return _gameDescription->desc.gameId;
+	}
 
 	Common::Language getGameLanguage() {
 		return _gameDescription->desc.language;
 	}
-	/**
-	 * Returns the game Id
-	 */
-	Common::String getGameId() const;
 
-	Common::String getRunFile() const;
+	Common::String getRunFile() const {
+		return _gameDescription->runFile;
+	}
 
-	uint32 getEngineVersion() const;
+	uint32 getEngineVersion() const {
+		return _gameDescription->engineVersion;
+	}
 };
 
 extern GamosEngine *g_engine;


Commit: 0fa80280838c4ef5527050e5a8ce52ba440235a7
    https://github.com/scummvm/scummvm/commit/0fa80280838c4ef5527050e5a8ce52ba440235a7
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:04+01:00

Commit Message:
GAMOS: Rename GetScummCode->getScummCode and GetWinCode->getWinCode

Changed paths:
    engines/gamos/keycodes.h
    engines/gamos/proc.cpp


diff --git a/engines/gamos/keycodes.h b/engines/gamos/keycodes.h
index 8ceabdb27ed..bc11f4734e7 100644
--- a/engines/gamos/keycodes.h
+++ b/engines/gamos/keycodes.h
@@ -271,10 +271,10 @@ protected:
 	void setCPTable(const uint16 *table, uint16 size, uint16 offset = 0x80);
 
 public:
-	uint8 GetWinCode(uint16 code) {
+	uint8 getWinCode(uint16 code) const {
 		return _winCodes[code];
 	};
-	uint16 GetScummCode(uint8 code) {
+	uint16 getScummCode(uint8 code) const {
 		return _scummCodes[code];
 	};
 
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index 25280178f58..ebc158509eb 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -33,7 +33,7 @@ void SystemProc::processMessage(const Common::Event &ev) {
 
 		_ascii = ev.kbd.ascii;
 
-		winKey = _codesConverter->GetWinCode(ev.kbd.keycode);
+		winKey = _codesConverter->getWinCode(ev.kbd.keycode);
 
 		if (winKey == KeyCodes::WIN_BACK ||
 			winKey == KeyCodes::WIN_RETURN ||


Commit: ce4d262b97463e0ebb85dabb2b595c6103287881
    https://github.com/scummvm/scummvm/commit/ce4d262b97463e0ebb85dabb2b595c6103287881
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:05+01:00

Commit Message:
GAMOS: Update detection table

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 519bba04f4f..423001a35e4 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -28,7 +28,8 @@ const PlainGameDescriptor gamosGames[] = {
 	{ "pilots2", "Pilots 2" },
 	{ "wild", "WildSnakes"},
 	{ "flop", "Flip-Flop"},
-	{ "it", "IT"},
+	{ "netwalk", "NetWalk"},
+	{ "vitamin", "Vitamin"},
 	{ 0, 0 }
 };
 
@@ -37,7 +38,7 @@ const GamosGameDescription gameDescriptions[] = {
 		{
 			"solgamer",
 			0,
-			AD_ENTRY1s("solgamer.exe", "6049dd1645071da1b60cdd395e6999ba", 24658521),
+			AD_ENTRY1s("solgamer.exe", "t:4a06f82f7638e865e27d68d2e071e827", 24658521),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
@@ -46,11 +47,37 @@ const GamosGameDescription gameDescriptions[] = {
 		"solgamer.exe",
 		0x80000018
 	},
+	{
+		{
+			"solgamer",
+			0,
+			AD_ENTRY1s("solgamee.exe", "t:cad7d29da5aa843853fb8e7609a46300", 24624511),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"solgamee.exe",
+		0x80000018
+	},
+	{
+		{
+			"solgamer",
+			0,
+			AD_ENTRY1s("solgamee.exe", "t:a32bbae8c381d8cdc4cbac9e18acb0a8", 24676118),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"solgamee.exe",
+		0x80000018
+	},
 	{
 		{
 			"pilots",
 			0,
-			AD_ENTRY1s("pilots.exe", "152f751d3c1b325e91411dd75de54e95", 48357155),
+			AD_ENTRY1s("pilots.exe", "t:82ae05090898af66447bac4f06e910f3", 48357155),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
@@ -59,11 +86,63 @@ const GamosGameDescription gameDescriptions[] = {
 		"pilots.exe",
 		0x80000016
 	},
+	{
+		{
+			"pilots",
+			0,
+			AD_ENTRY1s("pilde_r.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"pilde_r.exe",
+		0x80000016
+	},
+	{
+		{
+			"pilots",
+			0,
+			AD_ENTRY1s("pilotsrd.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"pilotsrd.exe",
+		0x80000016
+	},
+	{
+		{
+			"pilots",
+			0,
+			AD_ENTRY1s("pilde_e.exe", "t:a784fc52f6923817d8ec8b9101e3f3ea", 10904737),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"pilde_e.exe",
+		0x80000016
+	},
+	{
+		{
+			"pilots",
+			0,
+			AD_ENTRY1s("pilotsed.exe", "t:190cb2dcf936d0c3a891ba333dbc2f33", 10946501),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"pilotsed.exe",
+		0x80000018
+	},
 	{
 		{
 			"pilots2",
 			0,
-			AD_ENTRY1s("pilots2.exe", "a0353dfb46043d1b2d1ef8ab6c204b33", 582283983),
+			AD_ENTRY1s("pilots2.exe", "t:c434bd8787febde52ccb5ef0e0731c7b", 582283983),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
@@ -76,7 +155,7 @@ const GamosGameDescription gameDescriptions[] = {
 		{
 			"wild",
 			0,
-			AD_ENTRY1s("wildus.exe", "6049dd1645071da1b60cdd395e6999ba", 11475754),
+			AD_ENTRY1s("wildus.exe", "t:320c8dfd26ae5935b71a37227b7fe67f", 11475754),
 			Common::EN_ANY,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
@@ -85,43 +164,316 @@ const GamosGameDescription gameDescriptions[] = {
 		"wildus.exe",
 		0x80000018
 	},
+	{
+		{
+			"wild",
+			0,
+			AD_ENTRY1s("wildus.exe", "t:a28e6f87a9c5cad5661108678522e27c", 11471282),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"wildus.exe",
+		0x80000016
+	},
+	{
+		{
+			"wild",
+			0,
+			AD_ENTRY1s("wildru.exe", "t:35bcdf2b9a0b022fe546de08ab685bd9", 11510210),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"wildru.exe",
+		0x80000016
+	},
+	{
+		{
+			"wild",
+			0,
+			AD_ENTRY1s("wildrudm.exe", "t:335fa22e185426843190460bc57d78a7", 11517820),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"wildrudm.exe",
+		0x80000016
+	},
+	{
+		{
+			"wild",
+			0,
+			AD_ENTRY1s("wildusdm.exe", "t:bddc7069986caedcfaa38ce35d42520b", 11516932),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"wildusdm.exe",
+		0x80000016
+	},
 	{
 		{
 			"flop",
 			0,
-			AD_ENTRY1s("FFLOPRD.EXE", "82d5b8a9d442bcec25c3401b4f7c0f9e", 4637680),
+			AD_ENTRY1s("ffloprd.exe", "t:a09793d184d211f819299a5286a75f56", 4637680),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"FFLOPRD.EXE",
+		"ffloprd.exe",
+		0x80000016
+	},
+	{
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("ffloped.exe", "t:2f90db8d9083b57c775375cf880dc777", 4609380),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"ffloped.exe",
 		0x80000016
 	},
 	{
 		{
 			"flop",
 			0,
-			AD_ENTRY1s("FFLOPE.EXE", "6049dd1645071da1b60cdd395e6999ba", 4633340),
+			AD_ENTRY1s("fflope.exe", "t:7e098e0b565d97eb3d55eb3b6d45e413", 4633340),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"fflope.exe",
+		0x80000018
+	},
+	{
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("ffloped.exe", "t:1be4097f6564e9240c58079addfd4600", 4613290),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"ffloped.exe",
+		0x80000018
+	},
+	{
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("fflope.exe", "t:8ffba2d788278457bb2f9661b7bdf4ec", 4629006),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"fflope.exe",
+		0x80000016
+	},
+	{
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("fflopr.exe", "t:7e452d6f5fbfe32dc1ee3c53fba27f88", 4629153),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"fflopr.exe",
+		0x80000016
+	},
+	{ // 1.13rus
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("fflop.exe", "t:fd32bc85b8686504f3e63c8e00444c68", 6662497),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"fflop.exe",
+		0x8000000b
+	},
+	{ // 1.13eng
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("fflop.exe", "t:3f7b90481959b408c9f7dface714cb75", 6691028),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"fflop.exe",
+		0x8000000b
+	},
+	{ // 1.29eng
+		{
+			"flop",
+			0,
+			AD_ENTRY1s("fflop.exe", "t:a1f917e41e24cbb9e2bda3cf2da5e8fb", 6860990),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"fflop.exe",
+		0x80000012
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("it.exe", "t:76c0cce851177ed28e0d78ab989c6b63", 4125894),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"it.exe",
+		0x80000016
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("it.exe", "t:455ad057b10542674c69f428311b6daf", 4744297),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"it.exe",
+		0x8000000b
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("netwalk.exe", "t:f7e100541adf71f1cec35ecc914c8ca3", 5607140),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"netwalk.exe",
+		0x8000000b
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("netwalk.exe", "t:3512b1127b93c2ffe074e292f19a0ffb", 4981212),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"netwalk.exe",
+		0x80000016
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("netwalk.exe", "t:f1b1713c122a4d60a773046f6aa1e1d8", 4972704),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"netwalk.exe",
+		0x80000016
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("netwalk.exe", "t:ee6ec7c4d1f451d30038665e2edcc278", 5624675),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"netwalk.exe",
+		0x80000012
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("netwalk.exe", "t:140a884942bbc396ae0640645d8118aa", 4979981),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"netwalk.exe",
+		0x80000018
+	},
+	{
+		{
+			"netwalk",
+			0,
+			AD_ENTRY1s("netwalk.exe", "t:4d78e86ef47ceb6c578081ba367ee8ea", 4984836),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"netwalk.exe",
+		0x80000018
+	},
+	{
+		{
+			"vitamin",
+			0,
+			AD_ENTRY1s("vitam_e.exe", "t:04cae8b641a7d79a1842c7ac1899b534", 429943),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE,
+			GUIO1(GUIO_NONE)
+		},
+		"vitam_e.exe",
+		0x80000016
+	},
+	{
+		{
+			"vitamin",
+			0,
+			AD_ENTRY1s("vitam_e.exe", "t:3506cd8e1a32ec3e841a2043d9dabc5b", 1122512),
 			Common::EN_ANY,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"FFLOPE.EXE",
+		"vitam_e.exe",
 		0x80000018
 	},
 	{
 		{
-			"it",
+			"vitamin",
 			0,
-			AD_ENTRY1s("IT.EXE", "82d5b8a9d442bcec25c3401b4f7c0f9e", 4125894),
+			AD_ENTRY1s("vitam_r.exe", "t:427c0269c7327c7ca4f434e22c5cfce9", 459546),
 			Common::RU_RUS,
 			Common::kPlatformWindows,
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"IT.EXE",
+		"vitam_r.exe",
 		0x80000016
 	},
 	{


Commit: f25233866ba87ce3d52a5c901decce643c39846f
    https://github.com/scummvm/scummvm/commit/f25233866ba87ce3d52a5c901decce643c39846f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:05+01:00

Commit Message:
GAMOS: Add support loading games with engine version 0x12 and 0x0b

Changed paths:
    engines/gamos/file.cpp
    engines/gamos/file.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/proc.cpp


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index 1210fbf90d9..66385686f90 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -37,7 +37,9 @@ bool Archive::open(const Common::Path &name) {
 
 	seek(-12, SEEK_END);
 
-	_dirOffset = 12 + readUint32LE();
+	const uint32 dirInfSize = readUint32LE();
+
+	_dirOffset = 12 + dirInfSize;
 	skip(4);
 	uint32 magic = readUint32LE();
 
@@ -46,8 +48,16 @@ bool Archive::open(const Common::Path &name) {
 
 	seek(-_dirOffset, SEEK_END);
 
-	_dirCount = readUint32LE();
-	_dataOffset = readUint32LE();
+	byte tmpbuf[8] = {0, 0 ,0, 0, 0, 0, 0, 0};
+
+	/* read it into buffer firs, because it's can be less than 8 bytes */
+	if (dirInfSize > 8)
+		read(tmpbuf, 8);
+	else
+		read(tmpbuf, dirInfSize);
+
+	_dirCount = READ_LE_UINT32(tmpbuf);
+	_dataOffset = READ_LE_UINT32(tmpbuf + 4);
 
 	seek(-(_dirOffset + _dirCount * 5), SEEK_END);
 
@@ -141,12 +151,17 @@ bool Archive::readCompressedData(RawData *out) {
 		/* read size */
 		const byte szsize = (t & 3) + 1;
 
+		if (_version == 0xb)
+			skip(szsize);
+
 		/* big data size */
 		for (uint i = 0; i < szsize; ++i)
 			_lastReadSize |= readByte() << (i << 3);
 
 		/* is compressed */
-		if (t & 0xC) {
+		if (_version == 0xb) {
+			skip(szsize + 1);
+		} else if (t & 0xC) {
 			for (uint i = 0; i < szsize; ++i)
 				_lastReadDecompressedSize |= readByte() << (i << 3);
 		}
@@ -159,7 +174,7 @@ bool Archive::readCompressedData(RawData *out) {
 	out->resize(_lastReadSize);
 	read(out->data(), _lastReadSize);
 
-	if (!_lastReadDecompressedSize)
+	if (!_lastReadDecompressedSize || _version != 0x18)
 		return true;
 
 	/* looks hacky but we just allocate array for decompressed and swap it with compressed */
diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index 1b2d2a9ed28..f03fedfc51c 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -61,6 +61,10 @@ public:
 
 	static void decompress(RawData const *in, RawData *out);
 
+	void setVersion(int v) {
+		_version = v;
+	}
+
 public:
 
 	uint32 _lastReadSize = 0;
@@ -76,6 +80,8 @@ private:
 
 	Common::Array<ArchiveDir> _directories;
 
+	int _version = 0x18;
+
 	//bool _error;
 };
 
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index af0d8f3b644..76d4e7ae53b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -86,6 +86,10 @@ Common::Error GamosEngine::run() {
 	else
 		setCP1252();
 
+	_engineVersion = getEngineVersion() & 0xFF;
+
+	_arch.setVersion(_engineVersion);
+
 	init(getRunFile());
 
 	Common::Event e;
@@ -564,30 +568,43 @@ bool GamosEngine::initMainDatas() {
 	}
 
 	/* skip count of pages 1kb size */
-	dataStream.skip(4);
-	/* skip read buffer size */
-	dataStream.skip(4);
-	_width = dataStream.readUint32LE();
-	_height = dataStream.readUint32LE();
-	_gridCellW = dataStream.readSint32LE();
-	_gridCellH = dataStream.readSint32LE();
-	_movieCount = dataStream.readUint32LE();
-	dataStream.skip(3); // skip unknown unused
-	_fps = dataStream.readByte();
-	dataStream.skip(1); // skip unknown unused
-	_drawCursor = dataStream.readByte();
-	_fadeEffectID = dataStream.readByte();
-	_playIntro = dataStream.readByte();
-
-	_introPos.x = dataStream.readSint32LE();
-	_introPos.y = dataStream.readSint32LE();
-	_introSize.x = dataStream.readSint32LE();
-	_introSize.y = dataStream.readSint32LE();
-
-	int64 pos = dataStream.pos();
-	_string1 = dataStream.readString(0, 64);
-	dataStream.seek(pos + 64);
-	_winCaption = dataStream.readString(0, 9);
+	dataStream.skip(4); // 4
+	if (_engineVersion >= 0x12) {
+		/* skip read buffer size */
+		dataStream.skip(4); // 8
+	}
+	_width = dataStream.readUint32LE(); // c
+	_height = dataStream.readUint32LE(); // 10
+	_gridCellW = dataStream.readSint32LE(); // 14
+	_gridCellH = dataStream.readSint32LE(); // 18
+	_movieCount = dataStream.readUint32LE(); // 1c
+	dataStream.skip(3); // skip unknown unused 20
+	_fps = dataStream.readByte(); // 23
+	dataStream.skip(1); // skip unknown unused  24
+	_drawCursor = dataStream.readByte(); // 25
+
+	if (_engineVersion >= 0x12) {
+		_fadeEffectID = dataStream.readByte(); // 26
+		_playIntro = dataStream.readByte(); // 27
+	} else {
+		_playIntro = dataStream.readByte();
+		_fadeEffectID = dataStream.readByte();
+	}
+
+	if (_engineVersion >= 0x12) {
+		_introPos.x = dataStream.readSint32LE(); // 28
+		_introPos.y = dataStream.readSint32LE(); // 2c
+		_introSize.x = dataStream.readSint32LE(); // 30
+		_introSize.y = dataStream.readSint32LE(); // 34
+
+		int64 pos = dataStream.pos();
+		_string1 = dataStream.readString(0, 64); // 38
+		dataStream.seek(pos + 64);
+	} else {
+		_string1 = "";
+	}
+
+	_winCaption = dataStream.readString(0, 32); // 78
 
 	if (!_screen) {
 		initGraphics(_width, _height);
@@ -1085,7 +1102,7 @@ void GamosEngine::readData2(const RawData &data) {
 
 	//warning("Game data size %d", data.size());
 
-	if (getEngineVersion() == 0x80000018) {
+	if (_engineVersion == 0x18) {
 		_stateExt = dataStream.readString(0, 4); // FIX ME
 		dataStream.seek(4);
 		_messageProc._inputFlags = dataStream.readByte(); //4
@@ -1121,7 +1138,7 @@ void GamosEngine::readData2(const RawData &data) {
 		for (int i = 0; i < 12; i++) {
 			_messageProc._keyCodes[i] = dataStream.readByte();
 		}
-	} else if (getEngineVersion() == 0x80000016) {
+	} else if (_engineVersion >= 0x12 && _engineVersion <= 0x16) {
 		_stateExt = dataStream.readString(0, 4); // FIX ME
 		dataStream.seek(4);
 		_messageProc._inputFlags = dataStream.readByte(); //4
@@ -1156,6 +1173,52 @@ void GamosEngine::readData2(const RawData &data) {
 		for (int i = 0; i < 12; i++) {
 			_messageProc._keyCodes[i] = dataStream.readByte();
 		}
+	} else if (_engineVersion == 0xb) {
+		_stateExt = dataStream.readString(0, 4); // FIX ME
+		dataStream.seek(4);
+		_messageProc._inputFlags = dataStream.readByte(); //4
+		dataStream.seek(8);
+		_svModuleId = dataStream.readSint32LE(); // 8
+		_svGameScreen = dataStream.readSint32LE(); // c
+		_d2_fld10 = dataStream.readUint32LE(); // 10
+		_enableSounds = dataStream.readByte() != 0 ? true : false; // x14
+		_enableMidi = dataStream.readByte() != 0 ? true : false; //x15
+		_enableInput = dataStream.readByte() != 0 ? true : false; // x16
+		_enableMovie = dataStream.readByte() != 0 ? true : false; // x17
+		_enableCDAudio = false;
+		_cdAudioTrack = -1;
+		_scrollX = 0;
+		_scrollY = 0;
+		_scrollTrackObj = -1;
+		_scrollSpeed = 16;
+		_scrollCutoff = 80;
+		_scrollSpeedReduce = -1;
+		_scrollBorderL = 0;
+		_scrollBorderR = 0;
+		_scrollBorderU = 0;
+		_scrollBorderB = 0;
+		_sndChannels = dataStream.readByte(); // x18
+		_sndVolume = dataStream.readByte(); // x19
+		_midiVolume = dataStream.readByte(); // x1a
+		_svFps = dataStream.readByte(); // x1b
+		_svFrame = dataStream.readSint32LE(); // x1c
+		_midiTrack = dataStream.readUint32LE(); // x20
+		_mouseCursorImgId = dataStream.readSint32LE(); // x24
+		//0x28
+
+		_messageProc._keyCodes[0] = KeyCodes::WIN_UP;
+		_messageProc._keyCodes[1] = KeyCodes::WIN_PRIOR;
+		_messageProc._keyCodes[2] = KeyCodes::WIN_RIGHT;
+		_messageProc._keyCodes[3] = KeyCodes::WIN_NEXT;
+		_messageProc._keyCodes[4] = KeyCodes::WIN_DOWN;
+		_messageProc._keyCodes[5] = KeyCodes::WIN_END;
+		_messageProc._keyCodes[6] = KeyCodes::WIN_LEFT;
+		_messageProc._keyCodes[7] = KeyCodes::WIN_HOME;
+		_messageProc._keyCodes[8] = KeyCodes::WIN_SPACE;
+		_messageProc._keyCodes[9] = KeyCodes::WIN_RETURN;
+		_messageProc._keyCodes[10] = KeyCodes::WIN_TAB;
+		_messageProc._keyCodes[11] = KeyCodes::WIN_INVALID;
+		_messageProc._keyCodes[12] = KeyCodes::WIN_INVALID;
 	}
 }
 
@@ -2292,6 +2355,9 @@ uint32 GamosEngine::doScript(uint32 scriptAddress) {
 void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 	uint32 arg1 = 0, arg2 = 0;
 
+	if (_engineVersion <= 0x12 && funcID >= 47) // skip 47 func for old versions
+		funcID++;
+
 	switch (funcID) {
 	case 0:
 		_restartUpdateObject = true;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index caadf3dbb9c..4a459de0e4c 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -594,6 +594,8 @@ private:
 
 	bool _needReload = false;
 
+	uint32 _engineVersion = 0x18;
+
 protected:
 	// Engine APIs
 	Common::Error run() override;
diff --git a/engines/gamos/proc.cpp b/engines/gamos/proc.cpp
index ebc158509eb..e920a17d445 100644
--- a/engines/gamos/proc.cpp
+++ b/engines/gamos/proc.cpp
@@ -45,36 +45,38 @@ void SystemProc::processMessage(const Common::Event &ev) {
 		if (_rawKeyCode == 0)
 			_rawKeyCode = ACT_NONE;
 
-		if (winKey == _keyCodes[0])
-			_act1 = 0;
-		else if (winKey == _keyCodes[1])
-			_act1 = 1;
-		else if (winKey == _keyCodes[2])
-			_act1 = 2;
-		else if (winKey == _keyCodes[3])
-			_act1 = 3;
-		else if (winKey == _keyCodes[4])
-			_act1 = 4;
-		else if (winKey == _keyCodes[5])
-			_act1 = 5;
-		else if (winKey == _keyCodes[6])
-			_act1 = 6;
-		else if (winKey == _keyCodes[7])
-			_act1 = 7;
-		else {
-			if (winKey == _keyCodes[8])
-				_act2 = ACT2_MOUSEUP_L;
-			else if (winKey == _keyCodes[9])
-				_act2 = ACT2_MOUSEUP_R;
-			else if (winKey == _keyCodes[10])
-				_act2 = ACT2_TAB;
-			else if (winKey == _keyCodes[11])
-				_act2 = ACT2_HELP;
-			else
+		if (winKey != KeyCodes::WIN_INVALID) {
+			if (winKey == _keyCodes[0])
+				_act1 = 0;
+			else if (winKey == _keyCodes[1])
+				_act1 = 1;
+			else if (winKey == _keyCodes[2])
+				_act1 = 2;
+			else if (winKey == _keyCodes[3])
+				_act1 = 3;
+			else if (winKey == _keyCodes[4])
+				_act1 = 4;
+			else if (winKey == _keyCodes[5])
+				_act1 = 5;
+			else if (winKey == _keyCodes[6])
+				_act1 = 6;
+			else if (winKey == _keyCodes[7])
+				_act1 = 7;
+			else {
+				if (winKey == _keyCodes[8])
+					_act2 = ACT2_MOUSEUP_L;
+				else if (winKey == _keyCodes[9])
+					_act2 = ACT2_MOUSEUP_R;
+				else if (winKey == _keyCodes[10])
+					_act2 = ACT2_TAB;
+				else if (winKey == _keyCodes[11])
+					_act2 = ACT2_HELP;
+				else
+					return;
+
+				_rawKeyCode = winKey;
 				return;
-
-			_rawKeyCode = winKey;
-			return;
+			}
 		}
 
 		if ((_act1 < 8) && (ev.kbd.flags & Common::KBD_SHIFT))


Commit: acf0a735118572873e17a18efb7b1a768fdfd1ca
    https://github.com/scummvm/scummvm/commit/acf0a735118572873e17a18efb7b1a768fdfd1ca
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:05+01:00

Commit Message:
GAMOS: Update detection table for 1C demo disc

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 423001a35e4..936e4fbf17f 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -99,6 +99,19 @@ const GamosGameDescription gameDescriptions[] = {
 		"pilde_r.exe",
 		0x80000016
 	},
+	{
+		{
+			"pilots",
+			0,
+			AD_ENTRY1s("pildemo.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
+			Common::RU_RUS,
+			Common::kPlatformWindows,
+			ADGF_UNSTABLE | ADGF_DEMO,
+			GUIO1(GUIO_NONE)
+		},
+		"pildemo.exe",
+		0x80000016
+	},
 	{
 		{
 			"pilots",


Commit: 6b9a0d84defb06c7a4e9f04c44dd32a94c0a0991
    https://github.com/scummvm/scummvm/commit/6b9a0d84defb06c7a4e9f04c44dd32a94c0a0991
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:06+01:00

Commit Message:
GAMOS: Fix loading of engine version 16

Changed paths:
    engines/gamos/file.cpp


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index 66385686f90..e76aa566ce8 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -174,7 +174,7 @@ bool Archive::readCompressedData(RawData *out) {
 	out->resize(_lastReadSize);
 	read(out->data(), _lastReadSize);
 
-	if (!_lastReadDecompressedSize || _version != 0x18)
+	if (!_lastReadDecompressedSize || _version < 0x16)
 		return true;
 
 	/* looks hacky but we just allocate array for decompressed and swap it with compressed */


Commit: ca45b3637dbed211ec5a60768fb262b5ef74b3d1
    https://github.com/scummvm/scummvm/commit/ca45b3637dbed211ec5a60768fb262b5ef74b3d1
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:06+01:00

Commit Message:
GAMOS: Specify size for size type in array2d template

Changed paths:
    engines/gamos/array2d.h


diff --git a/engines/gamos/array2d.h b/engines/gamos/array2d.h
index 5635cab4be2..2438923f383 100644
--- a/engines/gamos/array2d.h
+++ b/engines/gamos/array2d.h
@@ -31,7 +31,7 @@ class Array2D : protected Common::Array<T> {
 private:
 	typedef Common::Array<T> __base;
 public:
-	typedef uint size_type; /*!< Size type of the array. */
+	typedef uint16 size_type; /*!< Size type of the array. */
 
 	using Common::Array<T>::data;
 	using Common::Array<T>::operator[];


Commit: 9b34c8aa802fab15bebdc14c2686262754d1d7fe
    https://github.com/scummvm/scummvm/commit/9b34c8aa802fab15bebdc14c2686262754d1d7fe
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:07+01:00

Commit Message:
GAMOS: Delete potfile because it's not needed

Changed paths:
  R engines/gamos/POTFILES


diff --git a/engines/gamos/POTFILES b/engines/gamos/POTFILES
deleted file mode 100644
index 1e1c41c86c4..00000000000
--- a/engines/gamos/POTFILES
+++ /dev/null
@@ -1 +0,0 @@
-engines/gamos/metaengine.cpp


Commit: 82a8c82f7832a7a3a71053213e836a272f0770d5
    https://github.com/scummvm/scummvm/commit/82a8c82f7832a7a3a71053213e836a272f0770d5
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:07+01:00

Commit Message:
GAMOS: Replace commented code with tip

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 76d4e7ae53b..83ae8098d01 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1926,16 +1926,9 @@ Object *GamosEngine::getFreeObject() {
 
 void GamosEngine::removeObject(Object *obj) {
 	obj->flags = 0;
-	/*if (&(_objects.back()) == obj) {
-	    int32 lastindex = _objects.size() - 1;
-	    for (int32 i = lastindex - 1; i >= 0; i--) {
-	        if ( _objects[i].flags & 1 ) {
-	            lastindex = i;
-	            break;
-	        }
-	    }
-	    _objects.resize(lastindex);
-	}*/
+	/*
+		In original engine here is free for continoues unused objects in the end
+	*/
 }
 
 void GamosEngine::removeObjectMarkDirty(Object *obj) {


Commit: bee7e09e8ed15c90def363830351b205f8223a60
    https://github.com/scummvm/scummvm/commit/bee7e09e8ed15c90def363830351b205f8223a60
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:07+01:00

Commit Message:
GAMOS: Replace iteration counter with uint

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 83ae8098d01..8f4479212a1 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -3284,7 +3284,7 @@ void GamosEngine::processInput(Common::Point move, Common::Point actPos, uint8 a
 	uint8 actT = 0;
 	uint8 pobjF5 = 255;
 
-	for (int i = 0; i < _objects.size(); i++) {
+	for (uint i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if (obj.isActionObject()) {
 			ObjectAction &action = _objectActions[obj.actID];


Commit: b9f0f825448358e1cc3305fb773d02b91d2c57fb
    https://github.com/scummvm/scummvm/commit/b9f0f825448358e1cc3305fb773d02b91d2c57fb
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:08+01:00

Commit Message:
GAMOS: Poll events on scroll routine

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 8f4479212a1..6c217457549 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -4110,6 +4110,7 @@ bool GamosEngine::scrollAndDraw() {
 				_scrollX += rDelta - lDelta;
 				_scrollY += dDelta - uDelta;
 
+				eventsSkip();
 				doDraw();
 
 				lDistance -= lDelta;


Commit: 0c77ee736e142c84be6eaa369c11cf9e00adaeb2
    https://github.com/scummvm/scummvm/commit/0c77ee736e142c84be6eaa369c11cf9e00adaeb2
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:08+01:00

Commit Message:
GAMOS: Fix bracket style

Changed paths:
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 4a459de0e4c..1295bf497d8 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -145,8 +145,7 @@ struct Sprite {
 	uint32 index = 0;
 
 	byte field_0;
-	union
-	{
+	union {
 		byte flags;
 		byte startChar; // if it's font
 	};


Commit: 686a47927c90a940f902dd95def17b6e718179a3
    https://github.com/scummvm/scummvm/commit/686a47927c90a940f902dd95def17b6e718179a3
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:08+01:00

Commit Message:
GAMOS: Sort objects in module.mk

Changed paths:
    engines/gamos/module.mk


diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
index a02d527d4f9..1225afceaf0 100644
--- a/engines/gamos/module.mk
+++ b/engines/gamos/module.mk
@@ -2,17 +2,17 @@ MODULE := engines/gamos
 
 MODULE_OBJS = \
 	blit.o \
-	gamos.o \
-	file.o \
 	console.o \
-	metaengine.o \
+	file.o \
+	gamos.o \
 	keycodes.o \
+	metaengine.o \
+	movie.o \
 	music.o \
 	proc.o \
-	movie.o \
 	saveload.o \
-	vm.o \
-	video.o
+	video.o \
+	vm.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_GAMOS), DYNAMIC_PLUGIN)


Commit: 36118e94066a8221d39addee8ea6d2abcc2e530b
    https://github.com/scummvm/scummvm/commit/36118e94066a8221d39addee8ea6d2abcc2e530b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:09+01:00

Commit Message:
GAMOS: Fill credits.pl

Changed paths:
    engines/gamos/credits.pl


diff --git a/engines/gamos/credits.pl b/engines/gamos/credits.pl
index 8400341ef9b..0e49bf5f3c3 100644
--- a/engines/gamos/credits.pl
+++ b/engines/gamos/credits.pl
@@ -1,3 +1,3 @@
 begin_section("Gamos");
-	add_person("Name 1", "Handle 1", "");
+	add_person("Anton Yarcev", "Zidane", "");
 end_section();


Commit: 64e9752d9a9d1ee075110fc16a46d01dcf331400
    https://github.com/scummvm/scummvm/commit/64e9752d9a9d1ee075110fc16a46d01dcf331400
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:09+01:00

Commit Message:
GAMOS: Add comments with game engine copyright, year and if preserved file date

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 936e4fbf17f..cc6d0af57c2 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -35,7 +35,8 @@ const PlainGameDescriptor gamosGames[] = {
 
 const GamosGameDescription gameDescriptions[] = {
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			24.03.1998 */
 			"solgamer",
 			0,
 			AD_ENTRY1s("solgamer.exe", "t:4a06f82f7638e865e27d68d2e071e827", 24658521),
@@ -48,7 +49,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"solgamer",
 			0,
 			AD_ENTRY1s("solgamee.exe", "t:cad7d29da5aa843853fb8e7609a46300", 24624511),
@@ -61,7 +63,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			24.03.1998 */
 			"solgamer",
 			0,
 			AD_ENTRY1s("solgamee.exe", "t:a32bbae8c381d8cdc4cbac9e18acb0a8", 24676118),
@@ -74,7 +77,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			30.08.1997 */
 			"pilots",
 			0,
 			AD_ENTRY1s("pilots.exe", "t:82ae05090898af66447bac4f06e910f3", 48357155),
@@ -87,7 +91,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			04.09.1995 ??? */
 			"pilots",
 			0,
 			AD_ENTRY1s("pilde_r.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
@@ -100,7 +105,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			04.09.1995 ??? */
 			"pilots",
 			0,
 			AD_ENTRY1s("pildemo.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
@@ -113,7 +119,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			04.09.1995 ??? */
 			"pilots",
 			0,
 			AD_ENTRY1s("pilotsrd.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
@@ -126,7 +133,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			20.09.1995 ??? */
 			"pilots",
 			0,
 			AD_ENTRY1s("pilde_e.exe", "t:a784fc52f6923817d8ec8b9101e3f3ea", 10904737),
@@ -139,7 +147,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.50] by Vadim Sytnikov
+			17.12.1997 */
 			"pilots",
 			0,
 			AD_ENTRY1s("pilotsed.exe", "t:190cb2dcf936d0c3a891ba333dbc2f33", 10946501),
@@ -152,7 +161,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.54] by Vadim Sytnikov
+			14.10.1998 */
 			"pilots2",
 			0,
 			AD_ENTRY1s("pilots2.exe", "t:c434bd8787febde52ccb5ef0e0731c7b", 582283983),
@@ -165,7 +175,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"wild",
 			0,
 			AD_ENTRY1s("wildus.exe", "t:320c8dfd26ae5935b71a37227b7fe67f", 11475754),
@@ -178,7 +189,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"wild",
 			0,
 			AD_ENTRY1s("wildus.exe", "t:a28e6f87a9c5cad5661108678522e27c", 11471282),
@@ -191,7 +203,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"wild",
 			0,
 			AD_ENTRY1s("wildru.exe", "t:35bcdf2b9a0b022fe546de08ab685bd9", 11510210),
@@ -204,7 +217,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.42] by Vadim Sytnikov
+			31.07.1997 */
 			"wild",
 			0,
 			AD_ENTRY1s("wildrudm.exe", "t:335fa22e185426843190460bc57d78a7", 11517820),
@@ -217,7 +231,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"wild",
 			0,
 			AD_ENTRY1s("wildusdm.exe", "t:bddc7069986caedcfaa38ce35d42520b", 11516932),
@@ -230,7 +245,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"flop",
 			0,
 			AD_ENTRY1s("ffloprd.exe", "t:a09793d184d211f819299a5286a75f56", 4637680),
@@ -243,7 +259,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"flop",
 			0,
 			AD_ENTRY1s("ffloped.exe", "t:2f90db8d9083b57c775375cf880dc777", 4609380),
@@ -256,7 +273,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"flop",
 			0,
 			AD_ENTRY1s("fflope.exe", "t:7e098e0b565d97eb3d55eb3b6d45e413", 4633340),
@@ -269,7 +287,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"flop",
 			0,
 			AD_ENTRY1s("ffloped.exe", "t:1be4097f6564e9240c58079addfd4600", 4613290),
@@ -282,7 +301,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.42] by Vadim Sytnikov
+			31.07.1997 */
 			"flop",
 			0,
 			AD_ENTRY1s("fflope.exe", "t:8ffba2d788278457bb2f9661b7bdf4ec", 4629006),
@@ -295,7 +315,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"flop",
 			0,
 			AD_ENTRY1s("fflopr.exe", "t:7e452d6f5fbfe32dc1ee3c53fba27f88", 4629153),
@@ -308,7 +329,7 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{ // 1.13rus
-		{
+		{ /* Copyright (C) 1996 by Gamos JSC, Moscow, Russia...  Run-time engine [1.13] by Vadim Sytnikov */
 			"flop",
 			0,
 			AD_ENTRY1s("fflop.exe", "t:fd32bc85b8686504f3e63c8e00444c68", 6662497),
@@ -321,7 +342,7 @@ const GamosGameDescription gameDescriptions[] = {
 		0x8000000b
 	},
 	{ // 1.13eng
-		{
+		{ /* Copyright (C) 1996 by Gamos JSC, Moscow, Russia...  Run-time engine [1.13] by Vadim Sytnikov */
 			"flop",
 			0,
 			AD_ENTRY1s("fflop.exe", "t:3f7b90481959b408c9f7dface714cb75", 6691028),
@@ -334,7 +355,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x8000000b
 	},
 	{ // 1.29eng
-		{
+		{ /* Copyright (C) 1996 by Gamos JSC, Moscow, Russia...  Run-time engine [1.29] by Vadim Sytnikov
+			04.01.1997 */
 			"flop",
 			0,
 			AD_ENTRY1s("fflop.exe", "t:a1f917e41e24cbb9e2bda3cf2da5e8fb", 6860990),
@@ -347,7 +369,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000012
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"netwalk",
 			0,
 			AD_ENTRY1s("it.exe", "t:76c0cce851177ed28e0d78ab989c6b63", 4125894),
@@ -360,7 +383,7 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1996 by Gamos JSC, Moscow, Russia...  Run-time engine [1.13] by Vadim Sytnikov */
 			"netwalk",
 			0,
 			AD_ENTRY1s("it.exe", "t:455ad057b10542674c69f428311b6daf", 4744297),
@@ -373,7 +396,7 @@ const GamosGameDescription gameDescriptions[] = {
 		0x8000000b
 	},
 	{
-		{
+		{ /* Copyright (C) 1996 by Gamos JSC, Moscow, Russia...  Run-time engine [1.13] by Vadim Sytnikov */
 			"netwalk",
 			0,
 			AD_ENTRY1s("netwalk.exe", "t:f7e100541adf71f1cec35ecc914c8ca3", 5607140),
@@ -386,7 +409,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x8000000b
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"netwalk",
 			0,
 			AD_ENTRY1s("netwalk.exe", "t:3512b1127b93c2ffe074e292f19a0ffb", 4981212),
@@ -399,7 +423,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.43] by Vadim Sytnikov
+			06.08.1997 */
 			"netwalk",
 			0,
 			AD_ENTRY1s("netwalk.exe", "t:f1b1713c122a4d60a773046f6aa1e1d8", 4972704),
@@ -412,7 +437,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1996 by Gamos JSC, Moscow, Russia...  Run-time engine [1.27] by Vadim Sytnikov
+			15.12.1996 */
 			"netwalk",
 			0,
 			AD_ENTRY1s("netwalk.exe", "t:ee6ec7c4d1f451d30038665e2edcc278", 5624675),
@@ -425,7 +451,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000012
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"netwalk",
 			0,
 			AD_ENTRY1s("netwalk.exe", "t:140a884942bbc396ae0640645d8118aa", 4979981),
@@ -438,7 +465,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"netwalk",
 			0,
 			AD_ENTRY1s("netwalk.exe", "t:4d78e86ef47ceb6c578081ba367ee8ea", 4984836),
@@ -451,7 +479,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			04.09.1995 ??? */
 			"vitamin",
 			0,
 			AD_ENTRY1s("vitam_e.exe", "t:04cae8b641a7d79a1842c7ac1899b534", 429943),
@@ -464,7 +493,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000016
 	},
 	{
-		{
+		{ /* Copyright (C) 1998 by Gamos JSC, Moscow, Russia...  Run-time engine [1.51] by Vadim Sytnikov
+			03.12.1998 */
 			"vitamin",
 			0,
 			AD_ENTRY1s("vitam_e.exe", "t:3506cd8e1a32ec3e841a2043d9dabc5b", 1122512),
@@ -477,7 +507,8 @@ const GamosGameDescription gameDescriptions[] = {
 		0x80000018
 	},
 	{
-		{
+		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
+			04.09.1995 ??? */
 			"vitamin",
 			0,
 			AD_ENTRY1s("vitam_r.exe", "t:427c0269c7327c7ca4f434e22c5cfce9", 459546),


Commit: 24b751dbae919c698dc4095e8ce7cb2cef09bf84
    https://github.com/scummvm/scummvm/commit/24b751dbae919c698dc4095e8ce7cb2cef09bf84
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:09+01:00

Commit Message:
GAMOS: Set copyright dates

Changed paths:
    engines/gamos/detection.cpp


diff --git a/engines/gamos/detection.cpp b/engines/gamos/detection.cpp
index fbba85cc5db..40a5d8b7a09 100644
--- a/engines/gamos/detection.cpp
+++ b/engines/gamos/detection.cpp
@@ -46,7 +46,7 @@ public:
 	}
 
 	const char *getOriginalCopyright() const override {
-		return "Gamos (C)";
+		return "Gamos (C) 1996-1998";
 	}
 
 };


Commit: 92515190b70a13ee173fd18db0279edb3c9f6a6f
    https://github.com/scummvm/scummvm/commit/92515190b70a13ee173fd18db0279edb3c9f6a6f
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:10+01:00

Commit Message:
GAMOS: Fix "error C4701: potentially uninitialized local variable"

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 6c217457549..084328ee2a3 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -1445,7 +1445,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 
 	_gfxObjectCreated = false;
 	if (a.flags & Actions::HAS_FUNCTION) {
-		uint32 fldsv;
+		uint32 fldsv = 0;
 		if (_curObject)
 			fldsv = _curObject->priority;
 		if (a.functionAddress != -1)


Commit: a10d43885ae5470d3fd6578e5136a187a36a83be
    https://github.com/scummvm/scummvm/commit/a10d43885ae5470d3fd6578e5136a187a36a83be
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:10+01:00

Commit Message:
GAMOS: Fixes for "warning C4018: signed/unsigned mismatch"

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/movie.cpp
    engines/gamos/saveload.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 084328ee2a3..563723725ed 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -247,10 +247,10 @@ bool GamosEngine::loadModule(uint id) {
 	byte prevByte = 0;
 	bool doLoad = true;
 
-	int32 p1 = 0;
-	int32 p2 = 0;
-	int32 p3 = 0;
-	int32 pid = 0;
+	uint32 p1 = 0;
+	uint32 p2 = 0;
+	uint32 p3 = 0;
+	uint32 pid = 0;
 
 	while (doLoad) {
 		byte curByte = _arch.readByte();
@@ -269,13 +269,13 @@ bool GamosEngine::loadModule(uint id) {
 
 			break;
 		case CONFTP_P1:
-			p1 = _arch.readPackedInt();
+			p1 = (uint32)_arch.readPackedInt();
 			break;
 		case CONFTP_P2:
-			p2 = _arch.readPackedInt();
+			p2 = (uint32)_arch.readPackedInt();
 			break;
 		case CONFTP_P3:
-			p3 = _arch.readPackedInt();
+			p3 = (uint32)_arch.readPackedInt();
 			break;
 		case 4: {
 			_resReadOffset = _arch.pos();
@@ -385,7 +385,7 @@ bool GamosEngine::loadModule(uint id) {
 			prevByte = curByte & CONFTP_RESMASK;
 
 			if ((curByte & CONFTP_IDFLG) == 0)
-				pid = _arch.readPackedInt();
+				pid = (uint32)_arch.readPackedInt();
 
 			break;
 		}
@@ -435,7 +435,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 		loadBackground(pid, data, dataSize);
 	} else if (tp == RESTP_INITACT) {
 		if (!_isSaveLoadingProcess) {
-			for (int i = 0; i < _states.size(); i++)
+			for (uint i = 0; i < _states.size(); i++)
 				_states.at(i) = ObjState(0xfe, 0, 0xf);
 
 			_ignoreSoundActions = true;
@@ -689,8 +689,8 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	uint32 dat6xCount = dataStream.readUint32LE(); // 30
 
 	_statesShift = 2;
-	for (int i = 2; i < 9; i++) {
-		if (_statesWidth <= (1 << i)) {
+	for (uint i = 2; i < 9; i++) {
+		if (_statesWidth <= (uint32)(1 << i)) {
 			_statesShift = i;
 			break;
 		}
@@ -1374,7 +1374,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 
 			int32 ps = spos * 2 + 1;
 
-			for (int i = 0; i < ate.entries.size(); i++) {
+			for (uint i = 0; i < ate.entries.size(); i++) {
 				/* use copy of entrie because it will be modified */
 				ActEntry e = ate.entries[i];
 
@@ -1477,7 +1477,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 
 			case 1: {
 				int32 num = rndRange16(ate.entries.size());
-				for (int i = 0; i < ate.entries.size(); i++) {
+				for (uint i = 0; i < ate.entries.size(); i++) {
 					if (num != 0) {
 						ActEntry e = ate.entries[i];
 						retval += processData(e, absolute);
@@ -1500,7 +1500,7 @@ int32 GamosEngine::doActions(const Actions &a, bool absolute) {
 			break;
 
 			case 3: {
-				for (int i = 0; i < ate.entries.size(); i++) {
+				for (uint i = 0; i < ate.entries.size(); i++) {
 					uint16 doproc = rndRange16(2);
 
 					if (doproc != 0) {
@@ -1976,7 +1976,7 @@ bool GamosEngine::updateObjects() {
 	if (!pobj)
 		pobj = &(_objects.front());
 
-	for (int32 objIdx = pobj->index; objIdx < _objects.size(); objIdx++) {
+	for (uint32 objIdx = pobj->index; objIdx < _objects.size(); objIdx++) {
 		pobj = &_objects[objIdx];
 
 		if (pobj->isActionObject()) {
@@ -2180,7 +2180,7 @@ void GamosEngine::addDirtyRect(const Common::Rect &rect) {
 	}
 
 	bool intersects = 0;
-	for (int i = 0; i < _dirtyRects.size(); i++) {
+	for (uint i = 0; i < _dirtyRects.size(); i++) {
 		Common::Rect &r = _dirtyRects[i];
 
 		if (!rect.intersects(r))
@@ -2223,7 +2223,7 @@ void GamosEngine::doDraw() {
 	Common::Array<Object *> drawList(1024);  //_drawElements.size(), 1024) );
 
 	int cnt = 0;
-	for (int i = 0; i < _objects.size(); i++) {
+	for (uint i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if ( obj.isGraphicObject() ) {
 			drawList[cnt] = &obj;
@@ -2234,8 +2234,8 @@ void GamosEngine::doDraw() {
 	drawList.resize(cnt);
 
 	if (cnt) {
-		for (int i = 0; i < drawList.size() - 1; i++) {
-			for (int j = i + 1; j < drawList.size(); j++) {
+		for (uint i = 0; i < drawList.size() - 1; i++) {
+			for (uint j = i + 1; j < drawList.size(); j++) {
 				Object *o1 = drawList[i];
 				Object *o2 = drawList[j];
 				if (o1->priority < o2->priority) {
@@ -2246,7 +2246,7 @@ void GamosEngine::doDraw() {
 		}
 	}
 
-	for (int i = 0; i < _dirtyRects.size(); i++) {
+	for (uint i = 0; i < _dirtyRects.size(); i++) {
 		Common::Rect r = _dirtyRects[i];
 
 		r.translate(-_scrollX, -_scrollY);
@@ -2365,7 +2365,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		if (_curObject->tgtObjectId == -1)
 			ctx->EAX.setVal(0);
 		else
-			ctx->EAX.setVal( _objects[ _curObject->tgtObjectId ].sprId == arg1 ? 1 : 0 );
+			ctx->EAX.setVal( _objects[ _curObject->tgtObjectId ].sprId == (int32)arg1 ? 1 : 0 );
 		break;
 	case 3:
 		ctx->EAX.setVal( (_curObject->inputFlag & 0x90) == 0x10 ? 1 : 0 );
@@ -2375,15 +2375,15 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		break;
 	case 5:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (_curObject->inputFlag & 0xb0) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (uint32)(_curObject->inputFlag & 0xb0) == arg1 ? 1 : 0 );
 		break;
 	case 6:
 		arg1 = ctx->pop32();
-		ctx->EAX.setVal( (_curObject->inputFlag & 0x4f) == arg1 ? 1 : 0 );
+		ctx->EAX.setVal( (uint32)(_curObject->inputFlag & 0x4f) == arg1 ? 1 : 0 );
 		break;
 	case 7:
 		arg1 = ctx->pop32();
-		if ((_curObject->inputFlag & 0x40) == 0 || (_curObject->inputFlag & 8) != (arg1 & 8))
+		if ((_curObject->inputFlag & 0x40) == 0 || (uint32)(_curObject->inputFlag & 8) != (uint32)(arg1 & 8))
 			ctx->EAX.setVal(0);
 		else
 			ctx->EAX.setVal( FUN_0040705c(arg1 & 7, _curObject->inputFlag & 7) ? 1 : 0 );
@@ -2819,7 +2819,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 		VM::ValAddr a1 = ctx->popReg();
 		VM::ValAddr a2 = ctx->popReg();
 		Common::String s = ctx->getString(a1);
-		for(int i = 0; i <= s.size(); i++) {
+		for(uint i = 0; i <= s.size(); i++) {
 			ctx->setMem8(a2.getMemType(), a2.getOffset() + i, s.c_str()[i]);
 		}
 	} break;
@@ -3209,7 +3209,7 @@ void GamosEngine::removeSubtitles(Object *obj) {
 	if (obj->state.flags & 2) {
 		obj->state.flags &= ~2;
 		//for (int index = obj->index; index < _objects.size(); index++) {
-		for (int index = 0; index < _objects.size(); index++) {
+		for (uint index = 0; index < _objects.size(); index++) {
 			Object *pobj = &_objects[index];
 			if (pobj->isOverlayObject() && pobj->actObjIndex == obj->index)
 				removeObjectMarkDirty(pobj);
@@ -3226,7 +3226,7 @@ void GamosEngine::cycleNextInputObj(Object *obj) {
 		if (obj)
 			objIndex = obj->index;
 
-		for (int32 i = 0; i < _objects.size(); i++) {
+		for (uint32 i = 0; i < _objects.size(); i++) {
 			Object &robj = _objects[i];
 
 			if (robj.index > objIndex)
@@ -3432,7 +3432,7 @@ void GamosEngine::addSubtitles(VM::Context *ctx, byte memtype, int32 offset, int
 						break;
 					}
 
-					for (int i = 0; i < tmp.size(); i++) {
+					for (uint i = 0; i < tmp.size(); i++) {
 						addSubtitleImage((uint8)tmp[i], sprId, &x, y);
 					}
 				}
@@ -3539,8 +3539,8 @@ byte GamosEngine::FUN_00408648(uint8 p1, uint8 p2, uint8 p3) {
 }
 
 byte GamosEngine::FUN_004084bc(uint8 p) {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			const uint8 id = _states.at(i, j).actid;
 			if (id == p)
 				_pathMap.at(i, j) = PATH_TARGET;
@@ -3552,8 +3552,8 @@ byte GamosEngine::FUN_004084bc(uint8 p) {
 }
 
 byte GamosEngine::FUN_00408510(uint8 p) {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if (id == 0xfe)
@@ -3568,8 +3568,8 @@ byte GamosEngine::FUN_00408510(uint8 p) {
 }
 
 byte GamosEngine::FUN_0040856c() {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			uint8 id = _states.at(i, j).actid;
 
 			if (id == 0xfe)
@@ -3583,8 +3583,8 @@ byte GamosEngine::FUN_0040856c() {
 }
 
 byte GamosEngine::FUN_004085d8(uint8 p) {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			uint8 id = _states.at(i, j).actid;
 
 			if (id == p)
@@ -3709,11 +3709,11 @@ byte GamosEngine::pathFindTraceMove(uint8 p) {
 		if (ydist < xdist) {
 			if (x >= 1 && _pathMap.at(x - 1, y) == p) {
 				xx = x - 1;
-			} else if (x <= _pathRight - 1 && _pathMap.at(x + 1, y) == p) {
+			} else if (x <= (int32)(_pathRight - 1) && _pathMap.at(x + 1, y) == p) {
 				xx = x + 1;
 			} else if (y >= 1 && _pathMap.at(x, y - 1) == p) {
 				yy = y - 1;
-			} else if (y <= _pathBottom - 1 && _pathMap.at(x, y + 1) == p) {
+			} else if (y <= (int32)(_pathBottom - 1) && _pathMap.at(x, y + 1) == p) {
 				yy = y + 1;
 			} else {
 				return ydist;
@@ -3721,11 +3721,11 @@ byte GamosEngine::pathFindTraceMove(uint8 p) {
 		} else {
 			if (y >= 1 && _pathMap.at(x, y - 1) == p) {
 				yy = y - 1;
-			} else if (y <= _pathBottom - 1 && _pathMap.at(x, y + 1) == p) {
+			} else if (y <= (int32)(_pathBottom - 1) && _pathMap.at(x, y + 1) == p) {
 				yy = y + 1;
 			} else if (x >= 1 && _pathMap.at(x - 1, y) == p) {
 				xx = x - 1;
-			} else if (x <= _pathRight - 1 && _pathMap.at(x + 1, y) == p) {
+			} else if (x <= (int32)(_pathRight - 1) && _pathMap.at(x + 1, y) == p) {
 				xx = x + 1;
 			} else {
 				return ydist;
@@ -3785,8 +3785,8 @@ byte GamosEngine::pathFindTraceMove(uint8 p) {
 byte GamosEngine::pathFindSetNeighbor(uint8 checkVal, uint8 setVal) {
 	uint8 ret = 0;
 
-	for (int32 y = 0; y < _statesHeight; y++) {
-		for (int32 x = 0; x < _statesWidth; x++) {
+	for (uint32 y = 0; y < _statesHeight; y++) {
+		for (uint32 x = 0; x < _statesWidth; x++) {
 			uint8 &rval = _pathMap.at(x, y);
 			if (rval == PATH_FREE) {
 				if ((x > 0 && _pathMap.at(x - 1, y) == checkVal) ||
@@ -3841,8 +3841,8 @@ byte GamosEngine::FUN_004088cc(uint8 p1, uint8 p2, uint8 p3) {
 }
 
 byte GamosEngine::FUN_004086e4(const Common::Array<byte> &arr) {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
@@ -3855,8 +3855,8 @@ byte GamosEngine::FUN_004086e4(const Common::Array<byte> &arr) {
 }
 
 byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
@@ -3869,8 +3869,8 @@ byte GamosEngine::FUN_00408778(const Common::Array<byte> &arr) {
 }
 
 byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
-	for (int j = 0; j < _statesHeight; j++) {
-		for (int i = 0; i < _statesWidth; i++) {
+	for (uint j = 0; j < _statesHeight; j++) {
+		for (uint i = 0; i < _statesWidth; i++) {
 			const uint8 id = _states.at(i, j).actid;
 
 			if ( ((arr[id >> 3]) & (1 << (id & 7))) == 0 )
@@ -4009,7 +4009,7 @@ void GamosEngine::removeStaticGfxCurObj() {
 	if (_curObject->state.actid != 0xfe) {
 		ObjectAction &act = _objectActions[_curObject->state.actid];
 
-		for (int i = 0; i < _objects.size(); i++) {
+		for (uint i = 0; i < _objects.size(); i++) {
 			Object &obj = _objects[i];
 			if (obj.isStaticObject() &&
 			        obj.actObjIndex == -1 &&
@@ -4028,7 +4028,7 @@ void GamosEngine::removeStaticGfxCurObj() {
 
 
 bool GamosEngine::updateMouseCursor(Common::Point mouseMove) {
-	if (_mouseCursorImgId >= 0 && _drawCursor == 0 && _mouseCursorImgId < _sprites.size()) {
+	if (_mouseCursorImgId >= 0 && _drawCursor == 0 && _mouseCursorImgId < (int32)_sprites.size()) {
 		Sprite &cursorSpr = _sprites[_mouseCursorImgId];
 
 		if (cursorSpr.frameCount > 1) {
@@ -4368,7 +4368,7 @@ void GamosEngine::txtInputEraseBack(int n) {
 }
 
 bool GamosEngine::onTxtInputUpdate(uint8 c) {
-	for(int i = 0; i < _objects.size(); i++) {
+	for(uint i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 		if ((obj.flags & (Object::FLAG_GRAPHIC | Object::FLAG_VALID | Object::FLAG_HASACTION | Object::FLAG_TRANSITION)) == (Object::FLAG_GRAPHIC | Object::FLAG_VALID)) {
 			if ((obj.frame + 1 == obj.frameMax) && obj.actObjIndex != -1) {
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 1295bf497d8..89a964878ea 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -584,8 +584,8 @@ private:
 
 	Array2D<uint8> _pathMap;
 	uint32 _statesCount = 0;
-	int32 _pathRight = 0;
-	int32 _pathBottom = 0;
+	uint32 _pathRight = 0;
+	uint32 _pathBottom = 0;
 
 	Common::Array<Common::Rect> _dirtyRects;
 
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index bff4ccf17ec..2b09bf040b9 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -332,7 +332,7 @@ int MoviePlayer::processImageChunk() {
 				if (act == ACT2_MOUSEUP_R)
 					return 3;
 
-				if ((tstamp - _firstFrameTime) / _currentFrame >= _frameTime)
+				if ((tstamp - _firstFrameTime) / _currentFrame >= (uint)_frameTime)
 					break;
 
 				g_system->delayMillis(1);
diff --git a/engines/gamos/saveload.cpp b/engines/gamos/saveload.cpp
index e9b41684dc8..82a5a4afc3f 100644
--- a/engines/gamos/saveload.cpp
+++ b/engines/gamos/saveload.cpp
@@ -31,7 +31,7 @@ void GamosEngine::storeToGameScreen(int id) {
 	gs._savedStates = _states;
 
 	int objCount = 0;
-	for (int i = 0; i < _objects.size(); i++) {
+	for (uint i = 0; i < _objects.size(); i++) {
 		const Object &obj = _objects[i];
 		if ((obj.flags & 3) == 3 || (obj.flags & 7) == Object::FLAG_VALID)
 			objCount++;
@@ -39,7 +39,7 @@ void GamosEngine::storeToGameScreen(int id) {
 
 	int idx = 0;
 	gs._savedObjects.resize(objCount);
-	for (int i = 0; i < _objects.size(); i++) {
+	for (uint i = 0; i < _objects.size(); i++) {
 		Object &obj = _objects[i];
 
 		if (obj.isActionObject()) {
@@ -63,7 +63,7 @@ void GamosEngine::storeToGameScreen(int id) {
 				idx += 2;
 			}
 
-			for (int j = 0; j < _objects.size(); j++) {
+			for (uint j = 0; j < _objects.size(); j++) {
 				Object &lobj = _objects[ j ];
 				if ((lobj.flags & 7) == Object::FLAG_VALID && lobj.actObjIndex == obj.index) {
 					gs._savedObjects[idx] = lobj;
@@ -327,13 +327,13 @@ bool GamosEngine::writeSaveFile(int id) {
 	writeVMData(osv, _xorSeq[1]);
 	writeVMData(osv, _xorSeq[2]);
 
-	for (int i = 0; i < _gameScreens.size(); i++) {
+	for (uint i = 0; i < _gameScreens.size(); i++) {
 		GameScreen &scr = _gameScreens[i];
 
 		if (scr.loaded) {
 			osv->writeUint32LE(i);
 
-			for (int j = 0; j < scr._savedStates.size(); j++) {
+			for (uint j = 0; j < scr._savedStates.size(); j++) {
 				const ObjState &ost = scr._savedStates[j];
 				osv->writeByte(ost.actid);
 				osv->writeByte(ost.flags);
@@ -400,7 +400,7 @@ bool GamosEngine::loadSaveFile(int id) {
 
 		scr._savedStates.resize( _states.sizes() );
 
-		for (int j = 0; j < scr._savedStates.size(); j++) {
+		for (uint j = 0; j < scr._savedStates.size(); j++) {
 			ObjState &st = scr._savedStates[j];
 			st.actid = rs->readByte();
 			st.flags = rs->readByte();


Commit: 4932aef24c86f9d098e8c09ce9a18976b6d3ae16
    https://github.com/scummvm/scummvm/commit/4932aef24c86f9d098e8c09ce9a18976b6d3ae16
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:11+01:00

Commit Message:
GAMOS: Remove unused console for now

Changed paths:
  R engines/gamos/console.cpp
  R engines/gamos/console.h
    engines/gamos/gamos.cpp
    engines/gamos/module.mk


diff --git a/engines/gamos/console.cpp b/engines/gamos/console.cpp
deleted file mode 100644
index 0f31c47741e..00000000000
--- a/engines/gamos/console.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* 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 "gamos/console.h"
-
-namespace Gamos {
-
-Console::Console() : GUI::Debugger() {
-	registerCmd("test",   WRAP_METHOD(Console, Cmd_test));
-}
-
-Console::~Console() {
-}
-
-bool Console::Cmd_test(int argc, const char **argv) {
-	debugPrintf("Test\n");
-	return true;
-}
-
-} // End of namespace Gamos
diff --git a/engines/gamos/console.h b/engines/gamos/console.h
deleted file mode 100644
index e07209f73e8..00000000000
--- a/engines/gamos/console.h
+++ /dev/null
@@ -1,40 +0,0 @@
-
-/* 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/>.
- *
- */
-
-#ifndef GAMOS_CONSOLE_H
-#define GAMOS_CONSOLE_H
-
-#include "gui/debugger.h"
-
-namespace Gamos {
-
-class Console : public GUI::Debugger {
-private:
-	bool Cmd_test(int argc, const char **argv);
-public:
-	Console();
-	~Console() override;
-};
-
-} // End of namespace Gamos
-
-#endif // GAMOS_CONSOLE_H
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 563723725ed..f07350352b5 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -18,7 +18,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
-#include "gamos/console.h"
 #include "gamos/detection.h"
 #include "gamos/gamos.h"
 
@@ -70,8 +69,6 @@ void GamosEngine::freeSequences() {
 }
 
 Common::Error GamosEngine::run() {
-	// Set the engine's debugger console
-	setDebugger(new Console());
 
 	// If a savegame was selected from the launcher, load it
 	int saveSlot = ConfMan.getInt("save_slot");
diff --git a/engines/gamos/module.mk b/engines/gamos/module.mk
index 1225afceaf0..d2b88ddecde 100644
--- a/engines/gamos/module.mk
+++ b/engines/gamos/module.mk
@@ -2,7 +2,6 @@ MODULE := engines/gamos
 
 MODULE_OBJS = \
 	blit.o \
-	console.o \
 	file.o \
 	gamos.o \
 	keycodes.o \


Commit: 51526a2e61ebce8eb8f60ab9827bebcab86353c6
    https://github.com/scummvm/scummvm/commit/51526a2e61ebce8eb8f60ab9827bebcab86353c6
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:11+01:00

Commit Message:
GAMOS: Use first file in detection as run file

Changed paths:
    engines/gamos/detection.h
    engines/gamos/detection_tables.h
    engines/gamos/gamos.h


diff --git a/engines/gamos/detection.h b/engines/gamos/detection.h
index 667b671e3ce..7972b1fe36e 100644
--- a/engines/gamos/detection.h
+++ b/engines/gamos/detection.h
@@ -30,7 +30,6 @@ struct GamosGameDescription {
 	AD_GAME_DESCRIPTION_HELPERS(desc);
 
 	ADGameDescription desc;
-	const char *runFile;
 	uint32 engineVersion;
 };
 
diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index cc6d0af57c2..2fa705d6c87 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -45,7 +45,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"solgamer.exe",
 		0x80000018
 	},
 	{
@@ -59,7 +58,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"solgamee.exe",
 		0x80000018
 	},
 	{
@@ -73,7 +71,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"solgamee.exe",
 		0x80000018
 	},
 	{
@@ -87,7 +84,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"pilots.exe",
 		0x80000016
 	},
 	{
@@ -101,7 +97,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"pilde_r.exe",
 		0x80000016
 	},
 	{
@@ -115,7 +110,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"pildemo.exe",
 		0x80000016
 	},
 	{
@@ -129,7 +123,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"pilotsrd.exe",
 		0x80000016
 	},
 	{
@@ -143,7 +136,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"pilde_e.exe",
 		0x80000016
 	},
 	{
@@ -157,7 +149,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"pilotsed.exe",
 		0x80000018
 	},
 	{
@@ -171,7 +162,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"pilots2.exe",
 		0x80000018
 	},
 	{
@@ -185,7 +175,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"wildus.exe",
 		0x80000018
 	},
 	{
@@ -199,7 +188,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"wildus.exe",
 		0x80000016
 	},
 	{
@@ -213,7 +201,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"wildru.exe",
 		0x80000016
 	},
 	{
@@ -227,7 +214,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"wildrudm.exe",
 		0x80000016
 	},
 	{
@@ -241,7 +227,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"wildusdm.exe",
 		0x80000016
 	},
 	{
@@ -255,7 +240,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"ffloprd.exe",
 		0x80000016
 	},
 	{
@@ -269,7 +253,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"ffloped.exe",
 		0x80000016
 	},
 	{
@@ -283,7 +266,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"fflope.exe",
 		0x80000018
 	},
 	{
@@ -297,7 +279,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"ffloped.exe",
 		0x80000018
 	},
 	{
@@ -311,7 +292,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"fflope.exe",
 		0x80000016
 	},
 	{
@@ -325,7 +305,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"fflopr.exe",
 		0x80000016
 	},
 	{ // 1.13rus
@@ -338,7 +317,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"fflop.exe",
 		0x8000000b
 	},
 	{ // 1.13eng
@@ -351,7 +329,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"fflop.exe",
 		0x8000000b
 	},
 	{ // 1.29eng
@@ -365,7 +342,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"fflop.exe",
 		0x80000012
 	},
 	{
@@ -379,7 +355,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"it.exe",
 		0x80000016
 	},
 	{
@@ -392,7 +367,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"it.exe",
 		0x8000000b
 	},
 	{
@@ -405,7 +379,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"netwalk.exe",
 		0x8000000b
 	},
 	{
@@ -419,7 +392,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"netwalk.exe",
 		0x80000016
 	},
 	{
@@ -433,7 +405,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"netwalk.exe",
 		0x80000016
 	},
 	{
@@ -447,7 +418,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"netwalk.exe",
 		0x80000012
 	},
 	{
@@ -461,7 +431,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"netwalk.exe",
 		0x80000018
 	},
 	{
@@ -475,7 +444,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE | ADGF_DEMO,
 			GUIO1(GUIO_NONE)
 		},
-		"netwalk.exe",
 		0x80000018
 	},
 	{
@@ -489,7 +457,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"vitam_e.exe",
 		0x80000016
 	},
 	{
@@ -503,7 +470,6 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"vitam_e.exe",
 		0x80000018
 	},
 	{
@@ -517,12 +483,10 @@ const GamosGameDescription gameDescriptions[] = {
 			ADGF_UNSTABLE,
 			GUIO1(GUIO_NONE)
 		},
-		"vitam_r.exe",
 		0x80000016
 	},
 	{
 		AD_TABLE_END_MARKER,
-		"",
 		0
 	}
 };
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 89a964878ea..138990be493 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -837,7 +837,7 @@ public:
 	}
 
 	Common::String getRunFile() const {
-		return _gameDescription->runFile;
+		return _gameDescription->desc.filesDescriptions[0].fileName;
 	}
 
 	uint32 getEngineVersion() const {


Commit: 027a9df2e6415a1624a01bf1f8ea92104a9c285b
    https://github.com/scummvm/scummvm/commit/027a9df2e6415a1624a01bf1f8ea92104a9c285b
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:11+01:00

Commit Message:
GAMOS: Rename pilots to pilots1

Changed paths:
    engines/gamos/detection_tables.h


diff --git a/engines/gamos/detection_tables.h b/engines/gamos/detection_tables.h
index 2fa705d6c87..84cdd7e05a8 100644
--- a/engines/gamos/detection_tables.h
+++ b/engines/gamos/detection_tables.h
@@ -24,7 +24,7 @@ namespace Gamos {
 const PlainGameDescriptor gamosGames[] = {
 	{ "gamos", "Gamos" },
 	{ "solgamer", "21 Solitaire" },
-	{ "pilots", "Pilots 1" },
+	{ "pilots1", "Pilots 1" },
 	{ "pilots2", "Pilots 2" },
 	{ "wild", "WildSnakes"},
 	{ "flop", "Flip-Flop"},
@@ -76,7 +76,7 @@ const GamosGameDescription gameDescriptions[] = {
 	{
 		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
 			30.08.1997 */
-			"pilots",
+			"pilots1",
 			0,
 			AD_ENTRY1s("pilots.exe", "t:82ae05090898af66447bac4f06e910f3", 48357155),
 			Common::RU_RUS,
@@ -89,7 +89,7 @@ const GamosGameDescription gameDescriptions[] = {
 	{
 		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
 			04.09.1995 ??? */
-			"pilots",
+			"pilots1",
 			0,
 			AD_ENTRY1s("pilde_r.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
 			Common::RU_RUS,
@@ -102,7 +102,7 @@ const GamosGameDescription gameDescriptions[] = {
 	{
 		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
 			04.09.1995 ??? */
-			"pilots",
+			"pilots1",
 			0,
 			AD_ENTRY1s("pildemo.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
 			Common::RU_RUS,
@@ -115,7 +115,7 @@ const GamosGameDescription gameDescriptions[] = {
 	{
 		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
 			04.09.1995 ??? */
-			"pilots",
+			"pilots1",
 			0,
 			AD_ENTRY1s("pilotsrd.exe", "t:a1bbaa7e59f69cb2be3223c3336982ac", 10770038),
 			Common::RU_RUS,
@@ -128,7 +128,7 @@ const GamosGameDescription gameDescriptions[] = {
 	{
 		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.47] by Vadim Sytnikov
 			20.09.1995 ??? */
-			"pilots",
+			"pilots1",
 			0,
 			AD_ENTRY1s("pilde_e.exe", "t:a784fc52f6923817d8ec8b9101e3f3ea", 10904737),
 			Common::EN_ANY,
@@ -141,7 +141,7 @@ const GamosGameDescription gameDescriptions[] = {
 	{
 		{ /* Copyright (C) 1997 by Gamos JSC, Moscow, Russia...  Run-time engine [1.50] by Vadim Sytnikov
 			17.12.1997 */
-			"pilots",
+			"pilots1",
 			0,
 			AD_ENTRY1s("pilotsed.exe", "t:190cb2dcf936d0c3a891ba333dbc2f33", 10946501),
 			Common::EN_ANY,


Commit: 7700e87131063dd509c4aaed3d6a2335dfedfb6e
    https://github.com/scummvm/scummvm/commit/7700e87131063dd509c4aaed3d6a2335dfedfb6e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:12+01:00

Commit Message:
GAMOS: Rename Archive into GameFile to better convey the meaning and use

Changed paths:
    engines/gamos/file.cpp
    engines/gamos/file.h
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/movie.cpp


diff --git a/engines/gamos/file.cpp b/engines/gamos/file.cpp
index e76aa566ce8..1143460e96d 100644
--- a/engines/gamos/file.cpp
+++ b/engines/gamos/file.cpp
@@ -23,13 +23,13 @@
 
 namespace Gamos {
 
-Archive::Archive() {
+GameFile::GameFile() {
 };
 
-Archive::~Archive() {
+GameFile::~GameFile() {
 };
 
-bool Archive::open(const Common::Path &name) {
+bool GameFile::open(const Common::Path &name) {
 	bool res = File::open(name);
 
 	if (!res)
@@ -64,7 +64,7 @@ bool Archive::open(const Common::Path &name) {
 	_directories.resize(_dirCount);
 
 	for (uint i = 0; i < _dirCount; ++i) {
-		ArchiveDir &dir = _directories[i];
+		GameFileDir &dir = _directories[i];
 
 		dir.offset = readUint32LE();
 		dir.id = readByte();
@@ -73,12 +73,12 @@ bool Archive::open(const Common::Path &name) {
 	return true;
 }
 
-bool Archive::seekDir(uint id) {
+bool GameFile::seekDir(uint id) {
 	int16 idx = findDirByID(id);
 	if (idx < 0)
 		return false;
 
-	const ArchiveDir &dir = _directories[idx];
+	const GameFileDir &dir = _directories[idx];
 
 	if (!seek(_dataOffset + dir.offset, SEEK_SET))
 		return false;
@@ -86,7 +86,7 @@ bool Archive::seekDir(uint id) {
 	return true;
 }
 
-int32 Archive::readPackedInt() {
+int32 GameFile::readPackedInt() {
 	byte b = readByte();
 	if (!(b & 0x80))
 		return b;
@@ -127,7 +127,7 @@ int32 Archive::readPackedInt() {
 	return val;
 }
 
-RawData *Archive::readCompressedData() {
+RawData *GameFile::readCompressedData() {
 	RawData *data = new RawData();
 	if (!readCompressedData(data)) {
 		delete data;
@@ -136,7 +136,7 @@ RawData *Archive::readCompressedData() {
 	return data;
 }
 
-bool Archive::readCompressedData(RawData *out) {
+bool GameFile::readCompressedData(RawData *out) {
 	const byte t = readByte();
 	if ((t & 0x80) == 0)
 		return false;
@@ -185,7 +185,7 @@ bool Archive::readCompressedData(RawData *out) {
 	return true;
 }
 
-void Archive::decompress(RawData const *in, RawData *out) {
+void GameFile::decompress(RawData const *in, RawData *out) {
 	uint pos = 0;
 	uint outPos = 0;
 
diff --git a/engines/gamos/file.h b/engines/gamos/file.h
index f03fedfc51c..9a81a3fb686 100644
--- a/engines/gamos/file.h
+++ b/engines/gamos/file.h
@@ -28,15 +28,15 @@ namespace Gamos {
 
 typedef Common::Array<byte> RawData;
 
-struct ArchiveDir {
+struct GameFileDir {
 	uint32 offset;
 	byte id;
 };
 
-class Archive : public Common::File {
+class GameFile : public Common::File {
 public:
-	Archive();
-	~Archive() override;
+	GameFile();
+	~GameFile() override;
 	bool open(const Common::Path &name) override;
 
 	uint16 getDirCount() const {
@@ -78,7 +78,7 @@ private:
 	byte _dirCount;
 	uint32 _dataOffset;
 
-	Common::Array<ArchiveDir> _directories;
+	Common::Array<GameFileDir> _directories;
 
 	int _version = 0x18;
 
diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index f07350352b5..765add4962b 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -85,7 +85,7 @@ Common::Error GamosEngine::run() {
 
 	_engineVersion = getEngineVersion() & 0xFF;
 
-	_arch.setVersion(_engineVersion);
+	_gameFile.setVersion(_engineVersion);
 
 	init(getRunFile());
 
@@ -142,14 +142,14 @@ Common::Error GamosEngine::run() {
 
 
 bool GamosEngine::loader2() {
-	int32 skipsz = _arch.readSint32LE();
-	_arch.skip(skipsz);
+	int32 skipsz = _gameFile.readSint32LE();
+	_gameFile.skip(skipsz);
 
-	if (_arch.readByte() != 7)
+	if (_gameFile.readByte() != 7)
 		return false;
 
 	RawData data;
-	if (!_arch.readCompressedData(&data))
+	if (!_gameFile.readCompressedData(&data))
 		return false;
 
 	int32 p1 = 0;
@@ -217,7 +217,7 @@ bool GamosEngine::loadModule(uint id) {
 	_keySeq.clear();
 
 	if ((!_isResLoadingProcess && !writeStateFile()) ||
-	        !_arch.seekDir(1))
+	        !_gameFile.seekDir(1))
 		return false;
 
 	_currentModuleID = id;
@@ -250,7 +250,7 @@ bool GamosEngine::loadModule(uint id) {
 	uint32 pid = 0;
 
 	while (doLoad) {
-		byte curByte = _arch.readByte();
+		byte curByte = _gameFile.readByte();
 
 		switch (curByte) {
 		case 0:
@@ -261,25 +261,25 @@ bool GamosEngine::loadModule(uint id) {
 
 			prefixLoaded = true;
 
-			if (!_arch.seekDir(targetDir))
+			if (!_gameFile.seekDir(targetDir))
 				return false;
 
 			break;
 		case CONFTP_P1:
-			p1 = (uint32)_arch.readPackedInt();
+			p1 = (uint32)_gameFile.readPackedInt();
 			break;
 		case CONFTP_P2:
-			p2 = (uint32)_arch.readPackedInt();
+			p2 = (uint32)_gameFile.readPackedInt();
 			break;
 		case CONFTP_P3:
-			p3 = (uint32)_arch.readPackedInt();
+			p3 = (uint32)_gameFile.readPackedInt();
 			break;
 		case 4: {
-			_resReadOffset = _arch.pos();
+			_resReadOffset = _gameFile.pos();
 			bool isResource = true;
 			if (prevByte == RESTP_GAMECONF) {
 				RawData data;
-				if (!_arch.readCompressedData(&data))
+				if (!_gameFile.readCompressedData(&data))
 					return false;
 				if (_isResLoadingProcess && !_isSaveLoadingProcess)
 					readData2(data);
@@ -302,20 +302,20 @@ bool GamosEngine::loadModule(uint id) {
 				isResource = false; /* do not loadResHandler */
 			} else if (prevByte == RESTP_DATACONF) {
 				RawData data;
-				if (!_arch.readCompressedData(&data))
+				if (!_gameFile.readCompressedData(&data))
 					return false;
 				if (pid == id)
 					readElementsConfig(data);
 				isResource = false; /* do not loadResHandler */
 			} else if (prevByte == RESTP_BKG) {
 				/* free elements ? */
-				_readingBkgOffset = _arch.pos();
+				_readingBkgOffset = _gameFile.pos();
 				_countReadedBkg++;
 			}
 
 			RawData data;
 			if (isResource) {
-				if (!_arch.readCompressedData(&data))
+				if (!_gameFile.readCompressedData(&data))
 					return false;
 
 				if (!loadResHandler(prevByte, pid, p1, p2, p3, data))
@@ -351,19 +351,19 @@ bool GamosEngine::loadModule(uint id) {
 			break;
 		}
 		case 5: {
-			byte t = _arch.readByte();
+			byte t = _gameFile.readByte();
 			if (t == 0 || (t & 0xec) != 0xec)
 				return false;
 
 			byte sz = (t & 3) + 1;
 			int32 movieSize = 0;
 			for (uint i = 0; i < sz; ++i)
-				movieSize |= _arch.readByte() << (i * 8);
+				movieSize |= _gameFile.readByte() << (i * 8);
 
 			if (prevByte == 0x14)
-				_movieOffsets[pid] = _arch.pos();
+				_movieOffsets[pid] = _gameFile.pos();
 
-			_arch.skip(movieSize);
+			_gameFile.skip(movieSize);
 			break;
 		}
 		case 6:
@@ -382,7 +382,7 @@ bool GamosEngine::loadModule(uint id) {
 			prevByte = curByte & CONFTP_RESMASK;
 
 			if ((curByte & CONFTP_IDFLG) == 0)
-				pid = (uint32)_arch.readPackedInt();
+				pid = (uint32)_gameFile.readPackedInt();
 
 			break;
 		}
@@ -552,7 +552,7 @@ bool GamosEngine::reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3
 bool GamosEngine::initMainDatas() {
 	RawData rawdata;
 
-	if (!_arch.readCompressedData(&rawdata))
+	if (!_gameFile.readCompressedData(&rawdata))
 		return false;
 
 	Common::MemoryReadStream dataStream(rawdata.data(), rawdata.size(), DisposeAfterUse::NO);
@@ -619,7 +619,7 @@ bool GamosEngine::initMainDatas() {
 bool GamosEngine::init(const Common::String &moduleName) {
 	_isSaveLoadingProcess = false;
 
-	if (!_arch.open(Common::Path(moduleName)))
+	if (!_gameFile.open(Common::Path(moduleName)))
 		return false;
 
 	if (!loadInitModule())
@@ -818,11 +818,11 @@ bool GamosEngine::loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byt
 		img->cSize = s.readSint32LE();
 	} else {
 		if (_sprites[id].flags & 0x80) {
-			if (_arch._lastReadDecompressedSize) {
-				img->offset = _arch._lastReadDataOffset;
-				img->cSize = _arch._lastReadSize;
+			if (_gameFile._lastReadDecompressedSize) {
+				img->offset = _gameFile._lastReadDataOffset;
+				img->cSize = _gameFile._lastReadSize;
 			} else {
-				img->offset = _arch._lastReadDataOffset;
+				img->offset = _gameFile._lastReadDataOffset;
 				img->cSize = 0;
 			}
 		} else {
@@ -883,7 +883,7 @@ bool GamosEngine::playIntro() {
 }
 
 bool GamosEngine::moviePlayerPlay(int id) {
-	bool res = _moviePlayer.playMovie(&_arch, _movieOffsets[id], this);
+	bool res = _moviePlayer.playMovie(&_gameFile, _movieOffsets[id], this);
 	return res;
 }
 
@@ -2315,19 +2315,19 @@ bool GamosEngine::loadImage(Image *img) {
 	if (img->offset < 0)
 		return false;
 
-	_arch.seek(img->offset, 0);
+	_gameFile.seek(img->offset, 0);
 
 	if (img->cSize == 0) {
 		img->rawData.resize((img->surface.w * img->surface.h + 16) & ~0xf);
 
-		_arch.read(img->rawData.data(), img->surface.w * img->surface.h);
+		_gameFile.read(img->rawData.data(), img->surface.w * img->surface.h);
 		img->surface.setPixels(img->rawData.data());
 	} else {
 		img->rawData.resize((img->surface.w * img->surface.h + 4 + 16) & ~0xf);
 
 		RawData tmp(img->cSize);
-		_arch.read(tmp.data(), tmp.size());
-		_arch.decompress(&tmp, &img->rawData);
+		_gameFile.read(tmp.data(), tmp.size());
+		_gameFile.decompress(&tmp, &img->rawData);
 		img->surface.setPixels(img->rawData.data() + 4);
 	}
 
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 138990be493..8fee92bc987 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -382,7 +382,7 @@ private:
 	bool _errSet = false;
 	Common::String _errMessage;
 
-	Archive _arch;
+	GameFile _gameFile;
 
 	byte _cmdByte = 0;
 
@@ -600,7 +600,7 @@ protected:
 	Common::Error run() override;
 
 	void readCMDByte() {
-		_cmdByte = _arch.readByte();
+		_cmdByte = _gameFile.readByte();
 	}
 
 	bool loadModule(uint id);
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 2b09bf040b9..07850f28bdd 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -410,7 +410,7 @@ bool MoviePlayer::readCompressed(int32_t count, Common::Array<byte> *buf) {
 		_packedBuffer.resize(_hdrValue1);
 		_file->read(_packedBuffer.data(), _hdrValue1);
 		buf->resize(_hdrValue2);
-		Archive::decompress(&_packedBuffer, buf);
+		GameFile::decompress(&_packedBuffer, buf);
 	} else {
 		buf->resize(_hdrValue1);
 		_file->read(buf->data(), _hdrValue1);


Commit: 6c0a29d10dd35cf7f067f64595675c9eaf2c0414
    https://github.com/scummvm/scummvm/commit/6c0a29d10dd35cf7f067f64595675c9eaf2c0414
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:12+01:00

Commit Message:
GAMOS: Rename exit label to loopExit to avoid possible conflicts

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 765add4962b..84e8c0fb6a8 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2005,7 +2005,7 @@ bool GamosEngine::updateObjects() {
 							pobj->flags &= ~Object::FLAG_TRANSITION;
 						} else {
 							if (pobj == _firstUpdateObject) {
-								goto exit;
+								goto loopExit;
 							}
 							goto continue_to_next_object;
 						}
@@ -2051,13 +2051,13 @@ bool GamosEngine::updateObjects() {
 
 									if (_firstUpdateObject) {
 										_firstUpdateObject = nullptr;
-										goto exit;
+										goto loopExit;
 									}
 									goto continue_to_next_object;
 								} else if (res != 0) {
 									if (_firstUpdateObject) {
 										_firstUpdateObject = nullptr;
-										goto exit;
+										goto loopExit;
 									}
 									cycleNextInputObj(pobj);
 									goto continue_to_next_object;
@@ -2068,12 +2068,12 @@ bool GamosEngine::updateObjects() {
 						if (scr.flags & 0x80) {
 							if (tmp) {
 								_firstUpdateObject = pobj;
-								goto exit;
+								goto loopExit;
 							}
 
 							if (_firstUpdateObject) {
 								_firstUpdateObject = nullptr;
-								goto exit;
+								goto loopExit;
 							}
 
 							break;
@@ -2089,7 +2089,7 @@ continue_to_next_object:
 		;
 	}
 
-exit:
+loopExit:
 	_curObject = nullptr;
 	_curObjIndex = -1;
 	return true;


Commit: a9a9382fb9a40b3fbd24c3622532c2ff70998bab
    https://github.com/scummvm/scummvm/commit/a9a9382fb9a40b3fbd24c3622532c2ff70998bab
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:12+01:00

Commit Message:
GAMOS: Fix style

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/vm.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 84e8c0fb6a8..749ecdfdc79 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -2948,7 +2948,7 @@ void GamosEngine::vmCallDispatcher(VM::Context *ctx, uint32 funcID) {
 
 		char buffer[256];
 		int a = 0, b = 0, c = 0, d = 0;
-		if ( sscanf(str.c_str(), "%s %d %d %d %d", buffer, &a, &b, &c, &d) > 0) {
+		if (sscanf(str.c_str(), "%s %d %d %d %d", buffer, &a, &b, &c, &d) > 0) {
 			stopMidi();
 			stopSounds();
 
@@ -4386,8 +4386,8 @@ bool GamosEngine::onTxtInputUpdate(uint8 c) {
 bool GamosEngine::eventsSkip(bool breakOnInput) {
 	bool brk = false;
 	Common::Event e;
-	while(_system->getEventManager()->pollEvent(e)) {
-		if (breakOnInput){
+	while (_system->getEventManager()->pollEvent(e)) {
+		if (breakOnInput) {
 			if (e.type == Common::EVENT_LBUTTONUP ||
 				e.type == Common::EVENT_RBUTTONUP ||
 				e.type == Common::EVENT_KEYUP)
diff --git a/engines/gamos/vm.cpp b/engines/gamos/vm.cpp
index f5aa829232e..c915c49720c 100644
--- a/engines/gamos/vm.cpp
+++ b/engines/gamos/vm.cpp
@@ -30,7 +30,7 @@ uint8 VM::MemAccess::getU8(uint32 address) {
 	if (!_currentBlock)
 		return 0; // ERROR!
 
-	return _currentBlock->data[ address - _currentBlock->address ];
+	return _currentBlock->data[address - _currentBlock->address];
 }
 
 uint32 VM::MemAccess::getU32(uint32 address) {


Commit: 83c27b9c73e1eacb0cb6e7c5c16bac78a376cd41
    https://github.com/scummvm/scummvm/commit/83c27b9c73e1eacb0cb6e7c5c16bac78a376cd41
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:13+01:00

Commit Message:
GAMOS: Use scummvm types

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/movie.cpp
    engines/gamos/movie.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 749ecdfdc79..a2858e2fc2a 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -408,7 +408,7 @@ bool GamosEngine::loadModule(uint id) {
 	return true;
 }
 
-bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize) {
+bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, uint32 dataSize) {
 	if (tp == RESTP_VMSTATE) {
 		Common::MemoryReadStream dataStream(data, dataSize, DisposeAfterUse::NO);
 
@@ -528,7 +528,7 @@ bool GamosEngine::loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, c
 	} else if (tp == RESTP_XORSEQ2) {
 		loadXorSeq(data, dataSize, 2);
 	} else {
-		warning("Unk Res %x at %x sz %zx", tp, _loadedDataSize, dataSize);
+		warning("Unk Res %x at %x sz %x", tp, _loadedDataSize, dataSize);
 	}
 	return true;
 }
@@ -733,7 +733,7 @@ void GamosEngine::readElementsConfig(const RawData &data) {
 	_vm.clearMemory();
 }
 
-void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
+void GamosEngine::loadXorSeq(const byte *data, uint32 dataSize, int id) {
 	Common::MemoryReadStream dataStream(data, dataSize);
 
 	Common::Array<XorArg> &seq = _xorSeq[id];
@@ -747,7 +747,7 @@ void GamosEngine::loadXorSeq(const byte *data, size_t dataSize, int id) {
 	}
 }
 
-bool GamosEngine::loadSpriteInfo(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteInfo(int32 id, const byte *data, uint32 dataSize) {
 	if (dataSize < 4)
 		return false;
 
@@ -764,7 +764,7 @@ bool GamosEngine::loadSpriteInfo(int32 id, const byte *data, size_t dataSize) {
 	return true;
 }
 
-bool GamosEngine::loadSpriteSeqLength(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteSeqLength(int32 id, const byte *data, uint32 dataSize) {
 	if (*(const uint32 *)data != 0)
 		error("41 not null!!!");
 
@@ -774,7 +774,7 @@ bool GamosEngine::loadSpriteSeqLength(int32 id, const byte *data, size_t dataSiz
 	return true;
 }
 
-bool GamosEngine::loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, uint32 dataSize) {
 	//warning("loadRes42 pid %d p %d sz %x",id, p1, dataSize);
 
 	if (_sprites[id].sequences.size() == 0)
@@ -798,7 +798,7 @@ bool GamosEngine::loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, s
 	return true;
 }
 
-bool GamosEngine::loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize) {
+bool GamosEngine::loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byte *data, uint32 dataSize) {
 	_images.push_back(new Image());
 	_sprites[id].sequences[p1]->operator[](p2).image = _images.back();
 
@@ -836,12 +836,12 @@ bool GamosEngine::loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byt
 	return true;
 }
 
-bool GamosEngine::loadMidiTrack(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadMidiTrack(int32 id, const byte *data, uint32 dataSize) {
 	_midiTracks[id].assign(data, data + dataSize);
 	return true;
 }
 
-bool GamosEngine::loadBackground(int32 id, const byte *data, size_t dataSize) {
+bool GamosEngine::loadBackground(int32 id, const byte *data, uint32 dataSize) {
 	GameScreen &bimg = _gameScreens[id];
 	bimg.loaded = true;
 	bimg.offset = _readingBkgOffset;
@@ -3883,7 +3883,7 @@ byte GamosEngine::FUN_0040881c(const Common::Array<byte> &arr) {
 
 
 
-void Actions::parse(const byte *data, size_t dataSize) {
+void Actions::parse(const byte *data, uint32 dataSize) {
 	Common::MemoryReadStream rstream(data, dataSize);
 
 	/* clean first */
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 8fee92bc987..503e314016c 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -213,7 +213,7 @@ struct Actions {
 	int32 conditionAddress = -1;
 	int32 functionAddress = -1;
 
-	void parse(const byte *data, size_t dataSize);
+	void parse(const byte *data, uint32 dataSize);
 };
 
 struct ObjectAction {
@@ -606,7 +606,7 @@ protected:
 	bool loadModule(uint id);
 	bool loader2();
 
-	bool loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, size_t dataSize);
+	bool loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const byte *data, uint32 dataSize);
 	bool loadResHandler(uint tp, uint pid, uint p1, uint p2, uint p3, const RawData &data);
 
 	bool reuseLastResource(uint tp, uint pid, uint p1, uint p2, uint p3);
@@ -620,16 +620,16 @@ protected:
 
 	void setFPS(uint fps);
 
-	void loadXorSeq(const byte *data, size_t dataSize, int id);
+	void loadXorSeq(const byte *data, uint32 dataSize, int id);
 
-	bool loadSpriteInfo(int32 id, const byte *data, size_t dataSize);
-	bool loadSpriteSeqLength(int32 id, const byte *data, size_t dataSize);
-	bool loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, size_t dataSize);
-	bool loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byte *data, size_t dataSize);
+	bool loadSpriteInfo(int32 id, const byte *data, uint32 dataSize);
+	bool loadSpriteSeqLength(int32 id, const byte *data, uint32 dataSize);
+	bool loadSpriteSeqImageInfo(int32 id, int32 p1, const byte *data, uint32 dataSize);
+	bool loadSpriteSeqImageData(int32 id, int32 p1, int32 p2, const byte *data, uint32 dataSize);
 
-	bool loadMidiTrack(int32 id, const byte *data, size_t dataSize);
+	bool loadMidiTrack(int32 id, const byte *data, uint32 dataSize);
 
-	bool loadBackground(int32 id, const byte *data, size_t dataSize);
+	bool loadBackground(int32 id, const byte *data, uint32 dataSize);
 
 	void freeImages();
 	void freeSequences();
diff --git a/engines/gamos/movie.cpp b/engines/gamos/movie.cpp
index 07850f28bdd..d5a54edadc4 100644
--- a/engines/gamos/movie.cpp
+++ b/engines/gamos/movie.cpp
@@ -139,7 +139,7 @@ int MoviePlayer::processControlChunk() {
 
 	switch (_hdrBytes[1]) {
 	case 0:
-		if ((uint32_t)_hdrValue1 != 0x563d2d5b || (uint32_t)_hdrValue2 != 0x5d2d3d53) {
+		if ((uint32)_hdrValue1 != 0x563d2d5b || (uint32)_hdrValue2 != 0x5d2d3d53) {
 			error();
 			return 0;
 		}
@@ -402,7 +402,7 @@ bool MoviePlayer::readHdr() {
 	return true;
 }
 
-bool MoviePlayer::readCompressed(int32_t count, Common::Array<byte> *buf) {
+bool MoviePlayer::readCompressed(int32 count, Common::Array<byte> *buf) {
 	if (_hdrValue1 == 0)
 		return true;
 
diff --git a/engines/gamos/movie.h b/engines/gamos/movie.h
index f2f3d5b2387..80d26094856 100644
--- a/engines/gamos/movie.h
+++ b/engines/gamos/movie.h
@@ -48,7 +48,7 @@ private:
 	int proccessMidiChunk();
 
 	bool readHdr();
-	bool readCompressed(int32_t count, Common::Array<byte> *buf);
+	bool readCompressed(int32 count, Common::Array<byte> *buf);
 
 	uint8 processMessages(bool keepAct, uint32 *msecs);
 
@@ -98,8 +98,8 @@ private:
 	Common::File *_file = nullptr;
 
 	byte _hdrBytes[4];
-	int32_t _hdrValue1 = 0;
-	int32_t _hdrValue2 = 0;
+	int32 _hdrValue1 = 0;
+	int32 _hdrValue2 = 0;
 };
 
 }


Commit: 2d2a2ecb6ecf5b0716cb9bed61ce23e57a752b7e
    https://github.com/scummvm/scummvm/commit/2d2a2ecb6ecf5b0716cb9bed61ce23e57a752b7e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:13+01:00

Commit Message:
GAMOS: Break event loop on Quit message too

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index a2858e2fc2a..ab6ab07f881 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -4390,7 +4390,8 @@ bool GamosEngine::eventsSkip(bool breakOnInput) {
 		if (breakOnInput) {
 			if (e.type == Common::EVENT_LBUTTONUP ||
 				e.type == Common::EVENT_RBUTTONUP ||
-				e.type == Common::EVENT_KEYUP)
+				e.type == Common::EVENT_KEYUP ||
+				e.type == Common::EVENT_QUIT)
 				brk = true;
 		}
 	}


Commit: 8a94f7cc83d46d48be6eeceb858f76a302e25e48
    https://github.com/scummvm/scummvm/commit/8a94f7cc83d46d48be6eeceb858f76a302e25e48
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:13+01:00

Commit Message:
GAMOS: Place action dump into dumps subdir

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index ab6ab07f881..d7413f31687 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -4401,7 +4401,7 @@ bool GamosEngine::eventsSkip(bool breakOnInput) {
 
 
 void GamosEngine::dumpActions() {
-	Common::String t = Common::String::format("./actions_%d.txt", _currentModuleID);
+	Common::String t = Common::String::format("./dumps/actions_%d.txt", _currentModuleID);
 
 	Common::DumpFile f;
 


Commit: 51db5e1739619978415826341becebd89ec66ba0
    https://github.com/scummvm/scummvm/commit/51db5e1739619978415826341becebd89ec66ba0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:14+01:00

Commit Message:
GAMOS: Do not include translation.h until keymapper is implemented

Changed paths:
    engines/gamos/metaengine.cpp


diff --git a/engines/gamos/metaengine.cpp b/engines/gamos/metaengine.cpp
index 862d838f2bb..fb51816bf8d 100644
--- a/engines/gamos/metaengine.cpp
+++ b/engines/gamos/metaengine.cpp
@@ -19,8 +19,6 @@
  *
  */
 
-#include "common/translation.h"
-
 #include "gamos/metaengine.h"
 #include "gamos/detection.h"
 #include "gamos/gamos.h"


Commit: 1c9da3fa6964129fdb66650e259a80abc3c27093
    https://github.com/scummvm/scummvm/commit/1c9da3fa6964129fdb66650e259a80abc3c27093
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:14+01:00

Commit Message:
GAMOS: Delete unused code for load save from save_slot

Changed paths:
    engines/gamos/gamos.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index d7413f31687..6b0dd276e14 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -70,11 +70,6 @@ void GamosEngine::freeSequences() {
 
 Common::Error GamosEngine::run() {
 
-	// If a savegame was selected from the launcher, load it
-	int saveSlot = ConfMan.getInt("save_slot");
-	if (saveSlot != -1)
-		(void)loadGameState(saveSlot);
-
 	CursorMan.setDefaultArrowCursor();
 	CursorMan.showMouse(true);
 


Commit: 3d56e6d864f385aeec33075625b0555b3e52d7c0
    https://github.com/scummvm/scummvm/commit/3d56e6d864f385aeec33075625b0555b3e52d7c0
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:14+01:00

Commit Message:
GAMOS: Implement syncSoundSettings

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h
    engines/gamos/music.cpp


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 6b0dd276e14..3764f4adfe9 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -620,11 +620,16 @@ bool GamosEngine::init(const Common::String &moduleName) {
 	if (!loadInitModule())
 		return false;
 
-	_savedSndVolume = !ConfMan.hasKey("sfx_volume") ? 255 : ConfMan.getInt("sfx_volume");
-	_savedMidiVolume = !ConfMan.hasKey("music_volume") ? 255 : ConfMan.getInt("music_volume");
+	_scummMidiVolume = !ConfMan.hasKey("music_volume") ? 256 : ConfMan.getInt("music_volume");
+	_scummSndVolume = !ConfMan.hasKey("sfx_volume") ? 256 : ConfMan.getInt("sfx_volume");
+	_savedSndVolume = 255;
+	_savedMidiVolume = 255;
 	_sndVolumeTarget = _savedSndVolume;
 	_midiVolumeTarget = _savedMidiVolume;
 
+	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, (_sndVolume * _scummSndVolume) >> 8);
+	_musicPlayer.setVolume((_midiVolume * _scummMidiVolume) >> 8);
+
 	playVideo("intro", _introPos, _introSize);
 
 	if (!playIntro())
@@ -634,7 +639,7 @@ bool GamosEngine::init(const Common::String &moduleName) {
 }
 
 bool GamosEngine::loadInitModule() {
-	rndSeed(_system->getMillis());
+	rndSeed(_randomSource.getRandomNumber(UINT_MAX));
 	_curObjIndex = -1;
 	_curObject = nullptr;
 	_curAction = nullptr;
@@ -1223,7 +1228,7 @@ bool GamosEngine::playMidi(Common::Array<byte> *buffer) {
 
 bool GamosEngine::playSound(uint id) {
 	Audio::SeekableAudioStream *stream = Audio::makeRawStream(_soundSamples[id].data(), _soundSamples[id].size(), 11025, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
-	_mixer->playStream(Audio::Mixer::kPlainSoundType, nullptr, stream, -1, _sndVolume);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, nullptr, stream, -1, ((uint16)_sndVolume * _scummSndVolume) >> 8);
 	return true;
 }
 
@@ -1248,15 +1253,34 @@ void GamosEngine::changeVolume() {
 	const int sndStep = stepVolume(_sndVolume, _sndVolumeTarget);
 	if (sndStep) {
 		_sndVolume += sndStep;
-		_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, _sndVolume);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ((uint16)_sndVolume * _scummSndVolume) >> 8);
 	}
 	const int midiStep = stepVolume(_midiVolume, _midiVolumeTarget);
 	if (midiStep) {
 		_midiVolume += midiStep;
-		_musicPlayer.setVolume(_midiVolume);
+		_musicPlayer.setVolume(((uint16)_midiVolume * _scummMidiVolume) >> 8);
 	}
 }
 
+void GamosEngine::syncSoundSettings() {
+	Engine::syncSoundSettings();
+
+	const uint16 newSndVolume = !ConfMan.hasKey("sfx_volume") ? 256 : ConfMan.getInt("sfx_volume");
+	const uint16 newMusicVolume = !ConfMan.hasKey("music_volume") ? 256 : ConfMan.getInt("music_volume");
+
+	if (newSndVolume != _scummSndVolume) {
+		_scummSndVolume = newSndVolume;
+		_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ((uint16)_sndVolume * _scummSndVolume) >> 8);
+	}
+
+	if (newMusicVolume != _scummMidiVolume) {
+		_scummMidiVolume = newMusicVolume;
+		_musicPlayer.setVolume(((uint16)_midiVolume * _scummMidiVolume) >> 8);
+	}
+
+}
+
+
 uint8 GamosEngine::update(Common::Point screenSize, Common::Point mouseMove, Common::Point actPos, uint8 act2, uint8 act1, uint16 keyCode, bool mouseInWindow) {
 	_needReload = false;
 	_vm._interrupt = false;
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index 503e314016c..b97368ae59e 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -493,6 +493,10 @@ private:
 	bool _enableMidi = false;
 	int32 _midiTrack = 0;
 
+	uint16 _scummMidiVolume = 256;
+	uint16 _scummSndVolume = 256;
+
+
 	uint32 _readingBkgOffset = 0;
 	int32 _readingBkgMainId = -1;
 	int32 _countReadedBkg = 0;
@@ -642,6 +646,8 @@ protected:
 
 	void changeVolume();
 
+	void syncSoundSettings() override;
+
 
 	void stopMidi();
 	void stopCDAudio();
diff --git a/engines/gamos/music.cpp b/engines/gamos/music.cpp
index 83dc4529d48..f188ac21b31 100644
--- a/engines/gamos/music.cpp
+++ b/engines/gamos/music.cpp
@@ -131,7 +131,7 @@ void MidiMusic::update() {
 				param2 = b & 0x7f;
 
 				if (cmd == MidiDriver_BASE::MIDI_COMMAND_NOTE_ON)
-					param2 = param2 * _volume / 255;
+					param2 = ((uint16)param2 * (uint16)_volume) / 255;
 			}
 
 			if (doSend)


Commit: 278fc09bedba7722852e8e5cdda605c1573beb3e
    https://github.com/scummvm/scummvm/commit/278fc09bedba7722852e8e5cdda605c1573beb3e
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:15+01:00

Commit Message:
GAMOS: Use RandomSource for get seed value instead of current time

Changed paths:
    engines/gamos/gamos.cpp
    engines/gamos/gamos.h


diff --git a/engines/gamos/gamos.cpp b/engines/gamos/gamos.cpp
index 3764f4adfe9..02685e3f433 100644
--- a/engines/gamos/gamos.cpp
+++ b/engines/gamos/gamos.cpp
@@ -46,7 +46,8 @@ GamosEngine::GamosEngine(OSystem *syst, const GamosGameDescription *gameDesc) :
 	_gameDescription(gameDesc),
 	_messageProc(this),
 	_vm(this, callbackVMCallDispatcher),
-	_txtInputVMAccess(_vm) {}
+	_txtInputVMAccess(_vm),
+	_randomSource("gamos") {}
 
 GamosEngine::~GamosEngine() {
 	freeImages();
@@ -983,7 +984,7 @@ void GamosEngine::flushDirtyRects(bool apply) {
 	_inputMouseActType = ACT_NONE;
 	PTR_00417388 = nullptr;
 
-	rndSeed(_system->getMillis());
+	rndSeed(_randomSource.getRandomNumber(UINT_MAX));
 	_inputActObj = nullptr;
 	cycleNextInputObj(nullptr);
 }
diff --git a/engines/gamos/gamos.h b/engines/gamos/gamos.h
index b97368ae59e..39a172c4e31 100644
--- a/engines/gamos/gamos.h
+++ b/engines/gamos/gamos.h
@@ -436,6 +436,7 @@ private:
 
 	Common::Array<XorArg> _xorSeq[3];
 
+	Common::RandomSource _randomSource;
 	uint32 _seed = 1;
 
 	Object _cursorObject;


Commit: f90060075ad7e19ac8dc160ded859e951ac20d4c
    https://github.com/scummvm/scummvm/commit/f90060075ad7e19ac8dc160ded859e951ac20d4c
Author: Marisa-Chan (thunder_8888 at mail.ru)
Date: 2026-02-20T19:03:15+01:00

Commit Message:
GAMOS: Delete extra spaces

Changed paths:
    engines/gamos/video.cpp


diff --git a/engines/gamos/video.cpp b/engines/gamos/video.cpp
index 522e8c8cce8..0b5e09f84cd 100644
--- a/engines/gamos/video.cpp
+++ b/engines/gamos/video.cpp
@@ -126,7 +126,7 @@ void GamosEngine::playVideo(const Common::String &video, const Common::Point &po
     }
 
     Common::Event e;
-    while ( !avi.endOfVideo() ) {
+    while (!avi.endOfVideo()) {
         if (eventsSkip(true))
             break;
 


Commit: 8fd96e993f9cf0c929fc9b181d72f369b91d5c16
    https://github.com/scummvm/scummvm/commit/8fd96e993f9cf0c929fc9b181d72f369b91d5c16
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:07:32+01:00

Commit Message:
VIDEO: Fix warning in 4xm decoder

Changed paths:
    video/4xm_decoder.cpp


diff --git a/video/4xm_decoder.cpp b/video/4xm_decoder.cpp
index 712bddc11d4..a0c7980e6cd 100644
--- a/video/4xm_decoder.cpp
+++ b/video/4xm_decoder.cpp
@@ -54,11 +54,11 @@ static const int8_t mv[256][2] = {
 class FourXMDecoder::FourXMAudioTrack : public AudioTrack {
 	uint _audioType;
 	uint _audioChannels;
-	uint _sampleRate;
+	//uint _sampleRate;
 	Common::ScopedPtr<Audio::PacketizedAudioStream> _output;
 
 public:
-	FourXMAudioTrack(FourXMDecoder *dec, uint trackIdx, uint audioType, uint audioChannels, uint sampleRate) : AudioTrack(Audio::Mixer::SoundType::kPlainSoundType), _audioType(audioType), _audioChannels(audioChannels), _sampleRate(sampleRate) {
+	FourXMAudioTrack(FourXMDecoder *dec, uint trackIdx, uint audioType, uint audioChannels, uint sampleRate) : AudioTrack(Audio::Mixer::SoundType::kPlainSoundType), _audioType(audioType), _audioChannels(audioChannels)/*, _sampleRate(sampleRate)*/ {
 		switch (_audioType) {
 		case 0: {
 			// Raw PCM data


Commit: fbf17d6ab9cf7d484fe1d7801ec05438de2d48f6
    https://github.com/scummvm/scummvm/commit/fbf17d6ab9cf7d484fe1d7801ec05438de2d48f6
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2026-02-20T19:07:51+01:00

Commit Message:
VIDEO: Comment out unused variable in Paco decoder

Changed paths:
    video/paco_decoder.cpp


diff --git a/video/paco_decoder.cpp b/video/paco_decoder.cpp
index 9f0c8ec4890..de3f23f4b51 100644
--- a/video/paco_decoder.cpp
+++ b/video/paco_decoder.cpp
@@ -221,7 +221,7 @@ void PacoDecoder::readNextPacket() {
 	if (_audioTrack) {
 		while (_audioTrack->needsAudio() && (_audioStream->pos() < _audioStream->size())) {
 			// buffer as much audio as we need
-			int64 currentPos = _audioStream->pos();
+			//int64 currentPos = _audioStream->pos();
 			int frameType = _audioStream->readByte();
 			int v = _audioStream->readByte();
 			uint32 chunkSize =  (v << 16 ) | _audioStream->readUint16BE();




More information about the Scummvm-git-logs mailing list