[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